SPI读取LSM303D加速度数据错误
下图展示了数据错误的测试情况
电脑右上框(串口)LSM加速度数据(红色=x轴,蓝色=y轴)一直在0和3000左右来回变,是为异常。程序流程是先读LSM303D的加速度计,后读L3GD20。
下图是此电路一主两从SPI连接图:
下图是示波器测得MISO(黄色)和LSM_CS即CS1的(蓝色)波形:
此图颇耐人寻味,是故障确立之关键,后面会详细剖析。
下图是关键程序流程:
图乃中断程序,定时5ms进入,此间先读LSM(加速度计),再读L3GD20(陀螺仪),均用STM32F1硬件读取;过一下几个函数:
下图是LSM303A_Raed函数(读加速度3轴数据):
下图是LSM303ReadReg函数(读LSM某个寄存器):
下图是LSM初始化配置:
此LSM设置通俗来说:
1.LSM以400Hz频率持续更新其acc 数据寄存器;
2.不用“转换完成”中断;
3.使用滤波器(应该无关紧要);
4.设置测量上限±12g;以及LSM内部地磁计设置。从最后的故障原因来看L3GD20的设置是无关紧要的。
一切似在掌握中,程序流畅亦合理,不知故障从何来?莫非妖人把我害?
试验1:去掉L3GD20的操作L3GD20_Read
来看结果:
居然不跳了!哼
仍贴出波形,MISO(黄色)和LSM_CS即CS1的(蓝色):
明显的,上次黄波后面一串都变0了,去掉了L3GD20_Read嘛。揪出故障既验技术亦磨心态!幸得正确范例以比之。
对故障波形做个梳理:
SPI时序不待多言,似乎除了波形有些异常和干扰外看不出时序有啥毛病。扪心自问:为啥加了L3GD20读就不行,去掉就好使??
1.读L3GD20时LSM的CS确定是高电平未使能,L3GD的读写应该不会影响到LSM!
2.不读L3GD20时LSM数据完全正确,说明时序上没有毛病!
难道:L3GD和LSM的MISO都是是推挽输出造成部分短路?
有网友指出MISO是3态门,CS高致使MISO高阻态;经测试,CS高时,都时高阻态,没问题,不会短路。
难道:焊接不牢?
焊接不牢焉能有正确读数的时候?
难道:芯片坏的?
又不能解释正确读数的时候啊!
难道:信号干扰?外星人?玄学?未见吾头大如斯也。。。
问题肯定还是出在LSM上!而且重点在引脚上;扒开LSM手册“细品”,在SPI部分找到这么一句话:SPC is the serial port clock and it is controlled by the SPI master. It is stopped high when CS is high (no transmission).
不传输的时候SCK(SPC)应该是高啊!这是一直被忽略的地方!看看SCK波形:
MothFuc,SCK并没有在CS为高的时候拉高。这可能是硬件SPI配置的问题。
试验2
让SCK在CS高时也为高,同时L3GD也改一下,重新加上L3GD20_Read:
居然就正常啦:
在看一下SCK波形:
虽然SCK只在间隙处短暂拉高,但是数据已然正常!回首这个对K3天的bug,老伙计淡定举杯,略施浅笑。