程序设计目标及程序运行效果说明
程序设计目标:通过本案例理解简单收音机的原理,尤其是理解收音机芯片RDA5807P的相关功能与工作原理,通过与RDA5807P芯片通信里然后设置相关寄存器的值可以收听一定频率的广播电台并且能够调节音量。
程序运行效果说明:程序初始化时是收听的是频率值为97.5的电台,将耳机插入耳机插孔之后可以在耳机中听到电台的声音。按下导航按键的左键往低频率方向调电台,按下导航按键的右键往高频率的方向调电台(能搜索的电台最大频率为,最小频率为108,最小为87.5,调频高于108时则为87.5,低于87.5时则为108),每次电台的频率加0.1或减0.1,按下按键2可以调大电台音量,按下按键1调小电台音量,第1号和第2号数码管显示当前电台音量,地6,7,8,号数码管显示当前电台频率。
程序相关电路及工作原理说明
1.使用到的引脚示意图
2.RDA5807P芯片原理
2.1 RDA5807P芯片工作模式
RDA5807P芯片提供两种不同的软件控制模式:RDA5807P Mode和TEA5767 Mode。
在TEA5767 Mode下控制接口为I2C;在RDA5807P Mode下控制接口为I2C 和 SPI,在PIN7:MODE上设置高低电平来选择。MODE:0为I2C;MODE:1为SPI。当控制接口为I2C时用CHIP ID来区分工作模式:
TEA5767 MODE CHIPID = 1100000B;
RDA5807P MODECHIP ID = 0010000B.
代码如下:
#include "FM.h"
/*初始化电台函数
*将电台初始化收听频率设置为87500
*/
void Init_Radio()
{
Get_CHAN();
Get_Frequency();
IIC_Radio_WriteData();
Delay(50);
}
/************************************RDA5807P芯片的IIC操作函数***************************************/
//IIC通信开始
void IIC_Radio_Start()
{
FM_DATA=UP;
FM_CLOCK=UP;
FM_DATA=DOWN;
Delayus(10);
FM_CLOCK=DOWN;
Delayus(10);
}
//IIC通信结束
void IIC_Radio_Stop()
{
FM_DATA=DOWN;
FM_CLOCK=UP;
Delayus(10);
FM_DATA=UP;
Delayus(10);
}
//主机应答信号
void IIC_Radio_MACK()
{
FM_DATA=DOWN;
Delayus(10);
FM_CLOCK=UP;
Delayus(10);
FM_CLOCK=DOWN;
Delayus(10);
FM_DATA=UP;
}
//从机应答信号
void IIC_Radio_ACK()
{
unsigned char i=0;
FM_CLOCK=UP;
while((FM_DATA==1)&&(i<250)) i++;
FM_CLOCK=DOWN;
Delayus(10);
}
//写入一字节数据
void IIC_Radio_WriteByte(unsigned char Data)
{
unsigned char i;
for(i=0;i!=8;i++)
{
FM_CLOCK=DOWN;
Delayus(10);
FM_DATA=(bit) (Data&0x80);
Data=Data<<1;
Delayus(10);
FM_CLOCK=UP;
Delayus(10);
}
FM_CLOCK=DOWN;
Delayus(10);
FM_CLOCK=UP;
Delayus(10);
}
//往从机一次写入八字节数据
void IIC_Radio_WriteData()
{
unsigned char i;
IIC_Radio_Start(); //IIC开始
IIC_Radio_WriteByte(0x20); //主机向IIC总线上写入从机的地址信息,与从机建立通信
IIC_Radio_ACK(); //从机收到后回应ACK
for(i=0;i<8;i++) //连续写入八字节数据
{
IIC_Radio_WriteByte(Radio_Write_Data[i]);
IIC_Radio_MACK();
}
IIC_Radio_Stop(); //IIC停止
}
//获取CHAN值
void Get_CHAN()
{
chan = Radio_Write_Data[2];
chan = chan*4 + Radio_Write_Data[3]/64;
}
//获取电台频率值,即CHAN转频率
void Get_Frequency()
{
frequency = 100*chan + 87000;
}
//将电台频率转化为PLL值的函数
void FrequencyToChan(void) //频率转CHAN
{
chan = (frequency-87000)/100;
}
//手动搜台函数,参数flag决定是向上还是向下搜台,每次只能调频100KHZ
void Manual_Search(unsigned char flag)
{
if( flag==1 ) //flag==1,表示向上搜台,并且保证电台频率不能超出 87500~108000
{
frequency += 100;
if( frequency>MAX_Frequency )
frequency = MIN_Frequency;
}
else if( flag==-1 ) //flag==1,表示向下搜台
{
frequency -= 100;
if( frequency<MIN_Frequency )
frequency = MAX_Frequency;
}
FrequencyToChan(); //将频率转化为CHAN
Radio_Write_Data[2] = chan/4;
Radio_Write_Data[3] = ((chan%4)<<6)|0x10;
IIC_Radio_WriteData(); //然后将CHAN写入收音机芯片的相关寄存器实现手动调频的功能
}
//设置收音机音量,参数flag决定是增大还是减小音量
void SetVolume(unsigned char flag)
{
volume = Radio_Write_Data[7] & 0x0f;
if( flag==1 ) //flag==1增大音量
{
if(volume==15)
volume=0;
else
volume++;
}
else
{
if( volume==0 ) //flag==0减少音量
volume=15;
else
volume--;
}
Radio_Write_Data[7] = (Radio_Write_Data[7]&0xf0) | (volume&0x0f);
IIC_Radio_WriteData(); //将改变后的音量值写入收音机芯片的相关寄存器从而达到调节收音音量的效果
}
//将电台频率和音量值显示到相应的数码管
void Frequency_Display()
{
unsigned long fre;
fre = frequency/100;
volume = Radio_Write_Data[7] & 0x0f;
//音量显示
if( volume<10 )
Display_LED_Num( volume,1,0);
else
{
Display_LED_Num( volume/10,1,0);
Display_LED_Num( volume%10,2,0);
}
//频率显示
if(fre/1000)
{
Display_LED_Num(fre/1000,5,0);
Display_LED_Num(fre%1000/100,6,0);
Display_LED_Num(fre%1000%100/10,7,1);
Display_LED_Num(fre%1000%100%10,8,0);
}
else
{
Display_LED_Num(fre/100,6,0);
Display_LED_Num(fre%100/10,7,1);
Display_LED_Num(fre%100%10,8,0);
}
}