CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Interfacing AD7730

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
akaka



Joined: 18 Jul 2012
Posts: 14

View user's profile Send private message Send e-mail

Interfacing AD7730
PostPosted: Sat Feb 27, 2016 4:54 am     Reply with quote

Hi every one I was looking for any similar post for days.....

I want to interface AD7730 Bridge Transducer ADC with a PIC.
The project it is still in Demo Mode and it's simple in main loop.
So here is the schematic
http://postimg.org/image/d77oqkcxt/

and code follows:

Libraries for AD7730

AD7730.c
Code:
/*----------------------------------------------------------------------------
File: AD7730.c

Description
   Driver of AD7730

Project            : Operating System for 16f88---->Test weighing scale with AD7730
Created for Version: 1.0
Updated for Version: 1.0
Last Date Modified : 20/02/2016

Copyright(c) 2016 by Chris_Kal
All Rights Reserved.
----------------------------------------------------------------------------*/

#include "AD7730.h"
#define    RESET           PIN_B6
#define    READY           PIN_B5
#define    AD7730_SELECT   PIN_B3


void SendAD_Data(BYTE data)
{
 
   //delay_ms(2);
   spi_write(data);
   //delay_ms(5);
   
   
}   

void AD7730_Init()

 
 
  //-----------Filter Configuration------------------------------- 
   printf("Filter Configuration...\r\n");
   output_low(AD7730_SELECT);
   SendAD_Data(CR_SINGLE_WRITE | CR_FILTER_REGISTER);
   SendAD_Data(FR2_SINC_AVERAGING_2048);
   SendAD_Data(FR1_SKIP_OFF | FR1_FAST_OFF);
   SendAD_Data(FR0_CHOP_ON);
   output_high(AD7730_SELECT);
   
  //--------------------------------------------------------------
   delay_ms(30);
   
  //----------------DAC Configuration-----------------------------
   printf("DAC Configuration...\r\n");
   output_low(AD7730_SELECT); 
   SendAD_Data(CR_SINGLE_WRITE | CR_DAC_REGISTER);
   SendAD_Data(DACR_OFFSET_SIGN_POSITIVE | DACR_OFFSET_NONE);
   output_high(AD7730_SELECT);
 
  //--------------------------------------------------------------
   delay_ms(30);
  //---------Internal Zero Calibartion----------------------------
   printf("Internal Zero Calibartion...\r\n");
   output_low(AD7730_SELECT);
   SendAD_Data(CR_SINGLE_WRITE | CR_MODE_REGISTER);
   SendAD_Data(MR1_MODE_INTERNAL_ZERO_CALIBRATION | CURRENT_MODE_1_SETTINGS);
   SendAD_Data(CURRENT_MODE_0_SETTINGS);
   //waitForReady
   while(input(READY) != 0) ;////not yet
   output_high(AD7730_SELECT);
 

  //---------Internal Full Calibartion----------------------------
   printf("Internal Full Calibartion...\r\n");
   output_low(AD7730_SELECT);
   SendAD_Data(CR_SINGLE_WRITE | CR_MODE_REGISTER);
   SendAD_Data(MR1_MODE_INTERNAL_FULL_CALIBRATION | CURRENT_MODE_1_SETTINGS);
   SendAD_Data(CURRENT_MODE_0_SETTINGS);
   //waitForReady
   while(input(READY) != 0) ;////not yet
   output_high(AD7730_SELECT);

  //--------------------------------------------------------------

  //---------------SET CONTINOUS MODE-----------------------------
   printf("SET CONTINOUS MODE...\r\n");
   output_low(AD7730_SELECT);
   SendAD_Data(CR_SINGLE_WRITE | CR_MODE_REGISTER);
   SendAD_Data(MR1_MODE_CONTINUOUS | CURRENT_MODE_1_SETTINGS);
   SendAD_Data(CURRENT_MODE_0_SETTINGS);
   //waitForReady
   while(input(READY) != 0) ;////not yet
   output_high(AD7730_SELECT);

  //--------------------------------------------------------------
 
  //---------------START CONTINUOUS READ-------------------------- 
   printf("START CONTINUOUS READ...\r\n");
   output_low(AD7730_SELECT);
   SendAD_Data(CR_CONTINUOUS_READ_START | CR_DATA_REGISTER);
   output_high(AD7730_SELECT);
  //--------------------------------------------------------------

}

