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

Having trouble using PIC16F1828 to communicate with ADS1255.
Goto page Previous  1, 2, 3, 4  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
olet96



Joined: 09 Jul 2014
Posts: 16

View user's profile Send private message

PostPosted: Thu Jul 10, 2014 10:22 am     Reply with quote

Version 5.026
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jul 10, 2014 2:03 pm     Reply with quote

Some tests need to be done.

1. You need to check all the connections on the ADS1255. Make sure
the reference voltages are not reversed on the two pins.

2. Check if you're getting \DRDY pulses from the ADS1255. Use your
scope. The \DRDY should periodically have low level pulses. It should
not be sitting at a continuous high level.

3. A short test program needs to be written, to see we can write to
and read from the GPIO Control Register in the ADS1255. If we can
write bytes such as 0x55 and 0xAA and read them back, then we
can be pretty sure we're successfully talking to the chip.

4. I think the driver code needs some modifications. The ads1255
data sheet says there should be a 't6' delay of 50 tclkin periods after
you send the read data command, and before you start to read data.
With an 8MHz clock, this delay would be 50/8MHz = 6 usec. The driver
code needs to be carefully reviewed, to make sure these delays are
inserted at the correct locations.

5. The driver code needs to be cleaned up. This line is sending a byte
but it has the 'bits' parameter set to 1.
Quote:
spi_xfer(ADS,val,1);

It doesn't matter with hardware SPI, because the compiler always sends
a complete byte anyway (8 bits). If software SPI was used, it would
matter. All lines where 'bits' = 1 should be changed to 'bits' = 8, just
for completeness.

6. SCLK at 2 MHz is right at the high limit for a CLKIN of 8 MHz.
It would be better to reduce it somewhat. See if it helps.

-----------
I have a question. Do you still have any interest in this project ?
If you lost interest, then I don't want to continue it. Also, when is
the project due ? When does the ads1255 have to be working ?
demedeiros



Joined: 27 Dec 2013
Posts: 71

View user's profile Send private message

PostPosted: Thu Jul 10, 2014 8:00 pm     Reply with quote

Hi PCM, i'm also working on this project. We are still actively pursuing this project, and are trying to determine if the ADS1255 is the ADC that we will move forward with. We dont have a defined time line, but would like to have this particular portion working as soon as we can.

Thank you for all of your help. It has been tremendously helpful! Olet96 is working on the short test program you have mentioned. Hopefully we'll have a test program written up tomorrow at some point.

Thanks again for all of your help!!!
olet96



Joined: 09 Jul 2014
Posts: 16

View user's profile Send private message

PostPosted: Fri Jul 11, 2014 12:22 pm     Reply with quote

I pieced together the read and write register codes from Ttelmah's original code to right to and then read back from registers on the ADC. However when im sending 0x55 and 0xAA to register 0x04 (GPIO) im reading back a 0x54 and a 0xA9, but when I tried writing a 0x01 and a 0xF0 it returned a 0x01 and a 0xF0 so im not sure whats going on exactly.

herei s the code im using
Code:

void write_regs(int8 reg_no, int8 num_bytes, int8 * data_ptr)
{
   //generic function to write to one or more registers on the ADS
   //Command to chip is 0101 reg_num 0000 num_bytes, then the bytes to send
  // output_low(CS); //select chip
   reg_no&=0xF; //ensure reg_no is 15 max
   num_bytes&=0xF; //same for number of bytes
   spi_xfer(ADS, 0x50 | reg_no, 1); //send first byte
   spi_xfer(ADS, (num_bytes-1), 1); //number of bytes to write less one
   printf("Data Ptr: 0x%X \n\r", data_ptr[0]);
   spi_xfer(ADS, data_ptr[0], 1); //send each byte
   }

int8 read_reg(int8 reg_no)
{
   int8 rval;
   //generic read function just for a single register
   reg_no&=0xF; //ensure reg_no is 15 max   
   spi_xfer(ADS, 0x10 | reg_no, 1); //send first byte
   spi_xfer(ADS, 0, 1); //read one byte
   delay_us(10);
   rval=spi_xfer(ADS,0,1); //Clock data back 
   return rval;
}

