欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

用RDA5807M实现收音机功能

程序员文章站 2024-03-04 10:16:05
...

使用RDA5807m实现调台收音功能


最近用RDA5807M实现调台收音的功能,在这里记录下整个历程(主要是程序实现)。
RDA5807是用IIC协议通信的,我用stm32作为控制器,通过CLOCK和DATA两个引脚和stm32连接,外围电路按照规格书给的应用电路。

RDA5807M的datasheet只给出了连续读写的方式,但在其他系列比如RDA5807N编程指南里描述了标准IIC读写方式,区别于IIC的器件地址不同。

连续读写方式

连续读写方式的器件地址是0010000B,加上读写标志,即0x20(写操作)和0x21(读操作)。
连续读写的方式不可以直接操作寄存器的地址,只有一个固定的开始寄存器地址,(写0x02H,读0x0AH),内部有一个增量地址计数器。
每个寄存器都是16bit的,写寄存器默认从0x02H开始,按字节算,写进去的数据依次为0x02H的高字节,0x02H低字节,0x03H高字节…,读寄存器时,默认从0x0AH开始读,所以读出来的数据依次是0x0AH的高字节,0x0AH的低字节…
读写顺序按照datasheeet给出的时序图,用stm32任意两个引脚模拟IIC通信,要注意在发送之后是否有收到ACK。
用RDA5807M实现收音机功能

标准IIC读写方式

这是带寄存器地址的方式,IIC器件地址0010000B,加上读写标志,即0x22(写),0x23(读),这种方式可以单独对相应的寄存器操作,并且可以直接读写每一个寄存器。
用RDA5807M实现收音机功能
用RDA5807M实现收音机功能

过程记录

开始的时候这两种读写方式我都尝试过,都遇到了不同的问题。
一开始我先用标准读写方式,我能够读写,但是02H和03H这两个写不进去,写完以后读出来的跟写的不一样。
于是我就改成了用连续读写的方式,不能实现连续写,写入两个字节之后再继续写就收不到ACK。搜了很多东西,也请教了曾经做过这个的大佬,他们当时遇到的问题是IIC延时太短,来不及收到ACK,我也试过还是不行,各种办法都试了一下,甚至还有一天试了个通宵。
一个星期之后另一个队友重做了一块板(之前在IIC接口加了上拉电阻没有用,重做板之后03H还是读出来不对),加了上拉之后,其他都正常,这次的问题是03H的第四位写1读出来是0,但实际是可以正常工作。
还要注意的是IIC通信,串口通信对传输线的要求比较高,之前用杜邦线,传输数据会乱,所以建议做通信绝对不要用杜邦线。还有前面提到的延时也是必要的。频繁读写会造成RDA不正常工作或者出现奇怪的音效。
实现调频率收音也就是TUNE模式主要设置02H,03H以及读0AH,0BH。

排除所有不可能的,剩下的那个即使再不可思议,那也是事实

在什么尝试都没有用的时候,怀疑板的问题是很合理的,确认代码没有问题的情况下板也查不出来什么的时候不如重做一块。

下面是基于stm32模拟IIC的代码,按照标准IIC读写的方式

//读写寄存器
unsigned int ReadReg(u8 reg_Addr)
{
	unsigned int buf = 0;
	IIC_Start();
	IIC_Send_Byte(RDA_WRITE);
	IIC_Wait_Ack();
	IIC_Send_Byte(reg_Addr);
	IIC_Wait_Ack();
	IIC_Start();
	IIC_Send_Byte(RDA_READ);
	IIC_Wait_Ack();
	buf = IIC_Read_Byte(1);
	buf = buf<<8;
	buf = buf|IIC_Read_Byte(0);
	IIC_Stop();
	return buf;
}
void WriteReg(u8 reg_Addr, u16 value)
{
	IIC_Start();
	IIC_Send_Byte(RDA_WRITE);
	IIC_Wait_Ack();
	IIC_Send_Byte(reg_Addr);
	IIC_Wait_Ack();
	IIC_Send_Byte(value>>8);
	IIC_Wait_Ack();
 	IIC_Send_Byte(value&0xFF);
	IIC_NAck();
	IIC_Stop();
}
RDA FM系列芯片的初始操作顺序:复位 → 读取芯片ID(可有可无) → 上电(使能) → 写初始化数据。

复位和使能后都需要延时(尤其是使能后)
RDA5807M初始化:

void RDA_init(void)  
{
	unsigned int temp;
	WriteReg(RDA_R02,0x0002);  
	delay_ms(50);
	WriteReg(RDA_R02,0xc001);
	delay_ms(600);
	WriteReg(RDA_R03,0x1A10);
	WriteReg(RDA_R04,0x0400);
	WriteReg(RDA_R05,0x86ad);
	WriteReg(0x06,0x8000);
	WriteReg(0x07,0x5F1A);
}
	Frequency = Channel Spacing (kHz) x CHAN+ 87.0 MHz

设置频率(设置频率之后一定要延时):

void Set_Fre(u32 fre)  //88MHz~108MHz  200KHz步进 
{
	u16 chan, temp;
	chan = (int)((fre-87000)/200);
	temp |= chan<<6;//chan[15:6]
	temp |= 1<<4;		//tune enable
	temp |= 1;      //200k
	WriteReg(RDA_R03, temp);
	delay_ms(40);
}

写完之后读寄存器测试读的和写的是否对应
最后能够实现功能感谢队友
感谢不放弃

以上部分内容参考RDA5807M datasheet和RDA5807N 编程指南

相关标签: 电子