This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

ADS1230: My function for read ads1230 Help me pls...

Part Number: ADS1230

Hello everybody, i do it for read adc.

#define SCLK1 PORTB|=(1<<PORTB2)
#define SCLK0 PORTB&=~(1<<PORTB2)
#define PDWN1 PORTB|= (1<<PORTB3)
#define PDWN0 PORTB&=~(1<<PORTB3)

#define DOUT (PINB&(1<<PINB1))

// DOUT B1 SCLK B2 PDWN B3

#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
#include "rs232.h"

uint32_t veri=0;


uint32_t adcoku(void)
{
	uint32_t bilgi=0;
	
		while(DOUT);
		for(int i=0; i<20; i++)
		{
			SCLK1;
			if(DOUT)
			{
				bilgi|=0x00001;
				SCLK0;
				bilgi<<=1;
			}
			else
			SCLK0;
			bilgi<<=1;
		}
	
	return bilgi;
}

Where is the error ?

  • Hello user5093154,

    is it an exam?
    Tell us what you get or what kind of error you have or... tell us your story.
  • Hi user5093154,

    Welcome to the E2E forum! The best way to verify your code is to use an oscilloscope or logic analyzer to verify that the communication is as expected. You must make sure you have waited long enough for the DRDY/DOUT output of the ADS1230 to settle before attempting to read the pin. The SCLK period must have a minimum high time of 100ns and a minimum low time of 100ns, so the total period should be at least 200ns (5MHz maximum SCLK frequency with the CLK pin tied low on the ADS1230). If you send a scope or logic analyzer shot I can help you with analysis of the timing. You will probably need to add some delays after SCLK1 and SCLK0. You must wait at least 100ns after the SCLK1 before attempting to read the pin.

    One other thing you should do is make sure you send a total of 21 SCLKs to force DRDY/DOUT high (see Figure 26 on page 15 of the ADS1230 datasheet). After reading the result, the last bit could be a high or a low. To accurately poll the DRDY/DOUT pin for a new conversion you must first force DRDY/DOUT high first. So send one more SCLK pulse after the 'for' loop and prior to the 'return'.

    Also, as the result is a 20-bit binary two's complement output , you must properly sign-extend the result to 32-bits. The most significant bit is the sign bit and you are saving to an unsigned value. See the section DATA FORMAT on page 13 of the datasheet. You should save to a signed int32 and properly sign-extend the ADS1230 result or you risk having invalid data for negative code values.

    Also, make sure that the PDWN is high or the ADS1230 will be in a powered down state.

    Best regards,
    Bob B
  • I understand you Mr. Bob, I will solve u said mistakes. Thank you.

    Best regards.

  • Mr. Bob Its my new code

    int32_t adcoku(void)
    {
    	int i;
    	int32_t bilgi=0;
    	
    
    	
    		for(i=0; i<20; i++)
    		{	
    			SCLK1;
    			if(DOUT)
    			{
    				bilgi|=0x00001;
    			}
    			SCLK0;
    			bilgi<<=1;
    		}
    			
    
    	
    	return bilgi;
    }

    And This logic analyzer results.

  • Hi,

    Your timing is ok for communication to read the data, but you must make sure the data are available before attempting to read the result.  Notice the first sets of clocks in the Saleae plots where DOUT remains high.  The result is not valid here as the conversion hasn't completed.  You must first wait for DRDY/DOUT to go low before trying to read.  Note that in the completed set of clocks shown, DRDY/DOUT transitions after the first SCLK.  You need to wait until after DRDY/DOUT goes low, then read the results, and send and extra clock to force DRDY/DOUT back high again.  So the previous code 'while(DOUT)' should have worked for polling to make sure conversion is complete.

    Also, you still need to properly sign-extend the 20-bit value to 32-bit.  The code should be something more similar to:

    int32_t adcoku(void)
    {
    	int i;
    	int32_t bilgi=0;
    	
    
    	        while(DOUT); //Wait for DRDY/DOUT to go low signaling end of conversion before reading result
    		for(i=0; i<20; i++)
    		{	
    			SCLK1;
    			if(DOUT)
    			{
    				bilgi|=0x00001;
    			}
    			SCLK0;
    			bilgi<<=1;
    		}
    			
                    SCLK1; // Add extra clock to force DRDY/DOUT high
                    SCLK0; 
                    // sign-extend negative results
                    if(bilgi & 0x80000) bilgi |= 0xFFF00000;
    	
    	return bilgi;
    }

    Best regards,

    Bob B

  • Thank you Mr. Bob solved problem. Best Regards. Have a nice day.