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

what is wrong in this ADS1211 code ?

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



Joined: 29 Aug 2010
Posts: 14
Location: SPAIN

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

what is wrong in this ADS1211 code ?
PostPosted: Tue May 20, 2014 11:53 am     Reply with quote

I use pins: DO, SDI, DRDY and Clock, SC always selected (0).
I wish to modify CMR with BIAS=1, SDL=1, then if I check Bias pin I know if has been modified.
Xtal of ADS is 8 MHz, and micro is 12 MHz (18F46K80).
I use real circuit for test.
But result that don't write to CMR and program hangs. I think that it hangs inside write_adc_instr().
Code:

/*programa para probar el AD1211 con driver ad1211b.c

*/
#include <18F46K80.h>
#device adc=16

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   
#FUSES NOXINST                 
#FUSES HSH                      //High speed Osc, high power 16MHz-25MHz
#FUSES NOPLLEN          //4X HW PLL disabled, 4X PLL enabled in software
#FUSES NOFCMEN                  //Fail-safe clock monitor disabled
#FUSES NOIESO            //Internal External Switch Over mode disabled
#FUSES NOBROWNOUT               //No brownout reset
#FUSES BORV27                   //Brownout reset at 2.7V
#FUSES WDT_SW                   //No Watch Dog Timer, enabled in Software

#use delay(clock=12000000)

#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)

#define ADC_DRDY  PIN_D1
#define ADC_DO    PIN_D2
#define ADC_DI    PIN_D3
//#define ADC_CS    PIN_D5
#define ADC_CLK   PIN_D6

//-------------declarations--------------------
void write_adc_instr(int8 data);          //send Instuction
void write_adc_byte(int8 data);
void write_4byte(long long int value);    //serial aout of 4 bytes
void set_command(long long int value);    //send CMR
void config_ADC(void);                    //build and send CMR
long long int read_adc_3byte(void);  //serial read 3 byte                         
long long int get_tension(void);          //read 3 DOR registers

//--------------------minimum program for test--------------------
void main()


   long long int resistencia;
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   setup_timer_4(T4_DISABLED,0,1);
   Output_low( ADC_DO);   //pin ADC_DO output
   input(ADC_DI);         //input
   output_low(pin_D5);    //chip select permanently
   delay_ms(1000);        // tiempo para estabilizar el ADC
   printf("Hola Antonio Mate \n\r");
   config_ADC();        //configura el ADC
   delay_ms(100);
   printf("Hola de nuevo \n\r");
   
   while(1){
            output_high(PIN_B1);  //led on
            resistencia = get_tension();
            printf("get= %LX  -    ",resistencia);
            delay_ms(500);
            output_low(PIN_B1);   //led OFF
            delay_ms(500);
            }

   }
//-------------------------definitions-------------------------------
 void config_ADC(void)
 { int8 CMR0=100,CMR1=0,CMR2=0,CMR3=0x82;
   long long int comando;
   comando=make32(CMR3,CMR2,CMR1,CMR0);
   set_command(comando);                //carga los 4 registros de command
 }

  void write_adc_instr(int8 data)      //envia un byte
   { while(!input(ADC_DRDY));          //waiting DRDY=1
     while(input(ADC_DRDY));           //waiting falling DRDY
     delay_us(4);                   // > 5.5Txy; Txy=0.125 us with 8 Mhz clock
     write_adc_byte(data);
    }
 
 void write_adc_byte(int8 data)        //rutina de envio de un byte
 {
   int8 i,data1=data;                  //para no modificar data
   for(i=0;i<8;++i) {
                     output_high(ADC_CLK);
                     output_bit(ADC_DI, shift_left(&data1,1,0));
                     delay_us(10);
                     output_low(ADC_CLK);
                     delay_us(10);
                  }
  }
       
void write_adc_4byte(long long int data)         //envia los 4 bytes
   { long long data1=data;
      int8 i;
      for(i=1;i<=32;++i) {
                           output_high(ADC_CLK);
                           output_bit(ADC_DO, shift_left(&data1,4,0));
                           delay_us(10);
                           output_low(ADC_CLK);
                           delay_us(10);
                          }
   }
       
long long int read_adc_3byte()
{  int8 i;
   long long data=0;
   for(i=1;i<=24;++i) {
                        output_high(ADC_CLK);
                        delay_us(10);
                        shift_left(&data,3,input(ADC_DO));
                        output_low(ADC_CLK);
                        delay_us(10);
                     }
 
   return ((data>>8)&0x00FFFFFF);
}

