anyone familiar with ADS1252 from TI?

Go To Last Post
19 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi there I am a newbie who is very lost in programming this adc. I am using AVR162 but any experience and advice on how to work with this sort of adc is very much appreciated.

I have tried all possible ways that I can think of to make it work but still.. I am lost.. and desperate.

These are few codes that I attempted.

#include 
#include 
#include 

#define F_CPU 1000000UL

volatile unsigned char RDY_FLG= 0x00;
volatile unsigned char SCLK_FLG = 0x00; // sclk flag
long char data = 0;
int k;

void init (void) {

	DDRC = 0x00;      // PORTC is input (PINC1  <-- DRDY/ DOUT)
	DDRB = 0xFF;       // PORTB is output (PORTB0 --> CLK of ADC ; PORTB1--> SCLK of ADC)
	DDRA = 0xFF;         // PORTA is output (PORTA0 --> output to memory)

	PORTA = 0x00;
	PORTB = 0x00;

	TCCR1B |= (1 << CS10); // Set up timer

	while (TCNT1 <= 2304) //reset adc


	{
		PORTB |= 0x02;  //SCLK high for 6 conversion cycles +1  to reset
	}

	PORTB &= ~0x02;

	MCUCR |= 0x03;  // set up interrupt (0x03 shows rising edge interrupt)
	GICR |= 0x40; //enable pin INT0 for use
    sei();
}


ISR (INT0_vect) {  //interrupt function with its vector
    RDY_FLG = 0xFF;
    cli();  //disable interrupt
}

int main (void)
{
	//DDRB = 0xFF;       // PORTB is output
	//PORTB = 0x00;

	//TCCR1B |= (1 << CS10); // Set up timer

	while (1)
	{
        if (RDY_FLG == 0xFF) {
            TCNT1 = 0; // Reset timer value

            while (TCNT1 <= 37) {}
            TCNT1 = 0; // Reset timer value
            SCLK_FLG = 0xFF;

            while (TCNT1 <= 348)
            {
                /*if (TCNT1 <= 240)
                {
                    for (k=23; k>=0; k--)
                    {
                        PORTB |=0X02;
                        data |= (PINC1<<k);
                        PORTA = (data << 0);
                        _delay_us (0.3125);

                        PORTB &=~0x02;
                        _delay_us (0.3125);
                    }
                }
                else
                {*/
                    PORTA |= 0x02;

                    PORTB |=0X02;
                    _delay_us (0.3125);
                    PORTB &=~0x02;
                    _delay_us (0.3125);
                //}

            //}

            }
            PORTA &= ~0x02;
            RDY_FLG = 0x00; //reset RDY_FLG after 1 conversion cycle
            sei();                 // re- activate interrupt
        }


	}

	return(0);
}
#include 
#include 

#define F_CPU 1000000UL

//volatile unsigned char RDY, data;
volatile unsigned char data [1] [24];
volatile unsigned char RDY;

void init (void) {

	DDRC = 0x00;      // PORTC is input
	DDRB = 0xFF;       // PORTB is output
	DDRA = 0xFF;         // PORTA is output

	PORTA = 0x00;
	PORTB = 0x00;

	TCCR1B |= (1 << CS10); // Set up timer

	while (TCNT1 <= 2304) //reset adc
	{
		PORTB |= 0x02;  //SCLK high for 6 conversion cycles +1  to reset
	}

	PORTB &= ~0x02;

	MCUCR |= 0x03;  // set up interrupt (0x03 shows rising edge interrupt)
	GICR |= 0x40; //enable pin INT0 for use
    sei();
}

ISR (INT0_vect) {  //interrupt function with its vector
    RDY = 0xFF;
    cli();  //disable interrupt
}

int main (void) {

    int k;

    init();

	while (1) {

        if (RDY == 0xFF) {

            //data = 0x00;
            TCNT1 = 0; // Reset timer value

            while (TCNT1 <= 37) {}

           /* for (k=23; k>=0; k--) {

                data = (PINC0 <<k);
                PORTB ^= (1<<1);
                PORTB |= 0x02;
                PORTB &= ~0x02;

            }
            PORTA0 = data; */

            for (k=23; k>=0; k--) {
                PORTA = PINC0;
                PORTB ^= (1<<1);
            }

            RDY = 0x00;
            sei();
        }
    }
	return(0);
}

