IIC驱动调试踩坑

最近需要使用一个ad的加速度传感器,虽然传感器提供SPI和IIC两种通信方式,由于传感器与主控芯片连接有一定距离,所以只能使用IIC。但是主控芯片使用的是ST cortex-M4内核的芯片,ST的IIC使用硬件总线的话总是有些问题,所以使用模拟IIC。

1.驱动编写

官方只给了一个ad自家芯片驱动的SPI例程,所以只能自己写驱动。

image

按照数据手册和时序图,写完驱动。

2.调试驱动

2.1 IIC发送无回复应答

驱动完成以后需要调试,刚开始IIC根本收不到回复,

w_ack = 1
w_ack = 1
w_ack = 1
ui8temp  = 0x 0
w_ack = 1
w_ack = 1
w_ack = 1

又重新看了下时序和代码,发现代码没什么问题,后来重启了一下,可以成功收到回复

w_ack = 0
w_ack = 0
w_ack = 0
ui8temp  = 0x 0
w_ack = 0
w_ack = 0
w_ack = 0

有时候串口也会受到J-link的影响,可能是电路有点问题。

2.2 数据读取不出来

虽然应答可以收到,但还是取不出数据,仔细看了数据手册,发现有一处细节没有注意。
image

上图红色圈到的地方,在发送完寄存器地址后,收到应答应该再次发送IIC start信号,但是给遗漏了。加上重新发送开始信号后,可以读到数据。

0xed
0xff
0xff
0xff
0xff
0xff

2.3 只能读到一次数据

虽然数据可以读到,但是如上面看到的,只有第一次可以读到,后续还是没有数据。这时我把最后一个ACK改成了1,但是还是依然如此,忽然想起来好像是我将时钟分频改了,又原来的168改成了8所以导致这种结果。

2.4 隔一次读到一次

改后是可以读到数据了,但是隔一次读一个,这又是哪出问题了,示波器看波形。
image

image

呃,什么情况,本来空闲状态都应该是高电平的,这么一会高一会低。

有点崩溃了,后来来回找了好久,才发现,上次把最后一个ACK给搞错了。改回低电平,成功读取数据。

3.总结

驱动的编写调试是嵌入式编程的基础,但这也是最复杂最让人厌烦的事情,需要耐心和细心。

韩智鸿老师说波形有些杂波,韩老师建议加104p旁路电容。IIC需要加4k7的电阻。

感谢韩智鸿老师和linuxhan的帮助。