int8 ReadStatus(void)
{
   int8 status;
   
   output_low(AD7730_SELECT);
   delay_ms(5);
   spi_write(CR_SINGLE_READ| CR_STATUS_REGISTER);
   status = spi_read(0);
   output_high(AD7730_SELECT);
   return status;
}

int16 Read_Mode(void)   
{   
   int16 data;
   int8 ModeH;
   int8 ModeL;
    output_low(AD7730_SELECT);
    delay_ms(5);
    spi_write(0x12);            //send comm reg for read from MODE reg(opcode)   
    ModeH = spi_read(0);      //read high byte   
    ModeL = spi_read(0);      //read low byte 
    data = (ModeH<<8)|ModeL;
    delay_ms(20);
    output_high(AD7730_SELECT);    //CS = 1   
    return data;
     
}   

int8 ReadDAC(void)
{
   int8 DAC;
   
   output_low(AD7730_SELECT);
   delay_ms(5);
   spi_write(CR_SINGLE_READ| CR_DAC_REGISTER);
   if( spi_data_is_in()){
      DAC = spi_read(0);
      printf("Incoming Data\r\n");
   }
   output_high(AD7730_SELECT);
   return DAC;
}


AD7730.h

Code:


#define READ_ONLY 0xFF
//Communication Register Values
#define CR_SINGLE_WRITE 0x00
#define CR_SINGLE_READ 0x10
#define CR_CONTINUOUS_READ_START 0x20
#define CR_CONTINUOUS_READ_STOP 0x30

#define CR_COMMUNICATION_REGISTER 0x00 //Write only
#define CR_STATUS_REGISTER 0x00 //Read only
#define CR_DATA_REGISTER 0x01
#define CR_MODE_REGISTER 0x02
#define CR_FILTER_REGISTER 0x03
#define CR_DAC_REGISTER 0x04
#define CR_OFFSET_REGISTER 0x05
#define CR_GAIN_REGISTER 0x06
#define CR_TEST_REGISTER 0x07

//Mode Register Values
#define MR1_MODE_IDLE 0x00
#define MR1_MODE_CONTINUOUS 0x20 //Standard Operation
#define MR1_MODE_SINGLE 0x40
#define MR1_MODE_STANDBY 0x60
#define MR1_MODE_INTERNAL_ZERO_CALIBRATION 0x80
#define MR1_MODE_INTERNAL_FULL_CALIBRATION 0xA0
#define MR1_MODE_SYSTEM_ZERO_CALIBRATION 0xC0
#define MR1_MODE_SYSTEM_FULL_CALIBRATION 0xE0
#define MR1_BU_BIPOLAR 0x00 //+- voltage defined by MR0_RANGE
#define MR1_BU_UNIPOLAR 0x10 //0 to voltage deifined by MRO_RANGE
#define MR1_WL_24_BIT 0x01
#define MR1_WL_16_BIT 0x00

#define MR0_HIREF_5V 0x80
#define MR0_HIREF_2P5V 0x00
#define MR0_RANGE_10MV 0x00
#define MR0_RANGE_20MV 0x01
#define MR0_RANGE_40MV 0x02
#define MR0_RANGE_80MV 0x03
#define MR0_CHANNEL_1 0x00
#define MR0_CHANNEL_2 0x01
#define MR0_CHANNEL_SHORT_1 0x02 //Used for internal noise check
#define MR0_CHANNEL_NEGATIVE_1_2 0x03 //Unknown use
#define MRO_BURNOUT_ON 0x04 //Advanced, to check if loadcell is burnt out

//Filter Register Values
#define FR2_SINC_AVERAGING_2048 0x80  //Base sample rate of 50 Hz
#define FR2_SINC_AVERAGING_1024 0x40  //Base sample rate of 100 Hz
#define FR2_SINC_AVERAGING_512 0x20   //Base sample rate of 200 Hz
#define FR2_SINC_AVERAGING_256 0x10   //Base sample rate of 400 Hz