long long int get_tension()
{     long long value=0;
      write_adc_instr(0xC0); //read from addres of DOR               
      value=read_adc_3byte();
      return  value;                       
}

void  set_command(long long value)
   {
     write_ADC_instr(0x64);      //write to command addres 100
     write_adc_4byte(value);
     input(ADC_DI);
   }

All your opinions will be very well received
antonio mate
asmboy



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

View user's profile Send private message AIM Address

PostPosted: Tue May 20, 2014 4:37 pm     Reply with quote

Code:

{ while(!input(ADC_DRDY));          //waiting DRDY=1
     while(input(ADC_DRDY));           //waiting falling DRDY
   


look at the data sheet!!!!!!
there will NEVER be a LOW time(or any transition) until you write some (valid) SPI data !!!!!!
amate



Joined: 29 Aug 2010
Posts: 14
Location: SPAIN

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

reading from ads1211
PostPosted: Wed May 21, 2014 8:47 am     Reply with quote

I have read notes about ADS and I have not seen you say, more and more, with the same config and write functions now I can modify the 4 bytes of CMR, that means that are correct.
But I cannot read, I have this modified function for read the 3 bytes of DOR.
Code:

long long int read_adc_3byte()  //lee los 3 Bytes de DOR
{   
   int8 i;
   long long data=0;
   while(!input(ADC_DRDY));          //waiting DRDY=1
   while(input(ADC_DRDY));           //waiting falling DRDY
   delay_us(4);                   // > 5.5Txy; Txy=0.125 us with 8 Mhz clock
   write_adc_byte(0xC0);
   input(ADC_DI);
   delay_us(5);
   for(i=0;i<24;++i) {   
                        output_high(ADC_CLK);
                        delay_us(5);
                        shift_left(&data,3,(input(ADC_DI)));
                        output_low(ADC_CLK);
                        delay_us(5);
                      }
   return (data);
}

There are here any error?
Thanks for be patient
asmboy



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

View user's profile Send private message AIM Address

PostPosted: Wed May 21, 2014 12:11 pm     Reply with quote

Without seeing AND studying the full SETUP sequence you sent the part (?)
no way to tell what error might lurk in the routine you extracted here.
and be sure to look at figure 6 in the data sheet-
as 0Xc0 looks wrong as an "INSR" prefix for starters ........
remember that you are dealing with a VERY complex part.
amate



Joined: 29 Aug 2010
Posts: 14
Location: SPAIN

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

reading from ads1211
PostPosted: Wed May 21, 2014 1:33 pm     Reply with quote

Hello, thanks for your time and collaboration.
0xC0 - b11000000-is the instruction for Read (1) , three bytes (10) from address 0000.(High Byte of DOR).
If the Command register is written OK means that this part of code is correct,I check this changing Bias and Data rate.
Then, after sending this instruction is when happen the problem, but I don't see if is software problem, or timing problem.
This is the minimum software I use now for test:
Code:
/*program for testing ADS1211
*/
#include <18F46K80.h>
#device adc=10

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   
#FUSES NOXINST                 
#FUSES HSH                      //High speed Osc, high power 16MHz-25MHz
#FUSES NOPLLEN                  //4X HW PLL disabled, 4X PLL enabled in software
#FUSES NOFCMEN                  //Fail-safe clock monitor disabled
#FUSES NOIESO                   //Internal External Switch Over mode disabled
#FUSES NOBROWNOUT               //No brownout reset
#FUSES BORV27                   //Brownout reset at 2.7V
#FUSES WDT_SW                   //No Watch Dog Timer, enabled in Software

#use delay(clock=12000000)

#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)

#define ADC_DRDY  PIN_D1
#define ADC_DO    PIN_D2
#define ADC_DI    PIN_D3
//#define ADC_CS    PIN_D5
#define ADC_CLK   PIN_D6

//-------------declarations--------------------
void write_adc_instr(char data);          //send Instruction
void write_adc_byte(char data);           //serial out of 1 byte                                                 
void write_4byte(long long int value);    //serial aout of 4 bytes
void set_command(long long int value);    //send CMR
void config_ADC(void);                    //build and send CMR
long long int read_adc_3byte(void);       //serial read 3 byte of DOR                         


//--------------------minimum program for test--------------------
void main()


   long long int medida;
   float resistencia;
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   setup_timer_4(T4_DISABLED,0,1);
   input(ADC_DI);         //input
   output_low(pin_D5);    //chip select permanently
   delay_ms(1000);        // tiempo para estabilizar el ADC
   config_ADC();          //configura el ADC
   delay_ms(100);
 
   while(1){
            medida = read_adc_3Byte();
            resistencia= (float)medida*5600.0/0x7FFFFF ;
            printf("get= %LX  - RES= %W1.6\n\r",medida,resistencia);
            delay_ms(1000);
            delay_ms(1000);
            }

   }
