单片机和ads1146进行spi通信,使用的是通用io口,自己写的通信程序,发现读出的数据很乱。对寄存器写入数据,然后再读出,发现每次读出的数据都是0.读数据能读到满刻度值(0x7fff)。但怎么实验都无法读取寄存器的值。
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.
您好,我是用高脉冲触发START引脚,然后直接读取DOUT引脚上数据。发现这样的操作能够顺利的读取一次测量数据,但SCLK引脚置高电平的时间要很长,大约4毫秒。我尝试过软件命令RDATA读取方式,但每次都不能成功。在连接一片ads1146的情况下用我上面所说的高脉冲触发START引脚,然后读取测量数据的方法,读出的数据很准确。具体的方式是首先触发START引脚,然后等待DRDY引脚变低,随后把SCLK引脚置高,读取DOUT引脚上的数据,然后拉低SCLK引脚,重复16次。我用这种方式在单片ads1146上测量很管用,但写入寄存器和读取寄存器以及用软件命令读写操作,无论怎样反复试验都不能成功。
第二个问题,我最多连接了33片ads1146,相当于使用了33个测量通道,每3个通道用一片电源芯片供电。每个通道的SCLK、START、DOUT、DIN引脚连接到一起,外加上拉电阻(DOUT引脚没有上拉,因为ads1146我用的是5v电源,而连接的单片机是3.3v电源),DRDY引脚通过二极管后连接到一起。用两片16选一模拟开关外加两路GPIO作为每片ads1146的片选信号线。但实际试验的时候是,一开始我制作了一个通道的小样板,用我上述的方式试验,一切正常,测量精度很高。随后我制作了33个通道的大样板,刚开始安装好4个通道后,经过调试,用触发START 引脚然后读取DOUT上的数据也正常。但等我把33路都安装完成后,就怎样试验都不能正常工作了。期间,我试过了各种软件的读写操作命令,尝试把ads1146测量通道减少为4个,但反复试验都不能成功。
没有办法,我又拿起之前试验用的一个通道的小样板,发现读取数据正常,而且没有时间延迟现象。我的单片机的io口的时钟是10MHz,在只连接一个通道时,不用加延时代码也能正常读取数据,但是用读写命令对寄存器进行操作,或者是用RDATA命令读取数据,都不能成功。不论延时长短,读写都是失败的。我在连接5路通道试验时发现,当我把其余4个通道的SCLK信号线断开,只保留其中一个通道的SCLK信号线,读取数据正常。其他的比如START等信号线没有影响。我试验了好多天,实在是找不到问题的症结。希望您能给与指点。
由于示波器坏了,无法读取时序。
你好。第一点,根据手册第12页所附的SPI时序,应该在SCLK下降沿时读DOUT上的数据。还有,SCLK的占空比不能超过75%,如你所诉,SCLK引脚置高电平的时间很长,4ms,这很有可能不满足占空比要求。还是希望您能克服困难去找一个示波器来抓一下SPI时序与手册建议时序对比。第二点,既然你ADS1146供电是5V,单片机是3.3V,而ADS1146的逻辑高电平是0.7DVDD,即3.5V,不知道你上拉的效果如何,建议用万用表测量一下,最好将ADS1146的DVDD即数字电源接到3.3V。你这种多通道的连接方式中多个DRDY连在一起会造成数据冲突或者丢失,正常设计中DRDY都作为中断信号,建议通道设计中采用一颗中断管理方式DRDY。
Zhao:
附件(含下面代码,ADS1247)仅供你参考:
/* Read the data from the device registers */
void ads_reg_read(void)
{
u8 dummy;
int i;
u8 reg[15]; // Device has 15 registers
anyl_stop(); // Stop getting data
//DRDYIEL();
vTaskDelay(40);
CNTLOUTH();
vTaskDelay(10);
CNTLOUTL(); // Reset the SPI bus with CS to low
while(!(IFG2&UTXIFG1));
U1TXBUF=0x20; // Command for register read
while(!(IFG2&URXIFG1));
dummy=U1RXBUF;
while(!(IFG2&UTXIFG1));
U1TXBUF=0x0E; // Command for number of registers to read
while(!(IFG2&URXIFG1));
dummy=U1RXBUF;
for (i=0; i<15; ++i) {
//vTaskDelay(10);
U1TXBUF=0xff;
while(!(IFG2&URXIFG1));
reg[i]=U1RXBUF;
}