#define FR1_SKIP_ON 0x02 //the FIR filter on the part is bypassed
#define FR1_SKIP_OFF 0x00
#define FR1_FAST_ON 0x01 //FIR is replaced with moving average on large step, sinc filter averages are used to compensate
#define FR1_FAST_OFF 0x00

#define FR0_CHOP_ON 0x10 //When the chop mode is enabled, the part is effectively chopped at its input and output to remove all offset and offset drift errors on the part.
#define FR0_CHOP_OFF 0x00 //Increases sample rate by x3

//DAC Register Values
#define DACR_OFFSET_SIGN_POSITIVE 0x00
#define DACR_OFFSET_SIGN_NEGATIVE 0x20
#define DACR_OFFSET_40MV 0x10
#define DACR_OFFSET_20MV 0x08
#define DACR_OFFSET_10MV 0x04
#define DACR_OFFSET_5MV 0x02
#define DACR_OFFSET_2P5MV 0x01
#define DACR_OFFSET_NONE 0x00

//current settings
#define CURRENT_MODE_1_SETTINGS (MR1_BU_UNIPOLAR | MR1_WL_24_BIT)
#define CURRENT_MODE_0_SETTINGS (MR0_HIREF_5V | MR0_RANGE_10MV | MR0_CHANNEL_1)


init.c
Code:
/*----------------------------------------------------------------------------
File: S_INIT.C

Description
   Implementation of InitSystem() function.

Project            : Operating System for 16f88---->Test weighing scale with AD7730
Created for Version: 1.0
Updated for Version: 1.0
Last Date Modified : 06/02/2016

Copyright(c) 2016 by Chris_Kal
All Rights Reserved.
----------------------------------------------------------------------------*/


/******************* Pin Description...**************************************/


//1      RA2/AN2/CVREF/VREF-         NOT USED            OUTPUT
//2      RA3/AN3/VREF+/C1OUT         NOT USED            OUTPUT
//3      RA4/AN4/T0CKI/C2OUT         NOT USED            OUTPUT
//4      RA5/MCLR/VPP               NOT USED            OUTPUT
//5      VSS
//6      RB0/INT/CCP1               AD7730_READY         INPUT
//7      RB1/SDI/SDA               SPI_SDI               INPUT
//8      RB2/SDO/RX/DT               SPI_SDO               OUTPUT
//9      RB3/PGM/CCP1               AD7730_SELECT         OUTPUT
//10     RA1/AN1                  SOFT UART TX         OUTPUT
//11     RA0/AN0                  SOFT UART RX         INPUT
//12     RA7/OSC1/CLKI               NOT USED            OUTPUT
//13     RA6/OSC2/CLKO               NOT USED            OUTPUT
//14     VDD                     
//15     RB7/AN6/PGD/               NOT USED            OUTPUT
//16     RB6/AN5/PGC/               NOT USED            OUTPUT
//17     RB5/SS/TX/CK               NOT USED            OUTPUT
//18     RB4/SCK/SCL               SPI_SCK               AUTO

/*The following files must be place to the main file (internal clock 8MHz)

#include <16F88.h>
//#fuses HS,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#fuses INTRC_IO,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay(clock=8000000)
#define AD7730_SELECT PIN_B3
#define SPI_SCK       PIN_B4
#define SPI_SDI     PIN_B1  //mosi
#define SPI_SDO     PIN_B2  //miso


#use spi(master, di=SPI_SDI, do=SPI_SDO, clk=SPI_SCK, mode=0, baud=500000, stream=STREAM_SPI_AD7730,FORCE_HW)//or baud=1000000

//SOFT UART SETUP
#use rs232(baud=9600, xmit=PIN_A1, rcv=PIN_A0,FORCE_SW)

*/

//#include <16F88.h>


/********Init System***********/

