Other Parts Discussed in Thread: ADS1291, MSP430F5529, MSP430F5522
hello everyone.
i have problem retrieving converted data from ADS1291.
this is my ADS1291 Circuit.
and i have already test this ADS1291 Circuit on bread board with MSP430F5529 development board.
and it's can work perfectly.
But now. i am using ADS1291 external CLK=2.048MZ and SPI CLOCK=4MHZ with MSP430F5522 , and i have MSP430F5522 external CLK=8MHZ.
and i found that i can't read/write ADS1291 correctly.
and after some try and error.
i found that i can write/read ADS1291 register correctly if i add a delay when i write ADS1291 register.
here is my MSP430F5522 source code
#include <msp430f5529.h>
#include <math.h>
#define START 0x80 // P2.7
#define PWDN 0xFE // P2.0
#define RESET_BT 0xBF // P2.6
#define DRDY_0 0x02 // P2.1
#define CS_0 0xEF // P4.4
char STAT0[3], RESU0[24], STAT1[3], RESU1[24];
char LOFF_P0, LOFF_N0, LOFF_P1, LOFF_N1, header, rx_data, rx_on=0, tx_on=0;
void configure_uart(void)
{
P3SEL |= BIT3 + BIT4; // P3.3,4 = USCI_A0 TXD/RXD
UCA0CTL1 |= UCSWRST; // **Put state machine in reset**
UCA0CTL1 |= UCSSEL_2; // SMCLK
UCA0BR0 = 0x08; // 8MMHz 921600 (see User's Guide)
UCA0BR1 = 0x00; // 8MMHz 921600
UCA0MCTL |= UCBRS_6 + UCBRF_8; // Modulation UCBRSx=1, UCBRFx=0
UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
UCA0IE |= UCRXIE; // Enable USCI_A0 RX inter
}
void configure_spi(void) //在這邊設定port4(解多工器) P4DIR P4OUT
{
// P1DIR |= 0x80 P1.7 for RESET_ADS
P2DIR |= 0XC1; // P2.0, 6, 7 for PWDN, RESET_BT, START
P3SEL |= BIT0 + BIT1 + BIT2; // P3.0, 1, 2 SPI option select
P4DIR |= 0X1F;
P4OUT |= ~CS_0 ;
UCB0CTL1 |= UCSWRST; // **Put state machine in reset**
UCB0CTL0 |= UCMST+UCSYNC+UCMSB; // 3-pin, 8-bit SPI master, MSB
UCB0CTL1 |= UCSSEL_2; // SMCLK
UCB0BR0 = 0x02; // /2
UCB0BR1 = 0x00; //
UCB0CTL1 &= ~UCSWRST; // **Initialize USCI state machine*
}
void main(void)
{
char i;
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
P5SEL |= BIT2+BIT3; // Port select XT2
UCSCTL6 &= ~XT2OFF; // Enable XT2
UCSCTL3 |= SELREF_2; // FLLref = REFO
// Since LFXT1 is not used,
// sourcing FLL with LFXT1 can cause
// XT1OFFG flag to set
UCSCTL4 |= SELA_2; // ACLK=REFO,SMCLK=DCO,MCLK=DCO
// Loop until XT1,XT2 & DCO stabilizes - in this case loop until XT2 settles
do
{
UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);
// Clear XT2,XT1,DCO fault flags
SFRIFG1 &= ~OFIFG; // Clear fault flags
}while (SFRIFG1&OFIFG); // Test oscillator fault flag
UCSCTL6 &= ~XT2DRIVE0; // Decrease XT2 Drive according to
// expected frequency
UCSCTL4 |= SELS_5 + SELM_5; // SMCLK=MCLK=XT2
configure_uart();
configure_spi(); // Setup SPI
P2OUT &= PWDN; //PWDN = 0
P2OUT &= RESET_BT; // P2.6 RESET_BT
P2OUT &= ~START; //START = 0
P2OUT |= ~PWDN; //PWDN = 1
P4OUT &= CS_0; // CS=0 CS Enable
while (!(UCB0IFG&UCTXIFG)); // SDATAC
UCB0TXBUF = 0x11;
while (!(UCB0IFG&UCTXIFG)); //從01h開始寫
UCB0TXBUF = 0x41;
while (!(UCB0IFG&UCTXIFG)); //寫3個暫存器
UCB0TXBUF = 0x02;
for (i = 0; i < 10; i++);
while (!(UCB0IFG&UCTXIFG)); // WREG CONFIG1 0x03 00000011 continuous mode, Data rate = 1KSPS
UCB0TXBUF = 0x03;
for (i = 0; i < 10; i++);
while (!(UCB0IFG&UCTXIFG)); // WREG CONFIG2 0xA0 10100000 internal reference 2.4 V
UCB0TXBUF = 0xA0;
while (!(UCB0IFG&UCTXIFG)); // WREG Lead-Off Control Register 0x10 00010000
UCB0TXBUF = 0x10;
while (!(UCB0IFG&UCTXIFG)); //從04h開始寫
UCB0TXBUF = 0x44;
while (!(UCB0IFG&UCTXIFG)); //寫兩個暫存器
UCB0TXBUF = 0x01;
while (!(UCB0IFG&UCTXIFG)); // WREG CH1 0x10 00010000
UCB0TXBUF = 0x10;
while (!(UCB0IFG&UCTXIFG)); // WREG CH2 0x81 10000001 power down CH2
UCB0TXBUF = 0x81;
while (!(UCB0IFG&UCTXIFG)); //從08h開始寫
UCB0TXBUF = 0x48;
while (!(UCB0IFG&UCTXIFG)); //寫一個暫存器
UCB0TXBUF = 0x00;
while (!(UCB0IFG&UCTXIFG)); // 01000000 CLK_DIV = 1 , CLK = 2.048MHZ
UCB0TXBUF = 0x40;
while (!(UCB0IFG & UCTXIFG)); // RREG starting at address 1 00100001 01h 開始讀
UCB0TXBUF = 0x21;
while (!(UCB0IFG & UCTXIFG)); // 讀8個 Registers
UCB0TXBUF = 0x07;
while (!(UCB0IFG & UCTXIFG)); // first dummy data
UCB0TXBUF = 0x00;
while (!(UCB0IFG & UCTXIFG)); // another dummy data
UCB0TXBUF = 0x00;
while (!(UCB0IFG & UCRXIFG));
RES[0] = UCB0RXBUF;
while (!(UCB0IFG & UCTXIFG));
UCB0TXBUF = 0x00;
while (!(UCB0IFG & UCRXIFG));
RES[1] = UCB0RXBUF;
while (!(UCB0IFG & UCTXIFG));
UCB0TXBUF = 0x00;
while (!(UCB0IFG & UCRXIFG));
RES[2] = UCB0RXBUF;
while (!(UCB0IFG & UCTXIFG));
UCB0TXBUF = 0x00;
while (!(UCB0IFG & UCRXIFG));
RES[3] = UCB0RXBUF;
while (!(UCB0IFG & UCTXIFG));
UCB0TXBUF = 0x00;
while (!(UCB0IFG & UCRXIFG));
RES[4] = UCB0RXBUF;
while (!(UCB0IFG & UCTXIFG));
UCB0TXBUF = 0x00;
while (!(UCB0IFG & UCRXIFG));
RES[5] = UCB0RXBUF;
while (!(UCB0IFG & UCTXIFG));
UCB0TXBUF = 0x00;
while (!(UCB0IFG & UCRXIFG));
RES[6] = UCB0RXBUF;
while (!(UCB0IFG & UCTXIFG));
UCB0TXBUF = 0x00;
while (!(UCB0IFG & UCRXIFG));
RES[7] = UCB0RXBUF;
while(UCB0STAT & UCBUSY); //SPI 如果UCBUSY=0 閒置 如果UCBUSY=1 USCI 正在接受或傳輸
_EINT();
P2OUT |= ~RESET_BT;
while(1) //把 NOSTOP 和 STOP_AD 包含住
{
while(rx_on==0); //rx_on=0 留在迴圈 rx_on不等於0 離開迴圈
rx_on = 0;
if(rx_data==0xff) goto NOSTOP; //電腦透過RS232 UART 傳開始字元 FF 給UART RX BUFFER
goto STOP_AD;
NOSTOP:
header = 0;
P2OUT |= START; //START=1 開始做ADC轉換
while (!(UCB0IFG&UCTXIFG)); // RDATAC
UCB0TXBUF = 0x10;
while(1) //進入NOSTOP迴圈後 便一值讀出ADC資料 直到UART 中斷為止(STOP_AD)
{
while((P2IN & DRDY_0)); //P2.1 DRDY_0 是否為LOW ? 如果為LOW 則跳出迴圈(ADC資料準備好了)
for (i = 0; i < 3; i++) // Read Status register 會先傳狀態暫存器 總共三筆 3*8=24BITS
{
while (!(UCB0IFG&UCTXIFG));
UCB0TXBUF = 0x00;
if(UCB0STAT & UCOE)
{
while (!(UCB0IFG&UCRXIFG));
STAT0[0] = UCB0RXBUF;
}
while (!(UCB0IFG&UCRXIFG));
STAT0[i] = UCB0RXBUF; //i=0,1,2 三筆狀態資料
}
for (i = 0; i < 6; i++) // Read Channel data 再傳CH值 ADS1291 2CH *24BITS=48BITS 一次傳8BITS
{
while (!(UCB0IFG&UCTXIFG));
UCB0TXBUF = 0x00;
while (!(UCB0IFG&UCRXIFG)); //ADS:MSB UART:LSB SPI:MSB
RESU0[i] = UCB0RXBUF;
}
RESU0[2]=RESU0[2] & 0xFE;
RESU0[2]=RESU0[2] | header;
header++;
if ( header == 2 ) header = 0;
for (i = 0; i < 3; i++) // Send Channel data to BT 傳一個CH的DATA 只有傳CH1 DATA
{
while (!(UCA0IFG&UCTXIFG)); // USCI_A0 TX buffer ready?
UCA0TXBUF = RESU0[i]; // i=0,1,2
if(rx_on>0 && rx_data==0x00) goto STOP_AD; //如果發生UART中斷 命令停止ADC取樣 則rx_on大於0 且 rx_data=0x00
}
while(UCA0STAT & UCBUSY);
rx_on = 0;
} //繼續 NOSTOP While(1) 迴圈
STOP_AD:
rx_on = 0;
}
}
#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void) //P997 UART 中斷 猜想是電腦透過RS232 UART傳資料給RX Buffer 造成RX中斷
{
rx_data = UCA0RXBUF; //UART 使用 FF當作開始字元 00當作結束字元
rx_on++;
}
can anyone explain why after i add for (i = 0; i < 10; i++); this delay when i wrote ADS1291 register then i can write/read ADS1291 register correctly?
and did i have something wrong with ADS1291 register setting?
and at the end. i sent those converted data by Bluetooth using 921600 baudrate.
and accept those data by Labview.
My Ads1291 IN1P is connetted to the output of analog amp including one INA and OPA and shift the signal to 1.5V.
my total analog amp gain = 3315
and i have already check my analog part, which is perfect.
here are the outcome i got from ADS1291.
100mVPP 5HZ sin wave
100mVPP 10HZ sin wave
200mVPP 5HZ sin wave
300mVPP 5HZ sin wave
300mVPP 10HZ sin wave
so have anyone know why i got this outcome?
are there any problem about my Firmware or my circuit?
Needs your help.
thanks for all of you.






