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.

ADS1292寄存器无法读写

Other Parts Discussed in Thread: ADS1198, ADS1292, ADS1291, ADS1292R


#include "io430.h"
#include "spwm.h"
#include "init.h"
#include "voltage.h"
#include "portdef.h"
#define uchar unsigned char
#define FALSE 0
#define TRUE 1
#define RDATAC 0x10
#define SDATAC 0x11
#define Addr_ID 0x00
#define Addr_CONFIG1 0x01
#define Addr_CONFIG2 0x02
#define Addr_LOFF 0x03
#define Addr_CH1SET 0x04
#define Addr_CH2SET 0x05
#define Addr_RLD_SENS 0x06
#define Addr_LOFF_SENS 0x07
#define Addr_LOFF_SSTAT 0x08
#define Addr_RESP1 0x09
#define Addr_RESP2 0x0A
#define Addr_GPIO 0x0B


int t=1;
char MST_Data = 0xAA,SLV_Data = 0xff;
unsigned char a[12];
unsigned char b[12];
unsigned char regdata[11]={0x02,0xa3,0x10,0x05,0x05,0x00,0x00,0x40,0xc3,0x00,0x03};//内部测试信号
//unsigned char regdata[11]={0x02,0xe3,0x10,0x00,0x00,0x30,0x0f,0x40,0x02,0x01,0x03};//二通道心电测试信号,无呼吸
int m;

void delay_ms(int ms)
{
int i,j;
for(j=0;j<ms;j++)
for(i=0;i<8000;i++);
}

void delay_us(int us)
{
int i,j;
for(j=0;j<us;j++)
for(i=0;i<8;i++);
}

//-------------------------------------------------------------------------
// 发送ADS1198单字节命令
//-------------------------------------------------------------------------
void ADS1198_Send_CMD_One(uchar cmd)
{
while (!(UCB1IFG&UCTXIFG)); // USCI_B0 TX buffer ready?
UCB1TXBUF = cmd; // Transmit data
//UCA1TXBUF = cmd;
}
void ADS1198_Read_CMD_One()
{
while (!(UCB1IFG&UCRXIFG)); // USCI_B0 TX buffer ready?
while (!(UCA1IFG&UCTXIFG)); // 接收数据字节
UCA1TXBUF = UCB1RXBUF; // Transmit data
}

void ADS_REG(unsigned char com,unsigned data)
{
unsigned char i;
for(i=0;i<45;i++);
ADS1198_Send_CMD_One(com);
for(i=0;i<45;i++);
ADS1198_Send_CMD_One(0X00);
for(i=0;i<45;i++);

ADS1198_Send_CMD_One(data);

}

void ADS_RREG(unsigned char com)
{
unsigned char i;
for(i=0;i<45;i++);
ADS1198_Send_CMD_One(com);
for(i=0;i<45;i++);
ADS1198_Send_CMD_One(0X00);
for(i=0;i<45;i++);
ADS1198_Read_CMD_One();

}
//-------------------------------------------------------------------------
// 传输ADS1198多字节命令
//-------------------------------------------------------------------------
void ADS1198_Send_CMD_Muti(uchar cmd,uchar len,uchar dat[])
{
uchar i;
ADS1198_Send_CMD_One(cmd); // 发送第一字节命令+地址
ADS1198_Send_CMD_One(len-1); // 发送第二字节命令,发送数据长度

for(i=0;i<len;i++)
{
ADS1198_Send_CMD_One(dat[i]); // 发送多字节数据
}
}
//-------------------------------------------------------------------------
// 接收ADS1198多字节命令
//-------------------------------------------------------------------------
uchar ADS1198_Recive_Data(uchar cmd,uchar len,uchar dat[])
{
uchar i;
ADS1198_Send_CMD_One(cmd); // 发送接收命令第一字节+地址
ADS1198_Send_CMD_One(len-1); // 发送接收第二字节命令,接收数据长度

for(i=0;i<len;i++)
{
//ADS1198_Send_CMD_One(0); // 发送SPI时钟,DOUT=0

if(UCB1IFG&UCRXIFG) // 判断接收标志
{
dat[i] = UCB1RXBUF; // 接收数据字节
while (!(UCA1IFG&UCTXIFG)); // 接收数据字节
UCA1TXBUF = dat[i];

}
else
{
return FALSE;
}
}

return TRUE;
}
//-------------------------------------------------------------------------
// 连续采集模式下接收数据
//-------------------------------------------------------------------------
void ADS_Read()
{
unsigned char i;
_CS;
for(i=0;i<9;i++);
ADS1198_Send_CMD_One(0X00);
for(i=0;i<9;i++);
if(UCB1IFG&UCRXIFG) // 判断接收标志
{

while (!(UCA1IFG&UCTXIFG)); // 接收数据字节
//UCA1TXBUF = UCB1RXBUF; // 接收数据字节
UCA1TXBUF = UCB1RXBUF;
}

CS;
for(i=0;i<9;i++);

}
//-------------------------------------------------------------------------
void ADS1198_Init(void)
{
uchar d[8];

START; // 禁止采集
CS;
_RESET;
delay_ms(100);
RESET; // 复位置高
delay_ms(1000); // 延时1S
_RESET; // 复位1198
delay_ms(200); // 延时100MS
RESET; // 复位清除
delay_ms(100);
_START;
_CS;
delay_us(1);
ADS1198_Send_CMD_One(SDATAC); // 发送停止命令
delay_us(8);
ADS_RREG(0x20|Addr_ID);
ADS_REG(0x40|Addr_CONFIG2,0XA8);
delay_ms(10);
ADS_RREG(0x20|Addr_CONFIG2);


ADS_REG(0x40|Addr_CONFIG1,0X01);
ADS_RREG(0x20|Addr_CONFIG1);

ADS_REG(0x40|Addr_LOFF,0XF0);
ADS_RREG(0x20|Addr_LOFF);

ADS_REG(0x40|Addr_CH1SET,0X65);
ADS_RREG(0x20|Addr_CH1SET);

ADS_REG(0x40|Addr_CH2SET,0X65);
ADS_RREG(0x20|Addr_CH2SET);
ADS1198_Send_CMD_One(RDATAC); // 连续读命令


START; // 开始数据采集
// }
}


