一、材料
先放上图片
材料:树莓派3b+、tea5767模块(收音机模块)和4根杜邦线。
树莓派3b+大约200元,tea5767模块大约25元吧,杜邦线不值钱。
顺便说一下,tea5767芯片更便宜,但需要自己做PCB.我动手能力比较差,所以直接买了。
树莓派淘宝直接搜就行,tea5767模块放个我买的的链接。
https://m.tb.cn/h.eNmGD2h
二、连接
现在开始接线。首先通过资料我们可以知道,tea5767模块与外部是SPI通信,接下来就简单了。我们需要找到树莓派的SPI口,将其与tea5767连接起来就可以了。
这个是树莓派的引脚图,左边这一排SDA.1和SCL.1就是SPI通信口,SCL属于时钟线,SDA属于数据线。
此时查看购买的tea5767模块的背面,背面图如下
我们可以看到它有4个引脚,5V接树莓派上的任意一个5v引脚,gnd也是一样,SDA接树莓派的SDA.1,SCL接树莓派的SCL.1,连接的话使用材料的4根杜邦线,于此同时,把耳机和收音机的天线接上。注意了,这两个孔形状一样,别接错了,接错的时候耳机应该不会有沙沙的声音。怎么区分喇叭和天线的孔呢?看上面这张图,模块的背面画了喇叭和天线,什么意思我就不说了。
编程
现在到了最欢乐的coding时刻。
Python
如果你习惯Python开发,请参照https://www.jianshu.com/p/104457f30b94文章的内容(感谢)。这篇文章不是我的,
评论者是我,我就是那个把喇叭和耳机接反的人。。。还要提醒一句,树莓派3b+检测出来的是I2C-1,直接运行作者的代码,很提示错误。所以安装smbus后,需要解包,然后根据Python提示的错误,修改smbus的代码才能正常运行。我测试过,没有问题,但没有深入了解代码。
C++
如果你习惯C++开发,那我们志同道合。首先还是参照https://www.jianshu.com/p/104457f30b94(感谢)文章,安装i2c-tools ,同时打开树莓派configure的I2C口(默认关闭),这几步是关键的。操作不明白的问度娘和google,如果也出现了和Python一样的错误,请修改smbus的代码。我们需要打开I2C设备,此时还需要下载wiringpi库。
wiringpi安装请参照https://blog.csdn.net/qq_16775293/article/details/80785520(感谢)。
一切OK,此时我们需要了解wiringpi操作I2C的接口
wiringPiI2CSetup(int <从机地址>);
打开i2c设备。
输入的是7位的从机地址,不需要输入i2c设备节点路径。
返回的是linux标准的设备文件描述符。
实际的处理过程是这样的:
wiringPi自动检测i2c设备文件路径(/dev/i2c-0或/dev/i2c-1);
然后打开文件,获取到了标准文件描述符;
然后通过ioctl设置从机地址。
int wiringPiI2CWrite(int fd,int data);
往从机写一个字节。
也就是从机地址后的一个字节,通常是command。
<起始> + <从机地址W> + + <结束>
int wiringPiI2CWriteReg8(int fd, int reg, int data);
往从机指定的reg写入1个字节。
<起始> + <从机地址W> + + + <结束>
int wiringPiI2CWriteReg16(int fd, int reg, int data);
往从机指定的reg写2个字节,先传输低8位,后传输高8位。
<起始> + <从机地址W> + + <data低8位> + <data高8位> + <结束>
int wiringPiI2CRead(int fd);
从从机直接读取一个字节,不写入任何cmd。
<起始> + <从机地址R> + <读1个字节> + <结束>
int wiringPiI2CReadReg8(int fd, int reg);
读取从机指定reg的一个字节。
<起始> + <从机地址W> + + <起始> + <从机地址R> + <读1个字节> + <结束>
int wiringPiI2CReadReg16(int fd, int reg);
读取从机指定reg的两个字节,先传输低8位,后传输高8位。
<起始> + <从机地址W> + + <起始> + <从机地址R> + <读低8位> + <读高8位> + <结束>
以上一大段介绍是我从https://blog.csdn.net/nicekwell/article/details/78623967 (感谢)copy的。
实际上我们只需要使用wiringPiI2CSetup这一个接口就够了,其他的读写IO的函数我使用过,不知道为什么一直不行。所以我直接使用了最基本的read和write函数。控制tea5767的代码是我搬移的,本来原作者的代码是服务于tea5767模块和单片机的C代码,我将它移植到了树莓派上,同时改成c++代码,增加了一些必要的功能,比如将搜索信息保存到文件,再次启动就不需要重新搜台了。
初始化
bool LocalFm::Initialize()
{
wiringPiSetup();
if (false == TEA5767_Initialize()) {
printf("FM Device Init Failed\n");
return false;
}
return true;
}
bool LocalFm::TEA5767_Initialize()
{
int fd = wiringPiI2CSetup(SLAVE_ADDRESS);
if (fd < 0) {
printf("I2C Device Init Failed\n");
return false;
}
m_dwDevFd = fd;
return true;
}
首先调用wiringPiSetup(),这个函数在使用wiringpi前必须调用,然后再调用wiringPiI2CSetup(SLAVE_ADDRESS),SLAVE_ADDRESS是tea5767模块的从机地址0x60。在树莓派终端输入sudo i2cdetect -y 1就可以看出:
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: – -- – -- – -- – -- – -- – -- –
10: – -- – -- – -- – -- – -- – -- – -- – --
20: – -- – -- – -- – -- – -- – -- – -- – --
30: – -- – -- – -- – -- – -- – -- – -- – --
40: – -- – -- – -- – -- – -- – -- – -- – --
50: – -- – -- – -- – -- – -- – -- – -- – --
60: 60 – -- – -- – -- – -- – -- – -- – -- –
70: – -- – -- – -- – --
I2C读写
读操作
void LocalFm::TEA5767_Read(unsigned char *data)
{
read(m_dwDevFd, data, 5);
#ifdef DEBUG_ON
printf("Read Data:");
for(int i = 0; i < 5; i++) {
printf("0X%02X ", data[i]);
}
printf("\n");
#endif
}
m_dwDevFd是wiringPiI2CSetup函数返回的指向I2C设备节点的指针,data是你要写入的数据,5是写入数据的字节数。tea5767模块一次需要写入5个控制字节。
写操作
void LocalFm::TEA5767_Write(unsigned char *data)
{
write(m_dwDevFd, data, 5);
#ifdef DEBUG_ON
printf("Write Data:");
for(int i = 0; i < 5; i++) {
printf("0X%02X ", data[i]);
}
printf("\n");
#endif
}
写操作和读操作类似,也是5个字节的写入。
总结
关于自动搜台、Preset Up、Preset Down等等功能请参照我的资源
https://download.csdn.net/download/qq_26654257/11828292
资源5个积分,谢谢支持。