void main()
{
int val;
int val2;
int8 Data1[1];
int8 Data2[1];

Data1[0] = 0x01;
Data2[0] = 0xF0;

  output_high(CS); //ensure chip select starts high
  delay_ms(100);
 
    while(TRUE){
    output_low(CS);
    write_regs(0x04, 1, Data1);
    val = read_reg(0x04);
    output_high(CS);
    delay_ms(10);
   
    output_low(CS);
    write_regs(0x04, 1, Data2);
    val2 = read_reg(0x04);
    output_high(CS);
    delay_ms(10);
   
    printf("Val: 0x%X \n\r", val);
    printf("Val2: 0x%X \n\r", val2);

    delay_ms(1000);}
   
     }
olet96



Joined: 09 Jul 2014
Posts: 16

View user's profile Send private message

PostPosted: Fri Jul 11, 2014 1:10 pm     Reply with quote

Out of curiosity I tried writing to a different register (0x03)DRATE and was able to write a 0x55 and a 0xAA and return a 0x55 and 0xAA. So my thought is that when I'm writing to register (0x04)GPIO I'm reading back the input values because according to the data sheet "Reading these bits will show the state of the corresponding digital I/O pin, whether if the pin is configured as an
input or output by DIR3-DIR0. When the digital I/O pin is configured as an output by the DIR bit, writing to the
corresponding DIO bit will set the output state. When the digital I/O pin is configured as an input by the DIR bit,
writing to the corresponding DIO bit will have no effect. When DO/CLKOUT is configured as an output and
CLKOUT is enabled (using CLK1, CLK0 bits in the ADCON register), writing to DIO0 will have no effect."
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Jul 11, 2014 1:22 pm     Reply with quote

I think you're right. That wasn't a good register to do a R/W test on.
Since it works with the DRATE register, I think the basic SPI
communication is working.

I think the next step is to carefully review the code that reads A/D data.
There must be a problem in it somewhere, possibly with the required
delay times, such as delay 't6' in the ads1255 data sheet.
olet96



Joined: 09 Jul 2014
Posts: 16

View user's profile Send private message

PostPosted: Fri Jul 11, 2014 2:26 pm     Reply with quote

So we discovered that the code was dropping off the last byte of data by using a logic analyzer to look at the SPI bus. We were able to read each of the three bytes of data individually ( 8 bits at a time) then put them together into our desired 32 bit number and it seems to work now we just have to work on converting our unsigned 32 bit number to a signed 32 bit number and get it all to work with the strain gauge.


Here is the code we used
Code:

{
   unsigned int8 value=0;
   unsigned int8 value2=0;
   unsigned int8 value3=0;
   unsigned int32 Data = 0;
 
     //read 24bit result from chip - page 34 on data sheet
   //First wait for DRDY to drop
   while (input(DRDY)) ;
   //get here when DRDY drops   
   //write_command(ADS1255_RDATA); //Issue the read command
   spi_xfer(ADS, ADS1255_RDATA);
   delay_us(10);
   //Now need to read 24bit result
   value=spi_xfer(ADS,0,8); //read 8bits
   value2=spi_xfer(ADS,0,8); //read 8bits
   value3=spi_xfer(ADS,0,8); //read 8bits
   //now need to convert 24bit signed to 32bit
   output_high(CS); //deselect chip after read
   printf("RAW DATA: 0x%lX \n\r",value);
   printf("RAW DATA2: 0x%lX \n\r",value2);
   printf("RAW DATA3: 0x%lX \n\n\n\n\r",value3);
   Data = value;
   Data = Data<<8 | value2;
   Data = Data<<8 | value3;
   printf("Data is: 0x%lX:\n\n\n\n\n\r", Data);
   return value;
}


Thanks again for all of your help. It has been extremely helpful!!!!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Jul 11, 2014 2:55 pm     Reply with quote

That's good. For the record, can you post some of the 24 bit values
that you are reading now ? (in hex format). It's so we can compare it
to the previous bad data that you posted.
olet96



Joined: 09 Jul 2014
Posts: 16

View user's profile Send private message

PostPosted: Fri Jul 11, 2014 11:52 pm     Reply with quote

Sorry I just noticed your reply and im no longer at the shop until Monday morning however I will be sure to post some of the data then.
Ttelmah