//-------------------------definitions-------------------------------
 void config_ADC(void)
 { char CMR0=0x38,CMR1=0x01,CMR2=0,CMR3=0x80;//Byas=1,DataRate=312
   long long int comando;
   comando=make32(CMR3,CMR2,CMR1,CMR0);
   set_command(comando);                //carga los 4 registros de command
 }

  void write_adc_instr(char data)      //envia un byte
   {
     while(!input(ADC_DRDY));          //waiting DRDY=1
     while(input(ADC_DRDY));           //waiting falling DRDY
      delay_us(4);                   // > 5.5Txy; Txy=0.125 us with 8 Mhz clock
      write_adc_byte(data);            //send Byte
    }
   
void write_adc_4byte(long long int data)         //send 4 bytes
   {  long long data1=data;
      int8 i;
      for(i=1;i<=32;++i) {
                           output_high(ADC_CLK);
                           output_bit(ADC_DI, shift_left(&data1,4,0));
                           delay_us(5);
                           output_low(ADC_CLK);
                           delay_us(5);
                          }
     }

void  set_command(long long value)
   {
     write_ADC_instr(0x64);   //write (0),4 (11)Bytes to adress 100-(b01100100)
     write_adc_4byte(value);
   }

long long int read_adc_3byte()  //read 3 Bytes de DOR
{   
   int8 i;
   long long data=0;
   while(!input(ADC_DRDY));          //waiting DRDY=1
   while(input(ADC_DRDY));           //waiting falling DRDY
   delay_us(4);                   // > 5.5Txy; Txy=0.125 us with 8 Mhz clock
   write_adc_byte(0xC0);    //instruction for read, 3 bytes fron address 000                                                   
   input(ADC_DI);         
   for(i=0;i<24;++i) {   
                        output_high(ADC_CLK);
                        delay_us(5);
                        shift_left(&data,3,(input(ADC_DI)));
                        output_low(ADC_CLK);
                        delay_us(5);
                      }
   return (data);
}
may be one timing problem?
Ther are not  much soft. abou ADS1211/ads1213 in this forum
amate



Joined: 29 Aug 2010
Posts: 14
Location: SPAIN

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

reading from ads1211
PostPosted: Wed May 21, 2014 1:38 pm     Reply with quote

sorry i erased this code line inside the main() :config_ADC();
Must be between two delays_ms(1000).
Thanks
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed May 21, 2014 4:02 pm     Reply with quote

If you want help, post a link to the schematic for your board.

This forum doesn't support image posting, so you need to post a link
to the schematic if you bought the board, or if you made the board
by yourself, then upload the schematic to a free image hosting website
such as http://postimage.org/ and post a link to it here.


----
Edited to put in correct link for image hosting service.


Last edited by PCM programmer on Mon Jun 29, 2015 3:33 pm; edited 1 time in total
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Thu May 22, 2014 3:25 am     Reply with quote

For studying your program we need to know what communication method you are using: 2, 3, 4, or multi-wire?
As PCM Programmer said, a schematic picture here will say more than 1000 words.

I can't solve your problem, but here are a few things I noticed to make your program better:
1) Your write_adc_byte(0 function is writing data to ADC_DI, but the write_adc_4byte() function writes to ADC_DO. Even without knowing your hardware connections this seems like a bug to me.

2) Variable types like int and long are not compatible between different compilers. Best is to use types like int8 and int32. You are already using int8, but instead of int32 you are using 'long long int'. Not wrong, but confusing.

3) Try to be consistent in how you code. For example you are using function names with capital letters and other times not, for example: 'output_low' and 'Output_low'. One for loop is counting 0 up to 8, the other from 1 up and including 32. The programming style for how you use the '{}' characters and indentation is different in many locations. etc.

4) The #use RS232 line always should include the 'ERRORS' parameter so the compiler can reset the UART in case of errors. Without this you have to write your own code to reset error conditions.

5)
Code:
#FUSES HSH                      //High speed Osc, high power 16MHz-25MHz
According to comment this fuse is for 16<Hz or higher. You have defined a clock speed of 12MHz. Something is wrong here.
amate



Joined: 29 Aug 2010
Posts: 14
Location: SPAIN

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

