FTDI BITBANG软件实现i2ctools

小小的串口也能当I2C

FT232R作为一个质量比较好的串口,很多搞嵌入式的手头都会有一个,价格在20元左右,支持BITBANG模式也就意味着可以调试I2C,做这个小东西的想法很久了,把手头的FT232串口发挥到极致。每次一个新的I2C传感器或者摄像头的SCCB想要调试总是太麻烦了,还要先写一个单片机或者拿到树莓派上用i2c-tools。终于熬过期末考试,在家休息两天,做好后拖了几天才开始写博客,主要是写了也没什么人会看,一直再考虑是否要当一个UP主,没有写下去的动力,算是沽名钓誉,也是想的分享一下知识有所肯定。
后续还要扩展EEPROM的支持和SPI FLASH的读取和烧写,以后也会坚持更新。

前情提要

上一篇文章:FT232R(FDTI最常用和廉价的芯片之一)的BITABNG三种模式,即为本篇功能实现基础
源码链接:github:rede97/tinyboard-tools

这份代码已经基本实现了i2c-tools,原本是linux上非常实用的工具可惜windows是没有的,可以扫描I2C总线上的所有设备,读取8bit寄存器的数据,16bit还没有实现,我拿了GY91试验了下,发现是没有问题的,手头也没有更多的I2C模块了。

线路连接

TX->SCLRX<-->SDA,直接连接就可以使用,不需要额外的连接之前想的太复杂了。
在这里插入图片描述
那两个10K的上拉电阻没有也是可以用的,毕竟这玩意没有开漏输出,之前还搞了一个肖特基二极管把推完变成了开漏输出,还有模有样4.7Kohm上拉电阻,当了回讲究怪。RX用来控制和读取SDA的电平,BITBANG模式是没有办法中途切换输入输出模式的,所以需要两个引脚并到一起,TX用来发生SCL的时钟,接线就是这个样子。

最终成果

这里只接了GY91,参数0是第0个FTDI设备,0x68MPU9250,0x76是气压计BMP280

PS ~> .\i2cdetect.exe 0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- --
70: -- -- -- -- -- -- 76 --

i2cdump用来扫描0x68设备的寄存器,0x75寄存器who am i也就是0x71

PS ~> .\i2cdump.exe 0 0x68
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00: c5 ce e0 0e a0 17 25 cf fa f0 fb fd 00 5a 5b 77
10: bf b9 a5 00 00 00 00 00 00 00 00 00 00 00 00 00
20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
30: 00 00 00 00 00 00 00 00 00 00 01 e3 9c e3 7c cd
40: 6c fa 60 ff 1f 00 3b ff f0 00 00 00 00 00 00 00
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
60: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 1f 89
70: 00 00 00 00 00 71 00 15 fa 00 eb 12 00 22 82 00
80: c5 ce e0 0e a0 17 25 cf fa f0 fb fd 00 5a 5b 77
90: bf b9 a5 00 00 00 00 00 00 00 00 00 00 00 00 00
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
b0: 00 00 00 00 00 00 00 00 00 00 01 e3 9c e3 68 cc
c0: 24 fa 80 ff 15 00 2b ff a0 00 00 00 00 00 00 00
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
e0: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 21 22
f0: 00 00 00 00 00 71 00 15 fa 00 eb 12 00 22 82 00

原理

配置FT232环境那一部分就不说了,上一篇文章里安排的明明白白,FT232R插上USB就是干!

芯片的配置

0x03对应0b0011D0(TX-->SCL)D1(RX<-->SDA)为输出。配制成其他管脚也是没有问题的。同步BITBANG模式都是先读取再输出电平,但是一开始配置为读取就只能读取没办法输出电平了。

ftStatus = FT_SetBitMode(handle, 0x03, FT_BITMODE_SYNC_BITBANG);

实际波特率是写进去波特率的6倍,IO的输出速率并不是真的只有9.6kHz。

ftStatus = FT_SetBaudRate(handle, 9600);

清理RX缓冲区,如果之前的程序退出的时候,接收缓冲的数据没有读取完,这次就会被原模原样读出来,不会被清空的。不清空出了bug我可不负责哦~

FT_Purge(handle, FT_PURGE_RX);

下面是扫描0x68地址的ACK信号判断的MPU9250是否存在,可以照着这个思路理解源码的其他部分。这里I2C序列生成的API可以参考ArduinoAPI,基本是一致的。
至于为什么使用序列,需要注意的是,FTDI的驱动将序列发送个FT232芯片输出是需要一段时间的,序列不宜太短,这样会降低通信的效率,必须生成一段足够长的序列,然后读回结果然后判断解析。

uint8_t seq[64] = {0}; //波形序列
uint32_t nbytes;
uint32_t idx = i2c_begin(seq, 0x68); // begin序列
idx += i2c_stop(seq + idx); //stop序列
print_wave(seq, idx, 2); //输出WaveDrom支持的序列格式

FT_Write(handle, seq, idx, (LPDWORD)&nbytes);
FT_Read(handle, seq, nbytes, (LPDWORD)&nbytes);
print_wave(seq, idx, 2); //输出最终的响应后的序列结果

看看最终的输出结果吧!

# 生成用于输出的序列
1..0.10.10.10.10.10.10.10.10.10.1
1.0.1.....0..1..0.............10.
# 最终接收到的序列
1..0.10.10.10.10.10.10.10.10.10.1
1.0.1.....0..1..0...........1..0.

如果数字看起来够直观,就把他转换成时序图,这个图是有WaveDrom生成的,SDAO是第一个要输出的序列,SDAI是读入的第二个序列。I2Cbeginstart加上send发送addr|w|acksend后都会跟一个SDA高电平周期,用来接收从机的ACKstop是高电平拉高SDA复位I2C总线,具体参考I2C标准。
在这里插入图片描述
start信号是将SDASCL高电平期间拉低。
在这里插入图片描述
然后发送地址0x68和写信号0
在这里插入图片描述
这里是ack信号和stop信号,可以看出这里两个信号的区别,原本SDAO输出的高电平在ACK周期被拉低,说明这个设备地址在I2C总线上是存在的。stop信号则是SCL高电平器件被拉高,stop信号后的电平是需要多发送一个序列才可以读取到的,实际上没有我补充出来了。

如果有帮助的话支持一下

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值