void InitSystem(void)
{
   set_tris_a(0x02);//RA0 Software Uart Input
   set_tris_b(0x23);//pins 5, 0 & 1 are inputs all others are outputs
   //setup_psp(PSP_DISABLED);       
   /*setup_timer_1(T1_DISABLED);   
   setup_timer_2(T2_DISABLED,0,1);
   setup_adc_ports(NO_ANALOGS);   
   setup_adc(ADC_OFF);    */         
   //setup_CCP1(CCP_OFF);           
   //setup_CCP2(CCP_OFF);   
   output_high(AD7730_SELECT);//set critical I/O
   
}

main file
Code:
/*----------------------------------------------------------------------------
File: weighing.c

Description
   Main application for Weighing scale using AD7730

Project            : Operating System for 16f88---->Test weighing scale with AD7730
Created for Version: 1.0
Updated for Version: 1.0
Last Date Modified : 24/02/2016

Copyright(c) 2016 by Chris_Kal
All Rights Reserved.
----------------------------------------------------------------------------*/

#include <16F88.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#fuses INTRC_IO,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay(clock=8000000)
#use rs232(baud=9600, xmit=PIN_A0, rcv=PIN_A1,FORCE_SW)

#include "AD7730.c"
#include "s_init.c"
#define SPI_SCK     PIN_B4
#define SPI_SDI     PIN_B1  //mosi
#define SPI_SDO     PIN_B2  //miso


#use spi(master, di=SPI_SDI, do=SPI_SDO, clk=SPI_SCK, mode=1, baud=250000, FORCE_HW,MSB_FIRST)//or baud=1000000

//SOFT UART SETUP
int8 result1;
int8 result2;
int8 result3;
int16 mode;
unsigned long result;


int8 first=0;
int8 nDAC;
int8 second;
int8 third;


void main(void)
{   
   InitSystem();
   output_low(RESET);
   delay_ms(250);
   output_high(RESET);
   delay_ms(250);
   printf("Welcome\r\n");
   //SendAD_Data(CR_SINGLE_WRITE | CR_MODE_REGISTER);
   //delay_ms(500);
   //spi_write(0xff);
   first = ReadStatus();
   printf("status is 0x%x\r\n",first);
  // delay_ms(500);
   nDAC = ReadDAC();
   printf("DAC is 0x%x\r\n",nDAC);
   mode=Read_Mode();
   printf("Mode is 0x%x \r\n",mode);
   output_low(AD7730_SELECT);
   SendAD_Data(CR_SINGLE_WRITE | CR_MODE_REGISTER);
   SendAD_Data(0x80);
   SendAD_Data(CURRENT_MODE_0_SETTINGS);
   while(input(READY) != 0) ;////not yet
   output_high(AD7730_SELECT);
   delay_ms(500);
   mode=Read_Mode();
   printf("Mode is 0x%x \r\n",mode);
   //waitForReady
   
   AD7730_Init();
   printf("Init finished\r\n");
   printf("Reading Registers.......\r\n");
   delay_ms(500);
   first = ReadStatus();
   printf("status is 0x%x\r\n",first);
   delay_ms(50);
   mode=Read_Mode();
   printf("Mode is 0x%x \r\n",mode);
   
   
   
   
   while(TRUE)
   {
      //From the data sheet, we need to read bytes continously but hold the AD7730 DIN pin (Arduino MOSI) low, so we send 0b0000 0000 three times
      output_low(AD7730_SELECT);
      SendAD_Data(CR_CONTINUOUS_READ_START | CR_DATA_REGISTER);
      output_high(AD7730_SELECT);
      while(input(READY) != 0) ;
      output_low(AD7730_SELECT);
      SendAD_Data(0x30);
      output_high(AD7730_SELECT);
      delay_ms(250);
      output_low(AD7730_SELECT);
      SendAD_Data(0x11);
      result1 = spi_read(0);
      result2 = spi_read(0);
      result3 = spi_read(0);
      output_high(AD7730_SELECT);


    printf("Data Registers (hex)\r\n ");
    printf("result1, HEX%x\r\n",result1);
    printf("result2, HEX%x\r\n",result2);
    printf("result3, HEX%x\r\n",result3);

  result = result3 + result2 * 256L + result1 * 256L * 256L;
  printf("result %Ld\r\n",result);
  delay_ms(2500);
}
   
}



