关于ADS1248读写寄存器时序问题
调试了一周时间,对ads1248的写操作仍未成功,对寄存器先写再读回,dout输出始终为零。spi时序都满足要求,reset和start始终高电平,先发送一个字节的写操作指令和寄存器地址,然后依次发送寄存器数目和数据,每个字节的间隔满足5个时钟周期的要求,但读出寄存器的值始终为零。不解问题出现在哪里,三否在发送每个字节前应该先判断/DRDY为0时,然后再发送?硬件电路按参考电路来的,也测试过,不存在问题,肯定问题在SPI上,始终搞不定,急死,望各位高手指点一二,非常感激!
Hi
将你的SPI时序发给我看一下:(包括命令,和写的值)
其中要注意:
1. Write 操作必须在power on后16mS后进行(fOSC=4.096MHz)
2. 数字写入是下降沿锁存。
时序图没有暂未保存,但通过示波器核对过单片机输出信号时序的正确性,可以确定时序符合要求,且数据在时钟下降沿锁存.如欲将MUX1和SYS0分别写入0x30和0x50,则SPI依次发送0x42 ,0x01 ,0x30 ,0x50,每个字节发送后延迟2us再发送下一字节,然后再读寄存器的值,依次发送0x22 ,0x01,0x FF,0xFF,同样每个字节发送后延迟2us再发送下一字节.写操作也是在上电很长一段时间后进行的,绝对大于16ms
Hi
见如下读寄存器的命令, 所以发送命令0x22 ,0x01即可,不需要0x FF,0xFF, 请确认?
从上图1可以看出,写完一个字节后,片选cs应该拉高并至少保持5个时钟周期,即1.2us。但从后两个时序图中可以看出,在连续写若干字节时,sclk是连续且等间隔,cs一直拉低。若将单片机的SPI模块配置为8bit,则在连续写几个字节时,相邻两个字节之间的sclk时间间隔会稍微变宽,且cs会被短暂的拉高(几时或几百个ns)。
那么,问题1:以上3个图中的时钟时序是否存在不一致的问题?实际应用中,应该遵守哪个时序图才是正确的?
问题2:若遵守后两个图的时序,即连续写若干个字节时,必须连续的sclk,且cs一直保持低,那么,单片机spi模块在连续写若干字节时cs的短暂变高是否影响正常通讯,或者反之,甚至要满足相邻字节间cs拉高不小于1.2us?
Hi
首选你需要明确片选CS的功能: CS作为ADC SPI口的控制开关,置低有效。
在不是多个ADC芯片并联的应用场合,CS脚可永远置低,SPI接口持续有效。
也可以在完成每一次转换后CS置高一下,因为在没有转换的这段时间里,DIN/DOUT都是没有数据的,所以置高是可以的。(可以看如上你的第三个图)
Hi
在正确是时序里(参照第一图), 在CS置低以后,时钟SCLK给出,DIN数据写入,DOUT输出输出,完成后CS置高再进行下个采样转换是可行的。
在这一个周期的转换内,无论你的MCU是配置3个8位还是其他,在这个周期过程中CS都被建议置低(24位的数据转换过程中,CS都是置低的)
感谢您对上述问题的解答!
还有两个问题想请教:1.对datasheet中关于bias voltage仍有困惑,请问什么情况下需要用到bias voltage?若用到时,是两个差分输入端都需要bias voltage偏置,还是其中一个通道使用?
2.在执行SYSOCAL和SYSGCAL校准指令前,是否对应的通道必须分别输入(或切换到)0V和满刻度电压值时才能正确的进行校准?在SPS=2000时,校准时间约为8.07ms,是否意味着每条校准指令均需要8.07ms的执行时间?
wenhui liu :
你好!
看了你的问题,感觉我和现在读写ADS1246是一样的情况,DOUT就是都没有数据输出,不知道你现在解决没有,能否提供一下解决方法,谢谢!
首先,确认数据在时钟下降沿捕获(或锁存),否则正常通讯无法建立。
在读写寄存器时,即便读写一个寄存器指令也不会少于3个8bit(字节),实测发现发送多个字节时cs应该一直拉低,发送完最后一个字节后再将cs拉高。采用mcu自带的SPI模块,在连续发送多个字节时,每个字节之间cs会被短暂拉高,影响了正常通讯,这也解释了为何网上好多帖子采用GPIO来模拟SPI通讯没有出现通讯异常的问题。
希望对你有帮助。
感谢wenhui liu 的提示,问题已经找到了,主要是读写寄存器的时候CS没有一直为低。
感谢您对上述问题的解答!
还有几个问题想请教:1.对datasheet中关于bias voltage仍有困惑,请问什么情况下需要用到bias voltage?若用到时,是两个差分输入端都需要bias voltage偏置,还是其中一个通道使用?
2.在执行SYSOCAL和SYSGCAL校准指令前,是否对应的通道必须分别输入(或切换到)0V和满刻度电压值时才能正确的进行校准?在SPS=2000时,校准时间约为8.07ms,是否意味着每条校准指令均需要8.07ms的执行时间?
3.ads1248内部自带的温度二极管输出电压与温度之间的关系式是什么?
1. 看上去,输入是个无极性(正负信号)信号,或者前级和1248之间做交流耦合的情况下,可以把这个bias voltage用起来。这样即可使1248内建直流工作点,不受外部影响。手册29页图11也指出了温度传感器的电容值和bias voltage建立时间的关系。这个关系可以这样理解,就是说bias voltage建立时,会通过那个开关电阻向前级的传感器隔直电容充电,如果容值越大,充电时间越长。当充到与bias voltage相等时,建立结束。
2. 手册54页,OCAL时切换到0,GCAL时切换到Full scale。校准时间应该是指每条指令的,见手册54页图82和手册32页表14。
3. 手册30页右下角,25°时对应115mV,温度系数405uV/°C,所以关系式应该是
V=115mV+405uV/°C*(T-25)
您好,我MCU采用STM32,想用STM32的硬件SPI控制ADS1246,但是DEBUG模式下单步运行写入例如0X43,用示波器检测DIN只发现DIN有0跳变到1,然后就没有变化了,不知道为什么不能写入43,。我的CS脚一直是拉低的,START脚一直拉高,下图是SPI的配置,我采用IO模拟SPI的话就没有问题,郁闷呢
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //50M时钟速度
GPIO_Init(GPIOB, &GPIO_InitStructure);
/*!< Configure ADS1246_SPI_SPI pins: MISO */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* SPI1 configuration */
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI2, &SPI_InitStructure);
/* Enable SPI1 */
SPI_Cmd(SPI2, ENABLE);
}
uint8_t SPI_SendByte(uint8_t byte)
{
/* Loop while DR register in not emplty */
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
/* Send byte through the SPI1 peripheral */
SPI_I2S_SendData(SPI2, byte);
/* Wait to receive a byte */
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);
/* Return the byte read from the SPI bus */
return SPI_I2S_ReceiveData(SPI2);
}
您能告知一下怎么回事么?拜谢
我现在发现:
我在3.0的库的环境下,配置SPI,然后调用它写入一个数据,可是SCK引脚始终都没有脉冲信号
你可以参考手册53页图81试试写寄存器,首先第一个Byte指定寄存器地址,第二个Byte指定写入的字长,然后向指定寄存器写数据。写好好,参考图80,把寄存器读出来。如果这个操作可以运行的话,则说明SPI的通信应该是没有问题的。