原创 【连载】【ALIENTEK 战舰STM32开发板】STM32开发指南--第四十章 FM收发实验

2013-3-30 23:02 3125 17 16 分类: MCU/ 嵌入式 文集: STM32学习

  

第四十章 FM收发实验

ALIENTEK战舰STM32开发板上板载了一颗FM收发芯片:RDA5820。该芯片不但可以用来做FM接收,实现收音机功能,还可以用来做FM发射,实现电台的功能。

本章,我们将使用STM32驱动RDA5820,实现FM接收和FM发射两个功能。本章分为如下几个部分:

40.1 RDA5820简介

40.2 硬件设计

40.3 软件设计

40.4 下载验证

40.1 RDA5820简介

       RDA5820是北京锐迪科推出的一款集成度非常高的立体声FM收发芯片。该芯片具有以下特点:

l  FM发射和接收一体

l  支持65Mhz~115Mhz的全球FM接收频段,收发天线共用。

l  支持IIC/SPI接口

l  支持32.768K晶振

l  数字音量及自动AGC控制

l  支持立体声/单声道切换,带软件静音功能

l  支持I2S接口(输入/输出)

l  内置LDO,使用电压范围宽(2.7~5.5V)

l  高功率32欧负载音频输出、可直接驱动耳机

l  集成度高、功耗低、尺寸小(4mm*4mm QFN封装)、应用简单

RDA5820应用范围很宽,在很多手机、MP3、MP4甚至平板电脑上都有应用。RDA5820的引脚图如图40.1.1所示:

 


图40.1.1 RDA5820引脚图

       RDA5820支持2种通信模式,SPI和IIC,在战舰STM32开发板上面,使用的是RDA5820的IIC模式。通过将图40.1.1的MODE脚接GND,RDA5820即进入IIC模式,此时SCLK充当IIC的SCL,SDIO充当IIC的SDA。RDA5820的IIC地址为0X11(不包含最低位),对应读为0X23,写为0X20。

       模式设置

RDA5820的模式设置通过40H(寄存器地址0X40)寄存器的CHIP_FUNC[3:0]位来设置,RDA5820可以工作在RX模式、TX模式、PA模式和DAC模式等,本章我们只介绍RX模式和TX模式。

通过设置CHIP_FUNC[3:0]=0即可定义当前工作模式为FM接收模式。在该模式下,我们即可实现FM收音机功能。

通过设置CHIP_FUNC[3:0]=1即可定义当前工作模式为FM发送模式。在该模式下,我们即可实现FM电台的功能。

频点设置

软件可以通过配置03H(寄存器地址0X30)寄存器来选择FM频道。搜台(Seek)的步进长度(100KHz、200KHz或50KHz)由SPACE[1:0] 来选择,频道由CHAN[9:0]来选择,频率范围(76MHz~91MHz、87MHz~108MHz或76MHz~108MHz 或用户自定义65MHz~115MHz 范围内频段)由BAND[1:0]来选择。自定义的频段由寄存器53H(chan_bottom)和54H(chan_top)来设置,单位为100KHz,即定义65MHz~76MHz,可设置BAND[1:0]=3(用户自定义频段),并且设置chan_bottom=0x028A,chan_top=0x02f8。

频点计算方法如下(该公式也适用于FM频点的读取):

FMfreq=SPACE*CHAN+FMBTM

       其中FMfreq即我们需要的FM频率(Mhz),SPACE为我们设置的步进长度(Khz),CHAN是我们设置的频点值,FMBTM则是我们在BAND里面所选频段的最低频率,当BAND=0的实惠,FMBTM=87Mhz;BAND=1的时候,FMBTM=76Mhz;BAND=2的时候,FMBTM=CHAN_BOTTOM*0.1Mhz。

       例如,我们要设置FM频率为93.0Mhz,假设BAND=0,SPACE=100Khz。那么我们只需要设置CHAN=60即可。

       频点设置部分,FM接收和FM发送是共用的,对两者都适用。

       关于RDA5820,我们就介绍到这,详细的使用说明,请大家参考《RDA5820编程指南》和RDA5820的数据手册。

 

40.2 硬件设计