I have been wondering at the same point for weeks and I am still here. Please help me. Many thanks in advanced.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've used the ADS1286,7816,7822. I believe these devices all use pretty much the same interface.
Is the ADS1252 similar to any of these?

Steve

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don't think your interrupts will work as you expect. I cannot see any reason why you want to use an interrupt anyway.

  /* for (k=23; k>=0; k--) { 

                data = (PINC0 <<k); 
                PORTB ^= (1<<1); 
                PORTB |= 0x02; 
                PORTB &= ~0x02; 

            } 
            PORTA0 = data; */ 

            for (k=23; k>=0; k--) { 
                PORTA = PINC0; 
                PORTB ^= (1<<1); 
            } 

            RDY = 0x00; 
            sei(); 

Not one single comment in the above code - my crystal ball isn't working too well today. My guess is that the code won't work as you expect for many reasons. Firstly, put some comments - what are the bits on PORTA,B,C doing? I can only guess you're trying to shift in 24 bits from the ADC, so the first loop makes a little sense, what's the second loop doing?

you've got data declared as an array but you access it like a scalar, so this:
data = (PINC0 <<k);
won't work as you expect. Declare it as a long int so it can store the 24 bits worth. also, the line won't accumulate the 24bits as you want ( this I assume). Without knowing what bit on PORTC that has the data, I can't help.

maybe this might be closer to what is needed:

unsigned long data;
.....

if (PINC & (1<<DATAPIN)) //if a '1' bit
{
data |=1; //add a '1' bit
}
data <<=1; //shift the bits along 1

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Steve thanks for concern but I don't the those ADCs has similar timing and interface. My biggest problem is trying make the ADC take in valid data by writing correct timing code but it just seems to be a problem there. Anyway thanks :)