working with ADSS1211
PostPosted: Sun May 25, 2014 4:40 am     Reply with quote

You are right Ckielstra, there are many errors, I am learning.
I have modified according you, and modify the functions. Now I can read and write in all registers of ADS1211.
Was important to do reset in ADS. In self calibrate write values in registers OFF and FULL far from limits 0 and 0x7FFFFF, may be the consequence that DOR don't correspond with reality, it is smaller.
May be that the analog module of ADS were damaged?
Also, readings from DOR are 2% different. What can be the reason?
I will follow for solving these points.
Thanks a lot for your support.

Antonio Mate
Code:
/*programa para probar el AD1211
 use DRDY, SDIO,SCLK,connected to PIC according #defines
 CS is conected permanently to ground(PIN D5=0)
   DR=432, Vref=2.625, Channel=1;
*/
#include <18F46K80.h>
#device adc=10

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   
#FUSES NOXINST                 
#FUSES HSM                      //High speed Osc, high power 16MHz-25MHz
#FUSES NOPLLEN                  //4X HW PLL disabled, 4X PLL enabled in software
#FUSES NOFCMEN                  //Fail-safe clock monitor disabled
#FUSES NOIESO                   //Internal External Switch Over mode disabled
#FUSES NOBROWNOUT               //No brownout reset
#FUSES BORV27                   //Brownout reset at 2.7V
#FUSES WDT_SW                   //No Watch Dog Timer, enabled in Software

#use delay(clock=12000000)

#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)

#define ADC_DRDY  PIN_D1
//#define ADC_DO    PIN_D2
#define ADC_DIO   PIN_D3
#define ADC_CLK   PIN_D6

//-------------declarations--------------------
void write_adc_instr(char data);          //send Instruction
void write_adc_byte(char value);              //serial out of 1 bytes
void write_4byte(int32 value);            //serial aout of 4 bytes
void write_adc_3byte(int32 value);
void set_command(int32 value);            //send CMR
void config_ADC(void);                    //build and send CMR
void ADC_reset(void);
void ADC_self_cal(void);
void ADS_wait(void);
int8 read_adc_byte(void);               //serial read 1 byte
int32 read_adc_3byte(void);               //serial read 3 byte
int32 read_DOR(void);                    //serial read 3 byte of DOR
int32 read_ADC_full(void);
int32 read_ADC_off(void);
void set_ADC_offset(int32 value);
void set_ADC_full(int32 value);
void timer_04(void);       //more times used => less rom


//--------------------minimum program for test--------------------
void main()   //program for test diferents functions and ADS1211


   int32 medida,full_data,off_data;
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   setup_timer_4(T4_DISABLED,0,1);
   input(ADC_DIO);                              // ADC_DI input
   output_low(pin_D5);                          // chip select permanently
   printf("Hola 1 - ");
   config_ADC();                                // configura el ADC
   //ADC_self_cal();
   set_ADC_offset(0x000000);
   set_ADC_full(0x7FFFFF);
   
   while(1){
            medida = read_DOR();
            full_data=read_ADC_full();
            off_data=read_ADC_off();
            printf("DOR = %LX ; off= %LX  ;full= %LX ;DORd= %Lu \n\r",
                                       medida,off_data,full_data,medida);
             delay_ms(200);
            }

   }
//-------------------funtions definitions-------------------------------

void timer_04()
               {delay_us(4);}
            //------------------   
 void config_ADC(void)
 { ADC_reset();
   ADC_self_cal();
   char CMR0=0xB0,CMR1=0x04,CMR2=0,CMR3=0x80;
   int32 comando;
   comando=make32(CMR3,CMR2,CMR1,CMR0);
   set_command(comando);                   //write 4 bytes in command address
 }
            //-------------------------
 void ADS_wait(void)
      { while(!input(ADC_DRDY));          //waiting DRDY=1
        while(input(ADC_DRDY));           //waiting falling DRDY
      }
            //------------------------------
  void write_adc_instr(char data)         //send 1 instr. byte
   { ADS_wait();
     write_adc_byte(data);
     input(ADC_DIO);
   }
                //-------------------
  void write_adc_byte(char data)          //send 1 instr. byte
   { int8 i;
     timer_04();//delay_us(4);                   
     for(i=0;i<8;++i) {
                     output_high(ADC_CLK);
                     output_bit(ADC_DIO,shift_left(&data,1,0));
                     timer_04();//delay_us(4);   // > 5.5Txy; Txy=0.125 us with 8 Mhz clock
                     output_low(ADC_CLK);
                     timer_04();//delay_us(4);
                    }
    input(ADC_DIO);
   }
               //---------------------     