本章实验功能简介:开机默认设置FM为接收模式,设置接收频率为93.6Mhz,我们插上耳机就能听到该频率的电台。通过KEY0和KEY2,我们可以调节FM频率(发送/接收),在FM接收模式下,KEY1用于自动搜台,在FM发送模式下,KEY1无效。通过WK_UP按键切换RDA5820的工作模式(FM发送/FM接收)。在FM发送模式下,我们可以通过在多功能端口(P3)的AIN排针上面输入音频信号,就可以在收音机里面听到该音频。同时用DS0提示程序正在运行。

所要用到的硬件资源如下:

1)  指示灯DS0

2)  KEY0、KEY1、KEY2和WK_UP等四个按键

3)  TFTLCD模块

4)  串口(USMART使用)

5)  RDA5820

6)  74HC4052

7)  TDA1308

前面4个我们就不介绍了,RDA5820与STM32的连接电路如图40.2.1所示:

 


图40.2.1 RDA5820与STM32的连接图

       这里RDA5820和之前介绍的24C02共用IIC总线,他们都是接在STM32的PB10和PB11两个脚上,上图中OUTL和OUTR接在RDA5820的LIN和RIN,OUTR和OUTL是来自音频选择器(74HC4052)的输出端,作为FM发送时的音源输入。另外RADIO_L和RADIO_R则是FM收音的音频输出,他们接在音频选择器的一对输入上面。

       音频选择器(74HC4052)和耳机驱动(TDA1308)的连接电路如图40.2.2所示:

 


图40.2.2 音频选择器与耳机驱动连接电路图

       战舰STM32开发板选择74HC4052来做音频选择器,74HC4052是一个4-2模拟选择器,可以实现4组立体声音源的切换,战舰STM32开发板有3路音源输出:FM收音机、MP3(VS1053)输出、PWM DAC输出,我们通过74HC4052实现这3路音源的切换。图中ASEL_A和ASEL_B是其控制信号,分别连接在STM32的PD7和PB7上,用于控制音源切换。OUTL和OUTR是74HC4052的输出端,被分为两路,一路接到FM发射的音频输入端,另外一路接到耳机驱动的输入端(A_OUTR和A_OUTL)。

       TDA1308是一款性能十分优异(秒杀TDA2822、TDA7050等)的AB类数字音频专用耳放IC,战舰STM32搭载这颗耳机驱动,其MP3播放的音质可以打败市面上很多中低端MP3播放器。A_OUTR和A_OUTL是来自74HC4052的输出信号,作为TDA1308的输入端,经过TDA1308驱动后,输出到耳机插座。

       硬件上,我们不需要做其他变动,只需找个耳机插到开发板的耳机插口,将开发板板载的天线拉出来,然后下载本章的实验例程,就可以听广播了。

 

40.3 软件设计

打开上一章的工程,首先在HARDWARE文件夹下新建RDA5820和AUDIOSEL两个文件夹。在RDA5820文件夹下新建rda5820.c和rda5820.h两个文件。然后,在AUDIOSEL文件夹里面新建audiosel.c和audiosel.h两个文件。并将这个两个文件夹加入头文件包含路径。

打rda5820.c,输入如下代码:

#include "rda5820.h"

#include "delay.h"

//初始化

//0,初始化成功;

//其他,初始化失败.

u8 RDA5820_Init(void)

{

       u16 id;

       IIC_Init();                                                //初始化IIC口     

       id=RDA5820_RD_Reg(RDA5820_R00);     //读取ID =0X5805

       if(id==0X5805)                                        //读取ID正确

       {

             RDA5820_WR_Reg(RDA5820_R02,0x0002);     //软复位

              delay_ms(50);

             RDA5820_WR_Reg(RDA5820_R02,0xC001);    //立体声,上电

              delay_ms(600);                                                //等待时钟稳定

             RDA5820_WR_Reg(RDA5820_R05,0X884F);   

//搜索强度8,LNAN,1.8mA,VOL最大

            RDA5820_WR_Reg(0X07,0X7800);          

             RDA5820_WR_Reg(0X13,0X0008);          

             RDA5820_WR_Reg(0X15,0x1420);            //VCO设置  0x17A0/0x1420

             RDA5820_WR_Reg(0X16,0XC000);         

             RDA5820_WR_Reg(0X1C,0X3126);         

             RDA5820_WR_Reg(0X22,0X9C24);          //fm_true

             RDA5820_WR_Reg(0X47,0XF660) ;          //tx rds

      }else return 1;//初始化失败

       return 0;

}

