Hi Experts,
i'm new to this forum and TI-devices so any help would be great! (At this point: sorry for my poor english!)
I'm currently trying to initialize an ADS1292R via SPI, following the quickstart-guide in the datasheet on page 63. After initialization the results on PIN DOUT are different to my expectations.
After the initialization the ADS1292R should work in RDATAC Mode. Every time DRDY goes low, the MCU shifts out 3*24Bits=72Bits (with SPI parameters: Tclk=2µs, fclk=500kHz -> Conversation_Time=72*2µs=144µs) of dummy data because otherwise the SPI Unit of the MCU will not work. So on the DOUT Pin of the ADS i would expect 24 Status Bits + 24Bits (CH1) + 24Bits (CH2) = 72Bits. However the osciloscope shows me, that the data from the ADS takes only about 102µs (From the first bit that's high to the last bit that's high). If the electrodes are touched, the Datagramm you see below DOES NOT CHANGE! If the electrodes are touched in the RDATAC MOde, i would expect wild moving bits in the last 2*24Bits.
So i think i didn't set up the ADS1292R properly in my source-code. Can anybody see major mistakes in my code below?
Picture 0: Code (main.c)
#define F_CPU 16000000 #include <avr/interrupt.h> #include <avr/io.h> #include <util/delay.h> #include "mmc_config.h" // Hier werden alle noetigen Konfigurationen vorgenommen, umbedingt anschauen ! #include "file.h" #include "fat.h" #include "mmc.h" // Hardware abhaengig #include "uart.h" // Hardware abhaengig, es kann auch eine eigene eingebunden werden ! #include "ads1292r.h" // Enthält Befehlssätze für den ADS1292R // ***************************************************************************************************************** void ADS1292R_init(void){ ADS1292R_Disable_Start(); ADS1292R_Enable_Internal_Clk(); ADS1292R_reset(); ADS1292R_SDATAC(); ADS1292R_WREG(REG_CONFIG2,0b10100000); ADS1292R_WREG(REG_CONFIG1,0b00000010); ADS1292R_WREG(REG_LOFF,0b00010000); ADS1292R_WREG(REG_CH1SET,0b00000101); ADS1292R_WREG(REG_CH2SET,0b00000000); ADS1292R_WREG(REG_RLDSENS,0b00101100); ADS1292R_WREG(REG_LOFFSENS,0x00); ADS1292R_WREG(REG_RESP1,0b11110010); ADS1292R_WREG(REG_RESP2,0b00000011); ADS1292R_Enable_Start(); ADS1292R_START(); ADS1292R_RDATAC(); } //Hardware-Commands // ***************************************************************************************************************** void ADS1292R_reset(void){ PORTC |= ( 1 << PC2); //PWDN/RESET auf high, damit Reset ausgeschlossen ist _delay_ms(1000); PORTC &= ~( 1 << PC2); //PWDN/RESET LOW -> Reset _delay_ms(10); PORTC |= ( 1 << PC2); //PWDN/RESET auf high, damit Reset ausgeschlossen ist } void ADS1292R_Enable_Internal_Clk(void){ PORTC |=(1<<PC1); //CLK_SEL auf 1 = internen Oszillator verwenden _delay_ms(1); } void ADS1292R_Enable_Start(void){ PORTC |=(1<<PC3); //START auf HIGH _delay_ms(1); } void ADS1292R_Disable_Start(void){ PORTC &= ~( 1 << PC3); //START auf LOW _delay_ms(1); } void ADS1292R_Spi_Select(void){ DDRB |= (1<< PB0)|(1<< PB0); //PORT B PIN 0 als Ausgang definieren PORTB &= ~( 1 << PB0); //CS' auf low für SPI communication _delay_ms(1); } void ADS1292R_Spi_Deselect(void){ DDRB |= (1<< PB0)|(1<< PB0); //PORT B PIN 0 als Ausgang definieren PORTB |= ( 1 << PB0); //CS' auf low für SPI communication _delay_ms(1); } //Software-Commands // ***************************************************************************************************************** void ADS1292R_SDATAC(void) { ADS1292R_Spi_Select(); SPDR = 0x11; // Send 0x11 to the ADS1x9x while(!(SPSR & (1<<SPIF)));; _delay_ms(1); ADS1292R_Spi_Deselect(); } void ADS1292R_RDATAC(void) { ADS1292R_Spi_Select(); SPDR = RDATAC; // Send 0x11 to the ADS1x9x while(!(SPSR & (1<<SPIF)));; _delay_ms(1); ADS1292R_Spi_Deselect(); } void ADS1292R_RDATA(void) { ADS1292R_Spi_Select(); SPDR = 0x12; while(!(SPSR & (1<<SPIF)));; } void ADS1292R_START(void) { ADS1292R_Spi_Select(); SPDR = START; // Send 0x11 to the ADS1x9x while(!(SPSR & (1<<SPIF)));; _delay_ms(1); ADS1292R_Spi_Deselect(); } void ADS1292R_STOP(void) { ADS1292R_Spi_Select(); SPDR = STOP; // Send 0x11 to the ADS1x9x while(!(SPSR & (1<<SPIF)));; _delay_ms(1); ADS1292R_Spi_Deselect(); } void ADS1292R_WREG(uint8_t Adresse, uint8_t Daten) { ADS1292R_Spi_Select(); SPDR = (WREG||Adresse); while(!(SPSR & (1<<SPIF)));; SPDR = 0x01; // Send 0x11 to the ADS1x9x while(!(SPSR & (1<<SPIF)));; SPDR = Daten; // Send 0x11 to the ADS1x9x while(!(SPSR & (1<<SPIF)));; _delay_ms(1); ADS1292R_Spi_Deselect(); } //SPI-Configuration // ***************************************************************************************************************** static void SPI_init(){ /* Set MOSI ans SCK Output, all others Input*/ DDRB |= (1<<DDB5)|(1<<DDB7)|(1<<DDB4); //5->MOSI, 7->CLK, 4->SS /* Enable SPI, Master, set clock rate fck/32 */ SPCR = 0x00; SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR1)|(1<<SPR1)|(1<<CPHA); SPSR = (1<<SPI2X); } //Main // ***************************************************************************************************************** int main(void){ //Ein- und Ausgänge definieren //********* PORT A *********** //not used //********* PORT B *********** //not used //********* PORT C *********** DDRC=0x00; DDRC = (1 << DDC3)|(1<<DDC1)|(1<<DDC2); //PORT C PIN 1,2,3 als Ausgänge definieren //********* PORT D *********** //not used // uart config ***************************************************** uinit(); uputs((uint8_t*)"\nBoot"); // SPI config ***************************************************** SPI_init(); // ADS config ***************************************************** ADS1292R_init(); ADS1292R_Spi_Select(); ADS1292R_Enable_Start(); while (1) { if ((PINC&0x01)==0) { uint8_t n=0; for (n=0;n<9;n++) { SPDR = 0b00000000; // Start transmission while(!(SPSR & (1<<SPIF))); } } // 3x24Bit von ADS einlesen } return; }
Picture 0.5: Code (ads1292r.h)
#ifndef ads1292r_h #define ads1292r_h #define CONFIG_SPI_MASTER_DUMMY 0xFF // Register Read Commands #define RREG 0x20 //Read n nnnn registers starting at address r rrrr //first byte 001r rrrr (2xh)(2) - second byte 000n nnnn(2) #define WREG 0x40 //Write n nnnn registers starting at address r rrrr //first byte 010r rrrr (2xh)(2) - second byte 000n nnnn(2) #define START 0x08 //Start/restart (synchronize) conversions #define STOP 0x0A //Stop conversion #define RDATAC 0x10 //Enable Read Data Continuous mode. //This mode is the default mode at power-up. #define SDATAC 0x11 //Stop Read Data Continuously mode #define RDATA 0x12 //Read data by command; supports multiple read back. //Pin declartion the other you need are controlled by the SPI library const int ADS1292_DRDY_PIN = 6; const int ADS1292_CS_PIN = 7; const int ADS1292_START_PIN = 5; const int ADS1292_PWDN_PIN = 4; //register address #define REG_ID 0x00 #define REG_CONFIG1 0x01 #define REG_CONFIG2 0x02 #define REG_LOFF 0x03 #define REG_CH1SET 0x04 #define REG_CH2SET 0x05 #define REG_RLDSENS 0x06 #define REG_LOFFSENS 0x07 #define REG_LOFFSTAT 0x08 #define REG_RESP1 0x09 #define REG_RESP2 0x0A #endif
Picture 1 CH1: SPI-Clock CH2: Pin DOUT from the ADS1292R CURSOR: Shows the Length of the Data Burst (148µs)
Picture 2: CH1: SPI-Clock CH2: Pin DOUT from the ADS1292R CURSOR: Tclk=2µs -> fclk=500kHz
Picture 3: CH1: SPI-Clock CH2: Pin DOUT from the ADS1292R CURSOR: Shows the Length of Data shifted out by the ADS1292R
Picture 4: CH1: DRDY Pin of the ADS1292R CH2: Pin DOUT from the ADS1292R CURSOR: Shows the Length of Data shifted out by the ADS1292R
Picture 5: Eagle-Schematic
Picture 6: Quick-Start-Guide from the Datasheet