On reset according to ad7730 datasheet the reset status reg seems to be fine (I read 0xc0) but after that all other regs is read 0.

I forgot to give you wirings:

AD7730 Board Easy PIC 6 (16f88)


SDI RB1
SDO RB2
CS/ RB3
SCK RB4
RDY/ RB5
RESET/ RB6


SYNC/ VCC
POL JUMPER TO GND

any ideas????

Thanks in advance
Chris
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Sat Feb 27, 2016 6:29 am     Reply with quote

in the ccs manual , spi_write() / spi_read() includes the following info:
Code:

This function is only available on devices with SPI hardware.



the hardware function in the F88 for SPI is on C3,4,5
your declaration #use spi is for software based SPI on other pins.

it doesn't work the way you think.

the problem:
you are mixing soft spi setup -with the HARDWARE only commands
of spi_read spi_write

They don't mix and match. time to read the CCS manual -

i might add that code like this:
Code:
SendAD_Data(MR1_MODE_INTERNAL_ZERO_CALIBRATION | CURRENT_MODE_1_SETTINGS);


is actually lot LESS CLEAR than
Code:

send_AD(0x14); // MR1_MODE_INTERNAL_ZERO_CALIBRATION  ,CURRENT_MODE_1_SETTINGS


because for debug it's too much wasted effort to figure out the bit pattern when its a bunch of defines - that could themselves be faulty.
If ANY of that stuff was VARS - it would be different - but these are #defines and not subject to change, - but IMHO, its less clear if you actually got the code right -- the way you over-document it - just my 2 cents
akaka



Joined: 18 Jul 2012
Posts: 14

View user's profile Send private message Send e-mail

PostPosted: Sat Feb 27, 2016 7:24 am     Reply with quote

Hi asmboy,
Thanks for your reply but I think you are a little bit confused.
16f88 is a 18 pin device there is no port C availiable.
Take a look at the following link which is the datasheet of 16f88

http://ww1.microchip.com/downloads/en/DeviceDoc/30487D.pdf
my configuration is proper for hardware SPI pins.

regards
Chris
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Sat Feb 27, 2016 7:48 am     Reply with quote

yes - i had pins for F886 in my head - sorry

the KEY comment stands about mixing soft SPI with hard --
i still suspect that setup_spi() - not #use spi is what you want

ie: that you are not doing what you think in SPI terms.

big picture: you do setup for SOFT spi
but then use the HARD function - which is not set up the same way.

so yes - you can see data clocked and everything - but bit order may not be right because of your "mix & match" code
akaka



Joined: 18 Jul 2012
Posts: 14

View user's profile Send private message Send e-mail

PostPosted: Sat Feb 27, 2016 8:13 am     Reply with quote

asmboy wrote:
because of your "mix & match" code


can you be more detailed about that???



I haven't found any info in ccs manual about #use spi command isused only in software interfacing.
On the contrary FORCE_HW commands is used to configure hardware pins
I'll check in .lst file if the proper registers are configured as it should be and I will keep you informed.
Tomorrow I am going to check it using oscilloscope.
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Sat Feb 27, 2016 8:36 am     Reply with quote

the manual details it rather well.

when you read the bold topic SPI

you see the following:

For software support, see #USE SPI.

you are incorrectly mixing #USE - which is for soft spi code
with hard code OUTPUT and INPUT

setup_spi() does not require a #USE SPI declaration

what is most telling is this:

go READ the heading for setup_spi()
and see what I/O functions are associated with IT.

then read
#USE SPI
and note that the ONLY function associated with IT is
Quote:

Also See: spi_xfer()


best of luck learning SPI for CCS
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Feb 27, 2016 10:37 am     Reply with quote

Also, #use spi() defaults to 32-bit transfers. If you're doing only 8-bit
transfers in your code with spi_xfer(), the easiest way to fix this is to
add the BITS=8 parameter as shown in bold below:
Quote:
#use spi(master, di=SPI_SDI, do=SPI_SDO, clk=SPI_SCK, mode=1, baud=250000, FORCE_HW,MSB_FIRST, BITS=8)
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group