chan=(freq-fbtm)/spc; //得到CHAN应该写入的值
chan&=0X3FF; //取低10位
temp|=chan<<6;
temp|=1<<4; //TONE ENABLE
RDA5820_WR_Reg(0X03,temp) ; //设置频率
delay_ms(20); //等待20ms
while((RDA5820_RD_Reg(0X0B)&(1<<7))==0);//等待FM_READY
}
//得到当前频率
//返回值:频率值(单位10Khz)
u16 RDA5820_Freq_Get(void)
{
u16 temp;
u8 spc=0,band=0;
u16 fbtm,chan;
temp=RDA5820_RD_Reg(0X03); //读取0X03的内容
chan=temp>>6;
band=(temp>>2)&0x03; //得到频带
spc=temp&0x03; //得到分辨率
if(spc==0)spc=10;
else if(spc==1)spc=20;
else spc=5;
if(band==0)fbtm=8700;
else if(band==1||band==2)fbtm=7600;
else
{
fbtm=RDA5820_RD_Reg(0X53);//得到bottom频率
fbtm*=10;
}
temp=fbtm+chan*spc;
return temp;//返回频率值
}
本部分代码我们就不细说了,都是一些寄存器配置,比较简单。保存rda5820.c文件,并加入到HARDWARE组下,然后打开rda5820.h,在该文件里面输入如下代码:
#ifndef __RDA5820_H
#define __RDA5820_H
#include "sys.h"
#include "myiic.h"
#define RDA5820_R00 0X00 //读出16个位的ID =0X5820
……此处省略部分寄存器定义
#define RDA5820_R64 0X64 //RDS_RXMOD[4:3](FIFO模式[10]或者寄存器模式[11]) #define RDA5820_READ 0X23 //读RDA5820
#define RDA5820_WRITE 0X22 //写RDA5820
u8 RDA5820_Init(void); //初始化
void RDA5820_WR_Reg(u8 addr,u16 val); //写RDA5820寄存器
u16 RDA5820_RD_Reg(u8 addr); //读RDA5820寄存器
void RDA5820_RX_Mode(void); //设置RDA5820为RX模式
void RDA5820_TX_Mode(void); //设置RDA5820为TX模式
u8 RDA5820_Rssi_Get(void);
void RDA5820_Mute_Set(u8 mute);
void RDA5820_Rssi_Set(u8 rssi);
void RDA5820_Vol_Set(u8 vol);
void RDA5820_TxPAG_Set(u8 gain);
void RDA5820_TxPGA_Set(u8 gain);
void RDA5820_Band_Set(u8 band);
void RDA5820_Space_Set(u8 spc);
void RDA5820_Freq_Set(u16 freq);
u16 RDA5820_Freq_Get(void);
#endif
此部分代码省略了部分寄存器的定义,大家可以在战舰STM32开发板的光盘找到本实验的源码查看。保存此部分代码,然后打开audiosel.c文件,在该文件里面输入如下代码:
#include "audiosel.h"
//声音初始化
void Audiosel_Init(void)
{
RCC->APB2ENR|=1<<3; //使能PORTB时钟
RCC->APB2ENR|=1<<5; //使能PORTD时钟
GPIOB->CRL&=0X0FFFFFFF;
GPIOB->CRL|=0X30000000;//PB.7 推挽输出
GPIOD->CRL&=0X0FFFFFFF;
GPIOD->CRL|=0X30000000;//PD.7 推挽输出
}
//设置4052的选择通道
//声音通道选择
//0 //MP3通道
//1 //收音机通道
//2 //PWM音频通道
//3 //无声
void Audiosel_Set(u8 ch)
{
AUDIO_SELA=ch&0X01;
AUDIO_SELB=(ch>>1)&0X01;
}
此部分代码很简单,用来控制74HC4052,保存audiosel.c文件,并将其加入到HARDWARE组下。然后,打开audiosel.h,并输入如下代码:
#ifndef __AUDIOSEL_H
#define __AUDIOSEL_H
#include "sys.h"
//74HC4052控制设置端口
#define AUDIO_SELB PBout(7)
#define AUDIO_SELA PDout(7)
//声音通道选择
#define AUDIO_MP3 0 //MP3通道
#define AUDIO_RADIO 1 //收音机通道
#define AUDIO_PWM 2 //PWM音频通道
#define AUDIO_NONE 3 //无声
void Audiosel_Init(void); //初始化函数
void Audiosel_Set(u8 ch); //设置函数
#endif
保存audiosel.h,最后,打开test.c文件,修改代码如下:
void RDA5820_Show_Msg(void)
{
u8 rssi;
u16 freq;
freq=RDA5820_Freq_Get(); //读取设置到的频率值
LCD_ShowNum(100,210,freq/100,3,16); //显示频率整数部分
LCD_ShowNum(132,210,(freq%100)/10,1,16); //显示频率小数部分
rssi=RDA5820_Rssi_Get(); //得到信号强度
LCD_ShowNum(100,230,rssi,2,16); //显示信号强度
}
int main(void)
{
u8 key,rssi;
u16 freqset=0;
u8 i=0;
u8 mode=0; //接收模式
Stm32_Clock_Init(9); //系统时钟设置
uart_init(72,9600); //串口初始化为9600
delay_init(72); //延时初始化
LED_Init(); //初始化与LED连接的硬件接口
LCD_Init(); ///初始化LCD
usmart_dev.init(72); //初始化USMART
KEY_Init(); //按键初始化
Audiosel_Init();
Audiosel_Set(AUDIO_RADIO);
RDA5820_Init();
POINT_COLOR=RED;//设置字体为红色
LCD_ShowString(60,50,200,16,16,"WarShip STM32");
LCD_ShowString(60,70,200,16,16,"RDA5820 TEST");
LCD_ShowString(60,90,200,16,16,"ATOM@ALIENTEK");
LCD_ShowString(60,110,200,16,16,"2012/9/14");
LCD_ShowString(60,130,200,16,16,"KEY0:Freq+ KEY2:Freq-");
LCD_ShowString(60,150,200,16,16,"KEY1:Auto Search(RX)");
LCD_ShowString(60,170,200,16,16,"KEY_UP:Mode Set");
POINT_COLOR=BLUE;
//显示提示信息
POINT_COLOR=BLUE;//设置字体为蓝色
LCD_ShowString(60,190,200,16,16,"Mode:FM RX");
LCD_ShowString(60,210,200,16,16,"Freq: 93.6Mhz");
LCD_ShowString(60,230,200,16,16,"Rssi:");
RDA5820_Band_Set(0); //设置频段为87~108Mhz
RDA5820_Space_Set(0); //设置步进为100Khz
RDA5820_TxPGA_Set(3); //信号增益设置为3
RDA5820_TxPAG_Set(63); //发射功率为最大.
RDA5820_RX_Mode(); //设置为接收模式
freqset=9360; //默认为93.6Mhz
RDA5820_Freq_Set(freqset); //设置频率
while(1)
{
key=KEY_Scan(0);//不支持连按
switch(key)
{
case 0: break;//无任何按键按下
case KEY_UP://切换模式
mode=!mode;
if(mode)
{
Audiosel_Set(AUDIO_PWM); //设置到PWM 音频通道
RDA5820_TX_Mode(); //发送模式
RDA5820_Freq_Set(freqset); //设置频率
LCD_ShowString(100,190,200,16,16,"FM TX");
}else
{
Audiosel_Set(AUDIO_RADIO); //设置到收音机声道
RDA5820_RX_Mode(); //接收模式
RDA5820_Freq_Set(freqset); //设置频率
LCD_ShowString(100,190,200,16,16,"FM RX");
}
break;
case KEY_DOWN://自动搜索下一个电台.
if(mode==0)//仅在接收模式有效
{
while(1)
{
if(freqset<10800)freqset+=10; //频率增加100Khz
else freqset=8700; //回到起点
RDA5820_Freq_Set(freqset); //设置频率
delay_ms(10); //等待调频信号稳定
if(RDA5820_RD_Reg(0X0B)&(1<<8))//是一个有效电台.
{
RDA5820_Show_Msg();break; //显示信息
}
RDA5820_Show_Msg(); //显示信息
key=KEY_Scan(0);//不支持连按
if(key)break; //在搜台期间有按键按下,则跳出搜台.
}
}
break;
case KEY_LEFT://频率减
if(freqset>8700)freqset-=10; //频率减少100Khz
else freqset=10800; //越界处理
RDA5820_Freq_Set(freqset); //设置频率
RDA5820_Show_Msg();//显示信息
break;
case KEY_RIGHT://频率增
if(freqset<10800)freqset+=10; //频率增加100Khz
else freqset=8700; //越界处理
RDA5820_Freq_Set(freqset); //设置频率
RDA5820_Show_Msg();//显示信息
break;
}
i++;
delay_ms(10);
if(i==200)//每两秒左右检测一次信号强度等信息.
{
i=0;
rssi=RDA5820_Rssi_Get(); //得到信号强度
LCD_ShowNum(100,230,rssi,2,16); //显示信号强度
}
if((i%20)==0)LED0=!LED0;//DS0闪烁,提示程序运行
}
}
此部分代码除了mian函数,还有一个RDA5820_Show_Msg函数,该函数用于显示当前FM频率和信号强度等信息。main函数我面就不多介绍了。本章,我面可以利用USMART来设置RDA5820的各项参数,方便大家快速掌握。在usmart_nametab里面,我面加入如下五个函数:
(void*)RDA5820_Rssi_Set,"void RDA5820_Rssi_Set(u8 rssi)",
(void*)RDA5820_Band_Set,"void RDA5820_Band_Set(u8 band)",
(void*)RDA5820_Freq_Set,"void RDA5820_Freq_Set(u16 freq)",
(void*)RDA5820_Vol_Set,"void RDA5820_Vol_Set(u8 vol)",
(void*)RDA5820_TxPGA_Set,"void RDA5820_TxPGA_Set(u8 gain)",
这样,我面就可以在串口调用这些函数,从而修改RDA5820的配置。至此,我们的软件设计部分就结束了。
40.4 下载验证 在代码编译成功之后,我们通过下载代码到ALIENTEK战舰STM32开发板上,得到如图40.4.1所示界面:
图40.4.1 程序运行效果图
此时,我们就可以在耳机上面听到广播了(注意,将开发板自带的天线拉出来,可以提高接收能力),通过KEY0和KEY1,调节频率,也可以通过按KEY1自动搜索下一个电台(PS:如果收不到台,说明你住的地方信号不好,跑到窗户边或者室外,一般就可以收到电台了)。
通过WK_UP按键,可以切换工作模式,例如:切换到FM TX模式,就可以通过单独的收音机(或者另外一块战舰STM32开发板)接收到开发板发出的FM信号了,此时在多功能接口P3的AIN端输入音频信号,就可以在收音机端接收这个音频信号了。
本章还可以通过USMART设置RDA5820的相关参数,感兴趣的朋友可以动手试试。
[ 本帖最后由 正点原子 于 2013-3-30 23:06 编辑 ]