void write_adc_4byte(int32 data)         //sen 4 byte serial
     {  int32 data1=data;
        int8 i;
        timer_04();
        for(i=1;i<=32;++i) {
                           output_high(ADC_CLK);
                           output_bit(ADC_DIO, shift_left(&data1,4,0));
                           timer_04();//delay_us(4);
                           output_low(ADC_CLK);
                           timer_04();//delay_us(4);
                          }
       input(ADC_DIO);  //ADC_DIO input direction
     }
            //----------------------------
 void write_adc_3byte(int32 data)         //sen 4 byte serial
     {  int32 data1=data;
        int8 i;
        data1<<=8;
        for(i=1;i<=24;++i) {
                           output_high(ADC_CLK);
                           output_bit(ADC_DIO, shift_left(&data1,4,0));
                           timer_04();//delay_us(4);
                           output_low(ADC_CLK);
                           timer_04();//delay_us(4);
                          }
       input(ADC_DIO);  //ADC_DIO input direction
     }
            //----------------------
void  set_command(int32 value)
   {
     write_ADC_instr(0x64);      //write to command addres 100
     write_adc_4byte(value);
     ADS_wait();
   }
            //---------------------
void set_ADC_offset(int32 value)
  {write_adc_instr(0x48);
   write_ADC_3byte(value);
  }
            //----------------------------
  void set_ADC_full(int32 value)
  {write_adc_instr(0x4C);
   write_ADC_3byte(value);
  } 
            //------------------------------
int32 read_adc_3byte(void)  //read 3 Bytes
   {   
      int8 i;
      int32 data=0;
      timer_04();//delay_us(4);                 // > 5.5Txy; Txy=0.125 us with 8 Mhz clock
      for(i=1;i<=24;++i) {   
                        output_high(ADC_CLK);
                        shift_left(&data,3,input(ADC_DIO));
                        timer_04();//delay_us(4);
                        output_low(ADC_CLK);
                        timer_04();//delay_us(4);
                        }
      return (data);
   }
                  //-----------------------------
char read_adc_byte(void)  //read 1 byte
   {   
      int8 i,data=0;
      timer_04();//delay_us(4);
      for(i=1;i<=8;++i) {   
                        output_high(ADC_CLK);
                        timer_04();//delay_us(4);
                        shift_left(&data,1,input(ADC_DIO));
                        output_low(ADC_CLK);
                        timer_04();//delay_us(4);
                        }
      return (data);
   }
                  //-----------------------
int32  read_DOR()                //read DOR register
   { int32 DOR_data;
     write_ADC_instr(0xC0);      //order for read 3 bytes beginig in addres 000
     DOR_data=read_adc_3byte();  //read the 3 bytes
     return DOR_data;
   }
                  //--------------------   
 void ADC_reset(void)         //reset ADS1211
      { output_high(ADC_CLK);
        delay_us(37);         //300*Txy
        output_low(ADC_CLK);
        delay_us(5);
        output_high(ADC_CLK);
        delay_us(87);         // 700*Txy
        output_low(ADC_CLK);
        delay_us(5);
        output_high(ADC_CLK);
        delay_us(137);        //1100*Txy
        output_low(ADC_CLK);
        delay_us(10);
      }
                  //---------------------   
 void ADC_self_cal(void)   //self calibration
      {
       write_ADC_instr(0x05);
       write_adc_byte(0x20);
       ADS_wait();
       }
               //----------------------------
 int32 read_ADC_off()      //Read OFF register
       {int32 off_data;
        write_ADC_instr(0xC8);      //order for read 3 bytes beginig in addres 000
        off_data=read_adc_3byte();  //read the 3 bytes
        return off_data;
       }
               //------------------------------
 int32 read_ADC_full()     //Read FULL register
       {int32 full_data;
        write_ADC_instr(0xCC);      //order for read 3 bytes beginig in addres 000
        full_data=read_adc_3byte();  //read the 3 bytes
        return full_data;
       }
 
amate



Joined: 29 Aug 2010
Posts: 14
Location: SPAIN

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

Solved the problem
PostPosted: Mon May 26, 2014 7:57 am     Reply with quote

Problem was the external erratic Vref, it very noisy.
Once I solved this, the software function correctly.
I am doing one circuit for read 4 PT1000/100 with ADS1211 and one micro,with automatic detection of type.
When finish I will facilitate the complete program.
Thanks a lot Very Happy
antonio mate
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