【一起玩MicroPython】05 I2C驱动与FM收音机
在FM接收的方案上纠结了半天,最先选择的是tea5767,这货控制简单,有挺多参考代码,控制起来非常方便,如果不使用搜台模式的话,只要写入5个字节就可以了。这5个字节里面最重要就是PLL,而这个是可以根据本地电台,事先算好的。但是tea5767的最大缺点是信号一般,总觉得噪声比较大,不知道是天线问题还是啥。于是换了个Si4703,图省事,买了模块,上面自带了音频口,硬件比较方便,可这软件吧,真是要坑死,跳了半个月,跳出来了,音质还不错,就选他了。以上两个模块都使用i2c接口。F4DISCO上用了两个I2C,#1 DISCO上用了PB6和PB9,已经有上拉4.7K。I2C2,是PB10(SCL)和PB11(SDA),没有上拉,PB10和音频有联系,不过可以使用。对于I2C而言,在python下已经很简单了,指定一个对象,用scan方法确定I2C的地址,然后就可以开始读写数据了(一般地址就按照说明书上给的就行,但是为了保险起见,可以scan确认下)。I2C的读写有两种方式,主要区别在于是否需要指定从器件的寄存器地址。如果不需要,则用recv和read,对应的函数原型如下:
I2C.recv(recv, addr=0x00)
I2C.send(send, addr=0x00)以上是无需指定内部寄存器地址的,recv的第一个参数可是是个整数,用来指定接收多少个字节,需要指定一个变量来接收,收到的是一个bytearray。而send里面的,一般是一个bytearray,就是用来发送的数据。由于python本身没有字节类型,所以一般都是从整数或者字符串利用struct的pack函数来生成要发送的字节。
如果收发时需要指定器件内部的寄存器地址,必须使用mem_read和mem_write。函数原型如下:
I2C.mem_read(data, addr, memaddr)
I2C.mem_write(data, addr, memaddr)可以看到,比上面就多了一个memaddr,不过为什么python的函数不能重载呢?
当然为了驱动Si4703,还要连一个RST,放到了PB12上。另外SDIO引脚还兼顾总线选择,所以先拿来派下用场
rst=Pin('B12',Pin.OUT_PP)
rst.low()
sdio=Pin('B11',Pin.OUT_PP)
sdio.low()
nrst.high()
i2c=I2C(2,I2C.MASTER,baudrate=400000)
i2c.scan()可以正常扫描的地址是16,就是0x10。这个和datasheet里面的是不一样的。
然后开始控制寄存器,首先读一下。总共16寄存器,每个2字节。16是地址。i2c.recv(32,16)可以看到器件ID都是对的。注意读取的顺序0A-0F-00-09,每次读取都从头开始读。然后就是把驱动从C++移植过来,对python不是很熟悉,绕了很多路,不过还是成功了,最关键一点,就是每次更新寄存器前,先读一遍,这样才比较安全。目前搜台还没做,因为暂时用不到,只做了调台和调节音量。给出测试代码如下(首先要把si4703.py放到pyb里面去)
from si4703 import SI4703
from pyb import Pin,I2C
radio=SI4703(I2C(2),Pin('B11'),Pin('B12'))
radio.powerOn()
radio.setChannel(996)
radio.powerOff()
radio.setVolume(5)终于能正常工作了,离胜利又进了一步。Si的驱动放附件,供参考。不过这个模块用的人不多吧
汇总帖在此:
【一起玩MicroPython】—by johnrey
https://bbs.eeworld.com.cn/forum.php?mod=viewthread&tid=489205&fromuid=536508
很详细,支持楼主一个 :victory:看那样子也要竣工了 太好用了 <p></p>
<p>刚好需要,下一个来试试。</p>
页:
[1]