//写RDA5820寄存器                                                                    

void RDA5820_WR_Reg(u8 addr,u16 val)

{

    IIC_Start();                    

       IIC_Send_Byte(RDA5820_WRITE); IIC_Wait_Ack();       //发送写命令       

    IIC_Send_Byte(addr); IIC_Wait_Ack();                    //发送地址

       IIC_Send_Byte(val>>8); IIC_Wait_Ack();             //发送高字节

      IIC_Send_Byte(val&0XFF); IIC_Wait_Ack();         //发送低字节

    IIC_Stop();                                                             //产生一个停止条件     

}

//读RDA5820寄存器  

u16 RDA5820_RD_Reg(u8 addr)

{

       u16 res;

    IIC_Start();                    

       IIC_Send_Byte(RDA5820_WRITE); IIC_Wait_Ack();       //发送写命令       

    IIC_Send_Byte(addr); IIC_Wait_Ack();                  //发送地址                                   

    IIC_Start();                    

       IIC_Send_Byte(RDA5820_READ); IIC_Wait_Ack(); //发送读命令

      res=IIC_Read_Byte(1);                          //读高字节,发送ACK    

      res<<=8;

      res|=IIC_Read_Byte(0);                   //读低字节,发送NACK       

      IIC_Stop();                                        //产生一个停止条件

       return res;                                          //返回读到的数据

}

//设置RDA5820为RX模式

void RDA5820_RX_Mode(void)

{

       u16 temp;

       temp=RDA5820_RD_Reg(0X40);        //读取0X40的内容

       temp&=0xfff0;                                  //RX 模式  

       RDA5820_WR_Reg(0X40,temp) ;              //FM RX模式

}                  

//设置RDA5820为TX模式

void RDA5820_TX_Mode(void)

{

       u16 temp;

       temp=RDA5820_RD_Reg(0X40);        //读取0X40的内容

       temp&=0xfff0;

       temp|=0x0001;                                //TX 模式

       RDA5820_WR_Reg(0X40,temp) ;              //FM TM 模式

}

//得到信号强度

//返回值范围:0~127

u8 RDA5820_Rssi_Get(void)

{

       u16 temp;

       temp=RDA5820_RD_Reg(0X0B);       //读取0X0B的内容

       return temp>>9;                     //返回信号强度

}

//设置音量ok

//vol:0~15;

void RDA5820_Vol_Set(u8 vol)

{

       u16 temp;

       temp=RDA5820_RD_Reg(0X05);        //读取0X05的内容

       temp&=0XFFF0;

       temp|=vol&0X0F;                                    

       RDA5820_WR_Reg(0X05,temp) ;              //设置音量    

}

//静音设置

//mute:0,不静音;1,静音

void RDA5820_Mute_Set(u8 mute)

{

       u16 temp;

       temp=RDA5820_RD_Reg(0X02);        //读取0X02的内容

       if(mute)temp|=1<<14;

       else temp&=~(1<<14);                                 

       RDA5820_WR_Reg(0X02,temp) ;              //设置MUTE 

}

//设置灵敏度

//rssi:0~127;

void RDA5820_Rssi_Set(u8 rssi)

{

       u16 temp;

       temp=RDA5820_RD_Reg(0X05);        //读取0X05的内容

       temp&=0X80FF;

       temp|=(u16)rssi<<8;                                        

       RDA5820_WR_Reg(0X05,temp) ;              //设置RSSI   

}

//设置TX发送功率

//gain:0~63

void RDA5820_TxPAG_Set(u8 gain)

{

       u16 temp;

       temp=RDA5820_RD_Reg(0X42);        //读取0X42的内容

       temp&=0XFFC0;

       temp|=gain;                                     //GAIN

       RDA5820_WR_Reg(0X42,temp) ;              //设置PA的功率

}

