使用树莓派打造一台收音机

一、材料

先放上图片
使用树莓派打造一台收音机_第1张图片材料:树莓派3b+、tea5767模块(收音机模块)和4根杜邦线。

树莓派3b+大约200元,tea5767模块大约25元吧,杜邦线不值钱。
顺便说一下,tea5767芯片更便宜,但需要自己做PCB.我动手能力比较差,所以直接买了。

树莓派淘宝直接搜就行,tea5767模块放个我买的的链接。
https://m.tb.cn/h.eNmGD2h

二、连接

现在开始接线。首先通过资料我们可以知道,tea5767模块与外部是SPI通信,接下来就简单了。我们需要找到树莓派的SPI口,将其与tea5767连接起来就可以了。

使用树莓派打造一台收音机_第2张图片这个是树莓派的引脚图,左边这一排SDA.1和SCL.1就是SPI通信口,SCL属于时钟线,SDA属于数据线。
此时查看购买的tea5767模块的背面,背面图如下

使用树莓派打造一台收音机_第3张图片我们可以看到它有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> + + + + <结束>

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个积分,谢谢支持。

你可能感兴趣的:(项目,刷题及面试总结)