Joined: 11 Mar 2010
Posts: 19538

View user's profile Send private message

PostPosted: Sat Jul 12, 2014 12:37 am     Reply with quote

Changing the last bit of a byte, suggests SPI reading on the wrong clock edge. However that it only does it when multi-byte transfers are used suggests the code is doing something very odd.

Try something very minor. Change the number of bits specified for the maximum transfer in the #USE SPI, to 32, rather than 24.
This is the 'maximum' that can be performed in a single transfer, and I'm wondering if the compiler gets in a twist with this being the odd '3 byte' size.

I've used multi byte transfers successfully with the #use syntax, without any problems but have always tended to set the transfer up to transfer an 'even byte' number of bits, and then used the lesser numbers in the actual transfer command.

Best Wishes
demedeiros



Joined: 27 Dec 2013
Posts: 71

View user's profile Send private message

PostPosted: Mon Jul 14, 2014 5:52 am     Reply with quote

Ttelmah,

During testing it appeared that the program was dropping the last byte, not bit. For example, on our logic analyzer, we would see the following three bytes:

Code:
0xB7   0x02 0x0C  //These are made up values



When plotting "value" before conversion to 32bit signed, only the following would print:

Code:
0x00B702


You can see how the last byte (0x0C) has not been printed.

I am not sure if this is an issue with printf or how we are printing the value?

Hopefully that clears it up. Olet96 will post some actual values later on this morning.

Thanks to the both of you for the phenomenal help!
olet96



Joined: 09 Jul 2014
Posts: 16

View user's profile Send private message

PostPosted: Mon Jul 14, 2014 7:51 am     Reply with quote

Here is some of the data we are getting from the PIC with 2.5v on the input of the ADC.

Code:

Data is: 0x00BFB9F7:                                                                             
Data is: 0x00BFB804:                                                                             
Data is: 0x00BFB8B2:                                                                             
Data is: 0x00BFB7AE:                                                                             
Data is: 0x00BFBAB6:                                                                             
Data is: 0x00BFB81E:                                                                             
Data is: 0x00BFBA4C:                                                                             
Data is: 0x00BFB9BF:                                                                             
Data is: 0x00BFB70C:                                                                             
Data is: 0x00BFB972:                                                                             
Data is: 0x00BFB908:                                                                             
Data is: 0x00BFB866:                                                                             
Data is: 0x00BFB886:                                                                             
Data is: 0x00BFB82E:                                                                             
Data is: 0x00BFB8FD:                                                                             
Data is: 0x00BFB8CC:                                                                             
Data is: 0x00BFB833:                                                                             
Data is: 0x00BFB8AF:                                                                             
Data is: 0x00BFB898:                                                                             
Data is: 0x00BFB92B:                                                                             
Data is: 0x00BFB89A:                                                                             
Data is: 0x00BFB9B2:                                                                             
Data is: 0x00BFB84A:                                                                             
Data is: 0x00BFB84A:                                                                             
Data is: 0x00BFB889:                                                                             
Data is: 0x00BFB804:                                                                             
Data is: 0x00BFB947:                                                                             
Data is: 0x00BFB830:                                                                             
Data is: 0x00BFB8EB:                                                                             
Data is: 0x00BFBAA8:
Ttelmah



Joined: 11 Mar 2010
Posts: 19538

View user's profile Send private message

PostPosted: Mon Jul 14, 2014 8:58 am     Reply with quote

All -ve....

You convert by looking at the 24th bit. If it's set, then you put 0xFF into the top byte. So the signed 32bit hex value (for the first number) is 0xFFBFB9F7. This was the extra code that I had. This gives (in decimal) -4212233. Almost exactly 1/2 scale -ve. Which 'input of the ADC'?. Remember it is the differential voltage it measures.
What have you got the gain set to?.
If this is '1', then it reads +/-5v, so if you have +2.5v on the -ve input, and 0v on the +ve input, then -ve 4194304, would be the expected reading. 17929 counts different, which is just 1/100th volt.
Looks a sensible reading if the voltages are set like this.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Jul 14, 2014 3:32 pm     Reply with quote

