项目中用到了TI的24bit ADC ADS131M04,datasheet里介绍SPI读写确实很弯弯绕绕的,结果我把自己也绕进去了……写IC驱动从来没浪费这么长时间过,就读个ID,撑死也就是1天的事,要么IIC要么SPI,一天总能调通了吧……结果楞是花了2天时间没读出chip ID,冒火!!!!结果发现……特么自己给自己蠢哭了。
分享:①SPI配置,按照手册P10页的,CPOL=0,CPHA=1即可,问题也就出在这里,我用stm32cubemx配置,结果把CPHA选择了1 Edge……并且检查了很多次SPI配置,没发现这里的问题,造成的后果就是:ID本来读出来是FF24,一直读出的却是7F92,7F92左移一位就是FF24,一直不知道哪里错了。CPHA选择2 Edge就好了(这才是CPHA=1。CPHA=0时选择 1 Edge)。
②读取单个寄存器,似乎当前读取出来的并不是当前指令对应的响应,而必须要在下一次指令时候响应上一次指令的结果,这很奇怪,继续研究下再补充吧。
(继续…)
例如,SPI初始化后,我做验证读取:
{
uint8_t temp[3];
uint8_t rxbuf[3];
HAL_GPIO_WritePin(GPIOD, ADC_RST2_Pin, GPIO_PIN_RESET);
HAL_Delay(5);
HAL_GPIO_WritePin(GPIOD, ADC_RST2_Pin, GPIO_PIN_SET);
temp[0]=0xa0; // 读取0x01 STATUS 寄存器
temp[1]=0x80;
temp[2]=0x00;
HAL_GPIO_WritePin(GPIOD, ADC_CS2_Pin, GPIO_PIN_RESET);
HAL_SPI_TransmitReceive(&hspi2, temp, rxbuf, 3, 1000);
HAL_GPIO_WritePin(GPIOD, ADC_CS2_Pin, GPIO_PIN_SET);
printf("id1=%X id2=%X\r\n", rxbuf[0], rxbuf[1]);
temp[0]=0xa0;// 读取0x01 STATUS 寄存器
temp[1]=0x80;
temp[2]=0x00;
HAL_GPIO_WritePin(GPIOD, ADC_CS2_Pin, GPIO_PIN_RESET);
HAL_SPI_TransmitReceive(&hspi2, temp, rxbuf, 3, 1000);
HAL_GPIO_WritePin(GPIOD, ADC_CS2_Pin, GPIO_PIN_SET);
printf("id1=%X id2=%X\r\n", rxbuf[0], rxbuf[1]);
}
因为我是用的默认规定的“字”=24bit,手册里又说“SPI通信帧由几个‘字’组成。。。”,我的理解是SPI的读写至少都要以24bit起,所以我用了3个字节,不足3字节的,在最后补0x00。
测试代码的用意是读取2次0x01寄存器的值,实际输出是:FF24,050F。
这更加验证了说法——本次读取的值(即response)是上次指令的response,这很搞人,不过根据手册给出的时序图,表达的确实是这个意思吧:
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/ddc0820acfed411985effdd0f2bb8540.png#pic_center)
图片是Figure 8-23. Reading a single register,不知道上传成功没,这个编辑器不太熟。
IC复位后,第一个会输出ID,(手册中说发送复位指令后,输出ID,但是这里我并没有发送复位指令,纯硬件复位);0x01寄存器复位值是0x0500,这里是050F,表示1-4个通道都有新数据准备好了,可以去读出。
【有新的进展将持续更新,也欢迎大家留言提供帮助!!!这TI的手册纯英文,真不如ADI的手册好用,要不是嫌弃AD7175-2太贵,我也懒得继续研究ads131M04了。。。】