//设置TX 输入信号增益

//gain:0~7

void RDA5820_TxPGA_Set(u8 gain)

{

       u16 temp;

       temp=RDA5820_RD_Reg(0X42);        //读取0X42的内容

       temp&=0XF8FF;

       temp|=gain<<8;                               //GAIN

       RDA5820_WR_Reg(0X42,temp) ;              //设置PGA

}

//设置RDA5820的工作频段

//band:0,87~108Mhz;1,76~91Mhz;2,76~108Mhz;3,用户自定义(53H~54H)

void RDA5820_Band_Set(u8 band)

{

       u16 temp;

       temp=RDA5820_RD_Reg(0X03);        //读取0X03的内容

       temp&=0XFFF3;

       temp|=band<<2;                       

       RDA5820_WR_Reg(0X03,temp) ;              //设置BAND

}

//设置RDA5820的步进频率

//band:0,100Khz;1,200Khz;3,50Khz;3,保留

void RDA5820_Space_Set(u8 spc)

{

       u16 temp;

       temp=RDA5820_RD_Reg(0X03);        //读取0X03的内容

       temp&=0XFFFC;

       temp|=spc;                        

       RDA5820_WR_Reg(0X03,temp) ;              //设置BAND

}

 非常抱歉,由于编辑器篇幅所限,剩下内容,请看附件。

PARTNER CONTENT

文章评论2条评论)

登录后参与讨论

MrDouglas 2024-4-25 16:04

咋没有图片

MrDouglas 2024-4-25 15:57

附件在哪,家人们

用户377235 2013-4-3 09:46

学习了,很厉害

用户375625 2010-12-9 14:17

不错,学习了!
相关推荐阅读
正点原子 2013-05-17 23:47
【连载】【ALIENTEK 战舰STM32开发板】STM32开发指南--第六十一章 战舰STM32开发板综合实验(标准例程终结篇)
   第六十一章 战舰STM32开发板综合实验        前面已经给大家讲了55个实例了,本章将设计一个综合实例,作为本指南的最后一个实验 ,该实验向大家展示了STM...
正点原子 2013-05-03 23:02
【连载】【ALIENTEK 战舰STM32开发板】STM32开发指南--第六十章 UCOSII实验3-消息队列、信号量集和软件定时器
   第六十章 UCOSII实验3-消息队列、信号量集和软件定时器   上一章,我们学习了UCOSII的信号量和邮箱的使用,本章,我们将学习消息队列、信号量集和软件定时器...
正点原子 2013-05-03 20:42
【连载】【ALIENTEK 战舰STM32开发板】STM32开发指南--第五十七章 ENC28J60网络实验
第五十七章 ENC28J60网络实验   本章,我们将向大家介绍ALIENTEK ENC28J60网络模块及其使用。本章,我们将使用ALIENTEK ENC28J60网络模块...
正点原子 2013-05-01 23:00
【连载】【ALIENTEK 战舰STM32开发板】STM32开发指南--第五十九章 UCOSII实验2-信号量和邮箱
第五十九章 UCOSII实验2-信号量和邮箱      上一章,我们学习了如何使用UCOSII,学习了UCOSII的任务调度,但是并没有用到任务间的同步与通信,本章我们将学习两个最基本的...
正点原子 2013-04-30 10:55
【连载】【ALIENTEK 战舰STM32开发板】STM32开发指南--第五十八章 UCOSII实验1-任务调度
  第五十八章 UCOSII实验1-任务调度      前面我们所有的例程都是跑的裸机程序(裸奔),从本章开始,我们将分3个章节向大家介绍UCOSII(实时多任务操作系...
正点原子 2013-04-26 23:16
【连载】【ALIENTEK 战舰STM32开发板】STM32开发指南--第五十七章 ENC28J60网络实验
 第五十七章 ENC28J60网络实验  本章,我们将向大家介绍ALIENTEK ENC28J60网络模块及其使用。本章,我们将使用ALIENTEK ENC28J60网络模块和uIP 1...
EE直播间
更多
我要评论
2
17
关闭 站长推荐上一条 /1 下一条