int main(void)
{

WDTCTL = WDTPW|WDTHOLD; // Stop watchdog timer

System_init(); //系统时钟设置
UART_init(); //串口初始化以及配置
SPI_init(); //SPI初始化以及配置
ADS1198_Init();
while(1)
{
if((P4OUT & BIT6)==0x00)
ADS_Read();
}

}

上面是ADS1292的硬件电路图,以及网上移植过来的代码,现在出现问题是不能读写寄存器,但是DRDY(500HZ)以及时钟信号(4MHZ)都能正常产生。想请问一下是硬件问题还是程序的时序或者什么问题,已经调试很久没有调通。

  • DRDY(500HZ)以及时钟信号(4MHZ)都能正常产生。想请问一下是硬件问题还是程序的时序或者什么问题?

    还不能确定. 不能读取寄存器, 那么 SPI 通信线上的波形是怎么样的,

    还有, 通信线的焊接和连接正常与否, 也改检查一下.

  • 现在不能确定到底是硬件问题还是程序问题,ADS1292使用内部时钟,主控输出SCLK为4M,DIN和DOU上没有波形输出,关于硬件应该这样检查时候正常工作?
  • 建议您通过示波器看下时序是否正确,参考datasheet Figure 1.
  • 我遇到了和你一模一样的问题。我是ADS1291.现在您解决了吗?分享一下哈。

    在手册中有这么一句话:SCLK can only be twice the speed of fCLK during register reads and writes. 你该一下sclk试一试。反正我是不行。

    我读写寄存器又鼓捣了一下,搞定了。其实我都不明白为什么就好了。我也搞了好几天没头绪。气得我把代码都删了,然后重新写了一遍,然后就好了。

    你的初始化函数有问题:START引脚高电平是开始数据转化。上来就错了。

    给你个参考

    /*
    返回值=0,配置成功;=1配置失败。
    */
    uint8_t ConfigADS129X(void)
    {
    uint8_t array[12] = {0},flag_fail = 0;
    unsigned char regdata[11]={ 0x03, //01h,连续采样模式+1kSPS采集速率
                                                        0xA8, //02h,配置使用内部2.42V参考电压 +内部CLK输出(内部产生512KHz的fclk)
                                                        0x10, //03h,默认值
                                                        0x60, //04h,开启通道1 + 增益=12 + 常规输入
                                                        0x81, //05h,关闭通道2 +增益=6(默认+ 输入短接
                                                        0x00, //06h,默认值
                                                        0x00, //07h,默认值
                                                         0x00, //08h,LOFF_STAT:内部512KHzHzfclk,4分频====》128kHz fmod
                                                      //0x40, //08h,LOFF_STAT:外部2.048MHzHzfclk,16分频====》128kHz fmod
                                                      0x00, //09h,RESP1:默认值
                                                      0x02, //0Ah,RESP2:默认值
                                                      0x0C}; //0Bh,GPIO:默认值

    //1.引脚初始化
    GPIO_WriteBit(AD_GPIO_Port,AD_nRST_Pin | AD_nCS_Pin, Bit_SET);
    GPIO_WriteBit(AD_GPIO_Port,AD_START_Pin, Bit_RESET);

    //2.通过引脚复位芯片
    GPIO_WriteBit(AD_GPIO_Port,AD_nRST_Pin, Bit_RESET);
    delay_ms(100);
    GPIO_WriteBit(AD_GPIO_Port,AD_nRST_Pin, Bit_SET);
    delay_ms(100);

    //3.芯片上电后默认进入RDATAC模式。如果想要发送控制命令需先退出RDATAC模式。
    SendCmd(SDATAC);

    //4.配置寄存器
    WriteReg(0x01,11,regdata); //配置所有11个寄存器
    //5.读取寄存器,验证配置是否生效
    ReadReg(0x00,12,array); //读取所有12个寄存器
    for(uint8_t i = 1;i<12;i++){
    if(array[i] != regdata[i-1]){
    flag_fail =1;
    break;
    }
    }

    if(flag_fail == 1)
    return(1);

    return(0);

    }

  • SCLK和DRDY的时序是没有问题,其他还需要重新试试.
  • 明天先按照你的方法和参考代码试试,能留一个联系方式交流一下吗?谢谢!
  • 你留下联系方式,我加你!
  • 我qq是1007557796

  • 你好,我前两天也遇到了和你同样的问题。有几个点你检查一下。

    1. 在连续读模式下,不能读写寄存器。在连续读模式下,首先要发命令停止 SDATAC 。然后才能发送其他命令。

    2. 手册里面这样描述,1292 接收多字节命令时,解析一个字节需要 7.2us。因此你发送多字节命令时,两个字节之间的间隔至少要到8us。

    The ADS1291, ADS1292, and ADS1292R serial interface decodes commands in bytes and requires 4 tCLK cycles
    to decode and execute. Therefore, when sending multi-byte commands, a 4 tCLK period must separate the end of
    one byte (or opcode) and the next.
    Assume CLK is 512 kHz, then tSDECODE (4 tCLK) is 7.8125 μs.

  • 您应该调通了 我也有问题请教您 可以加我一下么 qq1581297508