Ttelmah's sign extension code is in the read_data() routine in this post:
http://www.ccsinfo.com/forum/viewtopic.php?t=52447&start=3
olet96



Joined: 09 Jul 2014
Posts: 16

View user's profile Send private message

PostPosted: Tue Jul 15, 2014 3:39 pm     Reply with quote

So yesterday I had been trying to get the 24 complementary 2's converted to a signed 32 bit number and had noticed while looking at the RAW DATA that I wasn't getting what I expected to in hex with the 24 bit number I was getting from the ADC so today I tried doing a test and wrote to the register (0x01) MUX register and then set it to (0x88) which sets both inputs of the ADC to AINCOM which in this case we have tied to ground. However in doing this I noticed the RAW DATA would never go to (0x000000) demedeiros had recommended that I try changing the DRATE(0x03) register from the default 30,000SPS. So I tried setting it to 1,000SPS and noticed RAW DATA was closer to (0x000000) so I changed it to another data rate 100SPS just to see if it would change anything and RAW DATA jumped back up so at this point I'm pretty confused I have the code writing and reading back from registers so I believe its working I'm just unsure why I'm getting the results I am. I figure it would be best to make sure the ADC is functioning properly before I attempt to go any further with the conversions.

Code:

void write_regs(int8 reg_no, int8 num_bytes, int8 * data_ptr)
{
   //generic function to write to one or more registers on the ADS
   //Command to chip is 0101 reg_num 0000 num_bytes, then the bytes to send
   output_low(CS); //select chip
   reg_no&=0xF; //ensure reg_no is 15 max
   num_bytes&=0xF; //same for number of bytes
   spi_xfer(ADS, 0x50 | reg_no, 1); //send first byte
   delay_us(1);
   spi_xfer(ADS, (num_bytes-1), 1); //number of bytes to write less one
   delay_us(1);
   spi_xfer(ADS, data_ptr[0], 1); //send each byte
   output_high(CS); //and deselect
   }   
 

int8 read_reg(int8 reg_no)
{
   int8 rval;
   //generic read function just for a single register
   output_low(CS); //select chip
   reg_no&=0xF; //ensure reg_no is 15 max   
   spi_xfer(ADS, 0x10 | reg_no, 1); //send first byte
   spi_xfer(ADS, 0, 2); //read one byte
   delay_us(10);
   rval=spi_xfer(ADS,0,1); //Clock data back
   output_high(CS);
   return rval;
}

   
void main()

    int8 Setup1[1];
    int8 Setup2[1];
    int MUX_settings = 0;
    int DRATE_settings = 0;
    signed int32 result;
    Setup1[0] = 0x88;
    Setup2[0] = 0xA1;
   //setup_oscillator(OSC_INTRC|OSC_8MHZ|OSC_PLL_ON); //Shouldn't be needed but here 'in case'

   output_high(CS); //ensure chip select starts high
   //wait for supply to fully stabilise
   delay_ms(500);
   write_command(ADS1255_SELFCAL);
   delay_ms(1);
   //self calibrate
   write_regs(0x01, 1, Setup1);
   delay_us(10);
    write_regs(0x03, 1, Setup2);
   delay_us(10);
   write_command(ADS1255_STANDBY);
   output_high(CS); //and deselect
   
   
 
   
   //Now the chip is here in 'standby' mode, so to perform a conversion, you have to wake it,
   //then wait for DRDY, before issuing RDATA, and reading the reply.
   do
   {
      write_command(ADS1255_WAKEUP); //issue the wakeup command
      //now wait for DRDY, and read the data
      delay_ms(1);
     
      result=read_data();

      //Now put the chip to sleep
      write_command(ADS1255_STANDBY);
      output_high(CS); //and deselect the chip
      //here you should have a signed int32 reading in 'result'
       //result2=result*0.000000149011;
       MUX_settings = read_reg(0x01);
       printf("MUX Settings is: 0x%X \n\r", MUX_settings);
       delay_ms(1);
       DRATE_settings = read_reg(0x03);
       printf("DRATE Settings is: 0x%X \n\r", DRATE_settings);
     
       printf("DATA:%ld\n\r",result);   
      delay_ms(500);     
   }
   while (TRUE);
}
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2, 3, 4  Next
Page 2 of 4

 
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