Hi Kartman sorry my code is really messy as I kept changing it all the time for trial and error thats why I missed out the comment part. I will tidy it up and post it later. Thanks for the help :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am driving my AVR162 with 1MHz ( as you can see from the " #define F_CPU 1000000UL ". I have configure the fuse to run at 1MHz by setting the prescaler(8MHz/ 8 = 1MHz)

1. So is there a way to get a squarewave output from the PORTB3 of AVR162, which HIGH for 5 clock cycles and LOW for 5 clock cycles? I need to use this squarewave to drive the SCLK of my ADC, ADS1252 so that it can output its serial digital data at the DOUT port.

My biggest problem is that I don't know how to control the timing of the output waveform. I have tried every single code in the tutorial on AVR162 ( eg. using ISR, controlling TCNT, ...) but I cant really get what I want. I am very confused... See if I use

#include 
#include 
#include 

#define F_CPU 1000000UL    // system frequency at 1MHz


int main (void)
{
   DDRB = 0XFF;

   PORTB = 0x00;
   TCCR1B |= (1 << CS10); // Set up timer
   TCNT1 =0;            // reset time value
   while(1)
   {
      if (TCNT1 >=1)     // toggle PORTB3 at every 5 clock cycle
      {
         PORTB ^= ( 1  << 3);
         TCNT1= 0;      // reset time value
      }
   }

} 

I will get a HIGH for unpredictable clock cycle and LOW for the same unpredictable clock cycle. But according to the tutorial and the AVR datasheet, the TCNT is updated at every clock cycle, why wouldn't I get IMHz when I write "if (TCNT1 >=1)" and freq of (1MHz / 5)when I write "if (TCNT1 >=1)".

2. Besides that, I tried to use "_delay_us(5)" to get the delay of 5us at HIGH and LOW. But it turns out to be 50us or 500 us ( sorry I don't remember the exact number). WHY?

3. Then I tried another way by using for loop. The timing is unpredictable. But using the code below, I was able to get a squarewave of HIGH for 3us and LOW for 5us ( I have absolutely no idea why I got this waveform, but it does drive the ADS1252 to output data)

#include 
#include 
#include 

#define F_CPU 1000000UL

int k ;


int main (void)
{
	DDRB = 0XFF;
	DDRA = 0XFF;
	PORTB = 0x00;


	while(1)
	{
		for ( k = 0; k <= 1; k++)
		{
		
			PORTB ^= ( 1 << 3 );
		}
	}

}

The above code is just producing a free-running squarewave at PORTB3, the waveform is then input to the SCLK of ADS1252.

However, I only need the SCLK after the data ready waveform, DRDY ( which HIGH for 24 clock cycles, LOW for 6 clock cycles and then HIGH for 6 clock cycles again). I still need to calculate all the delays using timer, since I am not sure about how the TCNT counts ( as mentioned above) I am not able to get any nearer to my goal... The code below is what I have tried but failed, no waveform coming out from PORTB3 and no output data from ADS1252...

#include 
#include 
#include 

#define F_CPU 1000000UL

int k ;
unsigned data = '0';

int main (void)
{
	DDRC = 0x00;      // PORTC is input (PINC1  <-- DRDY/ DOUT)
	DDRB = 0XFF;	  // PORTB is output (PORTB0 --> CLK of ADC ; PORTB3--> SCLK of ADC)
	DDRA = 0XFF;	  // PORTA is output (PORTA0 --> output the data given by ADC)
	
	
	PORTB = 0x00;
	PORTA = 0x00;

	while(1)
	{
		for ( k = 0; k <= 1; k++)	// use for loop of index 1 to give squarewave...
		{	
			PORTB ^= ( 1 << 3 );	// toggle PORTB3 to give ouput squarewave
			
			if (PORTB && 0x08)   // if PORTB3 == 1 then
			{
				if (PINC1 == 1)  // if DOUT from ADC is 1 then
				{
					data = '1';
					PORTA = ( data << 0);	// output at PORTA0
				}
				else			// if DOUT from ADC is 0 then
				{
					data = '0';
					PORTA = ( data << 0);	// output at PORTA0
				}
			}	
		}
	}

}

Sorry for my bad English... I have come to a point of desperation that I really need someone to explain my errors. It would be greatly appreciated if someone is willing to understand the ADS1252 and recommend or write some code for me... Many thanks in advanced. Happy Easter everyone =)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Read the sections on CTC and Output compare pin toggling in the datasheet - you don't need to so all this pin toggling stuff in a software loop. You just set up the time to do it all in the hardware for you (there's no way software could do it all in 5 cycles anyway - that's only about 4 opcodes).

Also why run the CPU so slow ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
You just set up the time to do it all in the hardware for you (there's no way software could do it all in 5 cycles anyway - that's only about 4 opcodes).

1.What do you mean by set up the time to do it all in hardware? Is that by using CTC and output compare without toggling any ports?

2. What is opcodes?

3. What I need to do is to wait for 36 clock cycles passes in DATA READY mode, then only starts to insert SCLK (from PORTB3) to latch out the data from ADS1252. Do you have any suggestions on how to count the 36 clock cycles?

Thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

1. Basically, yes. Set up the timer using CTC to toggle an output port bit to generate your clock,

2. An opcode is a machine instruction. Cliff was saying that trying to generate the clock the way you were was near on impossible as hte processor was not fast enough as it only had time to execute around 4 machine instructions - your 'c' code would translate to much more than that.

3. Read the datasheet carefully! 36clocks cycles is probably a minimum, so anything greater than that is ok. You can use the function delay_us() to create a suitable delay.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the advise..

I have tried to use _delay_us()before, but it does not give me the correct delay as I want...for example,

while (1)
{
  PORTB ^= (1 << 3);
  _delay_us(50);
}

The delay of 50us that I set will give 410us of delay instead. And it gives weird delay everytime i change the delay parameter...I have enable the optimisation to Os, and I have no idea what else can I do now...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Gee, about 8/1. What are your AVR fuses ser to? In particular, choice of clock sources and CKDIV8.

What speed is your AVR >>really<< running at? How have you proven your answer?

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

I've used the ADS1242 which after scanning the datasheet I find is nothing like ADS1252.

ADS1252 looks like it is quite a beast to get working properly for these reasons.

1. The analoge input isn't very nice.
2. The datasheet says power supply & grounding are incredibly important.
3. You have to generate the modulator clock externally.
4. The data interface is non-standard. (Not SPI I2C/TWI etc)

In short you'd have to have a very good reason to choose this particular ADC.

You say you are a noobie; I would suggest this is not an ADC for a beginner. Perhaps you should choose another, perhaps one with at least a standard data interface (SPI or I2C/TWI).

Nigel

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

For the fuse configuration, i have set the clock source to be 8MHz by setting the divider of 8 . I have then set to output the system clock at PORTB0. I have check the output waveform of PORTB0 and am very sure that it is working at 1MHz. The lower fuse byte is set as below:

avrdude -p m162 -c usbasp -U lfuse:w:0x22:m

CKDIV8 -- 0 ( programmed)
CKOUT -- 0 ( programmed), output system clock at PORTB0

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

CKDIV8 -- 0 ( programmed)
CKOUT -- 0 ( programmed), output system clock at PORTB0
SUT1 -- 1 ( unprog)
SUT0 -- 0 (prog)
CKSEL3-- 0 (prog)
CKSEL2-- 0 (prog)
CKSEL1-- 1 (unprog)
CKSEL0-- 0 (prog)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

CKOUT -- 0 ( programmed), output system clock at PORTB0

So, when you check that signal with a 'scope or frequency meter, what frequency of waveform do you see?

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The squarewave out from PORTB0 is 1MHz

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

And what does that tell you?

Stealing Proteus doesn't make you an engineer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I got one, and to use it i had to make a three way serial cable to see with a 2nd computer what was talking between the device and the demo program, this help me to test with my own code:
First the serial port must be set to some like:

tty = serial.Serial(0,57600,8,'N',1, 100)

i set:
tty.setDTR(1)
then, set the device:
the demo programa send this sample codes to the ADS for different rates and samples:
# 128 samples at 2000 Hz and average of 32 samples.

#DemoData2 = '*W1U*R1*W1\xaa*R1*W1\x01*W2\x00*W3!*W4\x98*W5\xfb*W68*WB\x00*G*W7\x80*W8\x00*W9 *WA\x00*C*M'

# 128 samples at 35 kHz and average of 32 samples

#DemoData4 = '*W1U*R1*W1\xaa*R1*W1\x03*W2\x00*W3!*W4\xd0*W5\xd1*W60*WB\x05*G*W7\x80*W8\x00*W9 *WA\x00*C*M'

each token must be send individually. e.g. "*W7" and "*W8" are lo and hi bytes of number of samples.

then:
tty.write("*C")
read echo and send it to get data:
tty.write("*M")
then, the reply is the data, 7+lo+hi*256 bytes
usually you get the data in packages of three bytes (24bits).

i hope this is usefull
[/i]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Did you end up getting the ADS1252 to work?

I'm programming this ADC; using it with a 16 Mhz clock, and trying to hook it up with an Arduino/Atmega328 for my greenhouse measurements.

Can you share any code that you got to succeed?

mien_noodles wrote:
Thanks for the advise..

I have tried to use _delay_us()before, but it does not give me the correct delay as I want...for example,

while (1)
{
  PORTB ^= (1 << 3);
  _delay_us(50);
}

The delay of 50us that I set will give 410us of delay instead. And it gives weird delay everytime i change the delay parameter...I have enable the optimisation to Os, and I have no idea what else can I do now...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I'm programming this ADC; using it with a 16 Mhz clock, and trying to hook it up with an Arduino/Atmega328 for my greenhouse measurements.

Did you see above?
Quote:

ADS1252 looks like it is quite a beast to get working properly for these reasons:
...

Why in the world would you need a high-speed 24-bit ADC for greenhouse measurements? I'd guess most are temperature. Why not simple thermistors, or simple digital temperature sensors?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.