RDA5807m+IIC收音机51单片机C程序.docx
《RDA5807m+IIC收音机51单片机C程序.docx》由会员分享,可在线阅读,更多相关《RDA5807m+IIC收音机51单片机C程序.docx(20页珍藏版)》请在冰豆网上搜索。
![RDA5807m+IIC收音机51单片机C程序.docx](https://file1.bdocx.com/fileroot1/2022-12/12/e5ccaa53-5932-4a9f-9457-c032058fe46c/e5ccaa53-5932-4a9f-9457-c032058fe46c1.gif)
RDA5807m+IIC收音机51单片机C程序
RDA5807m驱动程序+IIC程序
/****************************************************************************************
**介绍:
RD5807M收音机程序供电3.3v主控使用51单片机显示使用LCD1602
**作者:
胖子
**时间:
2016-1-5
**地点:
桂林电子科技大学
*****************************************************************************************/
#include
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
#defineulintunsignedlongint
#definelintlongint
ucharcodexian[4][4]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
ucharcodehang[]={0xfe,0xfd,0xfb,0xf7};//矩阵键盘扫描使用
//RDA的寄存器地址
#defineRDA_R000X00//读出16个位的ID=0X5800
#defineRDA_R020X02//DHIZ[15],DMUTE[14]静音,MONO[13]声道,BASS[12]重低音,SEEKUP[9],SEEK[8],SKMODE[7],CLK_MODE[6:
4]时钟源选择,SOFTRESET[1]软复位,ENABLE[0]电源使能
#defineRDA_R030X03//CHAN[15:
6],TUNE[4],BAND[3:
2],SPACE[1:
0]设置频率带宽步长
#defineRDA_R040X04//STCIEN[14],DE[11],I2Senable[6],
#defineRDA_R050X05//INT_MODE[15],SEEKTH[14:
8](设定自动搜索信号强度阀值),LNA_PORT_SEL[7:
6]=0b10,LNA_ICSEL_BIT[5:
4],VOLUME[3:
0]音量;
#defineRDA_R0A0X0A//STC[14]seekcompleteSF[13]seekfailreadchan[9:
0]当前频道
#defineRDA_R0B0X0B//RSSI[15:
9],FMTRUE[8]当前频道是一个节目台
#defineRDA_READ0X23//读RDA5807
#defineRDA_WRITE0X22//写RDA5807
//IO操作函数
sbitSDA=P2^1;
sbitSCL=P2^0;
sbitRW=P1^1;
sbitRS=P1^0;
sbitEN=P2^5;
ucharcodea[]="FM:
.";
ucharcodeb[]="Vol:
RSSI:
";
ucharcodeshu[]="0123456789";
ucharnum;
voiddelayms(uintx)//延迟程序
{
uinti,j;
for(i=x;i>0;i--)
for(j=113;j>0;j--);
}
/***********************************************矩阵键盘程序********************************************************************/
ucharScanKey()//矩阵键盘扫描返回值是当前按键数值如没按下则返回值为零
{
uintx,y;
for(x=0;x<4;x++)
{
uchartemp,gaowei;
P3=hang[x];//分行置零
temp=P3&0xf0;
if(temp!
=0xf0)
{
delayms(10);
if(temp!
=0xf0)
{
gaowei=P3/16;//判断是第几列的按键按下,将数据装入高四位
switch(gaowei)
{
case0xe:
y=0;break;
case0xd:
y=1;break;
case0xb:
y=2;break;
case0x7:
y=3;break;
}
while(temp!
=0xf0)
{
temp=P3&0xf0;
}
returnxian[x][y];
}
}
}
return0;
}
/*******************************************************LCD1602程序************************************************************************/
voidwrite_com(unsignedcharcom)
{
RS=0;
P0=com;
delayms(5);
EN=1;
delayms(5);
EN=0;
}
voidwrite_data(unsignedchardate)
{
RS=1;
P0=date;
delayms(5);
EN=1;
delayms(5);
EN=0;
}
voidinit_1602()
{
P0=0xc0;
RW=0;
EN=0;
write_com(0x38);//éè?
?
16*2?
?
ê?
£?
5*7μ?
?
ó£?
8?
?
êy?
Y?
ú
write_com(0x0c);//éèa?
?
ê?
£?
2ê?
1a±ê
write_com(0x06);//D′ò×?
·?
oóμ?
?
·ó1
write_com(0x01);//?
?
êá?
£?
êy?
Yá?
}
voidDisplayFrq(floatFrq)//显示频率
{
uintF;
F=Frq*10;
write_com(0x80+3);
write_data(shu[F/1000]);
delayms
(1);
write_data(shu[F/100%10]);
delayms
(1);
write_data(shu[F/10%10]);
delayms
(1);
write_com(0x80+7);
write_data(shu[F%10]);
delayms
(1);
}
voidDisplayVol(uintVol)//显示音量
{
write_com(0x80+0x40+4);
write_data(shu[Vol/10]);
delayms
(1);
write_data(shu[Vol%10]);
delayms
(1);
}
voidDisplay_mute()//显示静音
{
write_com(0x80+0x40+4);
write_data('x');
delayms
(1);
write_data('x');
delayms
(1);
}
voidDisplay_RSSI(uintRSSI)//显示信号强度
{
write_com(0x80+0x40+14);
write_data(shu[RSSI/10]);
delayms
(1);
write_data(shu[RSSI%10]);
delayms
(1);
}
/*----------------------------------------IIC通信程序---------------------------------------------------*/
voidIIC_delayms()//用于IIC延时
{
_nop_();_nop_();_nop_();_nop_();
}
voidOpenIIC()//IIC启动信号
{
SDA=1;
SCL=1;
IIC_delayms();
SDA=0;
IIC_delayms();
SCL=0;
}
voidCloseIIC()//IIC停止信号
{
SCL=0;
SDA=0;
IIC_delayms();
SCL=1;
SDA=1;
IIC_delayms();
}
ucharIIC_Wait_Ack(void)//IIC发送字节后等待从机发送响应信
{
ucharucErrTime=0;
SDA=1;
IIC_delayms();
SCL=1;
IIC_delayms();
while(SDA==1)
{
ucErrTime++;
if(ucErrTime>250)
{
CloseIIC();
return1;
}
}
SCL=0;
return0;
}
voidIIC_Ack(void)//发送应答信号
{
SCL=0;
SDA=0;//0±íê?
ó|′e
IIC_delayms();
SCL=1;
IIC_delayms();
SCL=0;
}
voidIIC_NAck(void)//IIC非应答信号
{
SCL=0;
SDA=1;
IIC_delayms();
SCL=1;
IIC_delayms();
SCL=0;
}
voidIICsendByte(uchartxd)//IIC·写一个字节
{
uchart;
SCL=0;
for(t=0;t<8;t++)
{
if(((txd&0x80)>>7)==1)
SDA=1;
else
SDA=0;
txd<<=1;
IIC_delayms();
SCL=1;
IIC_delayms();
SCL=0;
IIC_delayms();
}
}
ucharIICReadByte(unsignedcharack)//IIC读一个字节
{
unsignedchari,receive=0;
SDA=1;//51单片机讲引脚置高可设为输入引脚
for(i=0;i<8;i++)
{
SCL=0;
IIC_delayms();
SCL=1;
receive<<=1;
if(SDA==1)receive++;
IIC_delayms();
}
if(!
ack)
IIC_NAck();
else
IIC_Ack();
returnreceive;
}
uintReadReg(ucharregAddr)//芯片读寄存器
{
uintbuf;
OpenIIC();
IICsendByte(RDA_WRITE);//发送芯片地址方向为写
IIC_Wait_Ack();
IICsendByte(regAddr);//发送寄存器地址
IIC_Wait_Ack();
OpenIIC();
IICsendByte(RDA_READ);//发送芯片地址方向为读
IIC_Wait_Ack();
buf=IICReadByte
(1);
buf=buf<<8;
buf=buf|IICReadByte(0);
CloseIIC();
returnbuf;
}
voidWriteReg(ucharregAddr,uintval)//芯片写寄存器
{
OpenIIC();
IICsendByte(RDA_WRITE);//发送芯片地址方向为写
IIC_Wait_Ack();
IICsendByte(regAddr);//发送寄存器地址
IIC_Wait_Ack();
IICsendByte(val>>8);
IIC_Wait_Ack();
IICsendByte(val&0XFF);
IIC_Wait_Ack();
CloseIIC();
}
voidVol_Set(ucharvol)//音量设置0~15
{
uinttemp=0;
temp=ReadReg(RDA_R05);
temp&=0xfff0;
WriteReg(0x05,vol|temp);
}
voidMute_Set(ucharmute)//静音设置1为静音0为不静音
{
uinttemp=0;
temp=ReadReg(0X02);
if(!
mute)temp|=1<<14;
elsetemp&=~(1<<14);
WriteReg(0X02,temp);
}
voidBass_Set(ucharbass)//频带设置
{
uinttemp=0;
temp=ReadReg(0X02);
if(bass)temp|=1<<12;
elsetemp&=~(1<<12);
WriteReg(0X02,temp);
}
ucharRssi_Get(void)//信号强度获取0~63
{
uinttemp=0;
temp=ReadReg(0X0B);
temp=(temp>>9)&0x7f;
returntemp;
}
voidSeekth_Set(uintrssi)//自动搜台信号阈值强度0~15默认为8数值越低搜到的台越多
{
uinttemp;
rssi=rssi&0xf;
temp=ReadReg(0X05);
temp&=~(0xf<<8);
temp|=rssi<<8;
WriteReg(0X05,temp);
}
voidSeek_direction(uchardirection)//搜台方向1向上搜索0向下搜索
{
uinttemp;
temp=ReadReg(RDA_R02);
temp&=~(1<<9);
if(direction==1)
temp|=1<<9;
//if(direction==0)
//temp|=0<<9;
WriteReg(0X05,temp);
}
voidFreq_Set(uintfreq)//频率设置单位是:
10KHz6500~10800
{
uinttemp;
ucharspc=0,band=0;
uintfbtm,chan;
temp=ReadReg(0X03);
temp&=0X001F;
band=(temp>>2)&0x03;
spc=temp&0x03;
if(spc==0)spc=10;
elseif(spc==1)spc=20;
elsespc=5;
if(band==0)fbtm=8700;
elseif(band==1||band==2)fbtm=7600;
else
{
fbtm=ReadReg(0X53);
fbtm*=10;
}
if(freqchan=(freq-fbtm)/spc;
chan&=0X3FF;
temp|=chan<<6;
temp|=1<<4;
WriteReg(RDA_R03,temp);
delayms(20);
//while((ReadReg(0X0B)&(1<<7))==0);
}
unsignedintseek_channel(void)//半自动搜台
{
unsignedlongtemp;
temp=ReadReg(RDA_R02);
temp|=(1<<8);
WriteReg(RDA_R02,temp);//SEEK位置一使能自动搜台
while((ReadReg(RDA_R0A)&(1<<14))==0)//等待STC位置一表示搜索完成
{
delayms(10);//?
óê±10ms
}
temp=((ReadReg(RDA_R0A)&0x3FF)*100000+87000000)/10000;//获取当前频率
returntemp;//返回搜到电台频率单位是:
10Khz
}
voidFM_enable(ucharflag)//1使能芯片0禁用芯片
{
uinttemp;
temp=ReadReg(RDA_R02);
if(flag==1)
temp|=1;
if(flag==0)
temp&=~0x1;
WriteReg(RDA_R02,temp);
}
voidRDA_Init(void)//RDA3?
ê?
?
ˉ
{
WriteReg(RDA_R02,0x0002);//软复位
delayms(30);
WriteReg(RDA_R02,0xd081);//?
§32.768Khz?
òé÷?
?
μíò?
á¢ì?
éùSKMODE=1÷μ?
±?
?
μê±í£?
1
WriteReg(RDA_R03,0x0000);//?
μ?
êéè?
a87MHz£?
2100Khz?
μ′?
?
a87M~108M
WriteReg(RDA_R04,0x0040);//?
ù±
WriteReg(RDA_R05,0X8882);//ò?
á?
éèavol=2÷·§?
μ?
a8
FM_enable
(1);//?
?
Dé?
μ?
Seekth_Set(8);//自动搜台信号阈值强度0~15默认为8数值越低搜到的台越多
}
voiddisplay_1602()
{
write_com(0x80);
for(num=0;num<34;num++)
{
write_data(a[num]);
delayms(5);
}
write_com(0x80+0x40);
for(num=0;num<34;num++)
{
write_data(b[num]);
delayms(5);
}
}
voidmain()
{
unsignedcharKey_num=0,Vol=1,RSSI=0,mute=1;
unsignedintRXFreq=8830,time=0;
unsignedintDiantai[40]={8830};
charNum=0,station=1;
unsignedinttest=7896;
unsignedinttemp=10;
init_1602();
display_1602();
RDA_Init();//RDA5807初始化
Freq_Set(8830);//频率设置
Vol_Set
(2);
DisplayFrq(88.3);
DisplayVol
(2);//显示音量
while
(1)
{
time++;
if(time>1000)
Display_RSSI(Rssi_Get());//显示信号强度
Key_num=ScanKey();
switch(Key_num)
{
case1:
{if(RXFreq==8800)RXFreq=8800;//频率减
elseRXFreq-=10;
Freq_Set(RXFreq);
DisplayFrq(RXFreq/100.0);
while(0!
=ScanKey());//按键释放
break;
}
case2:
{if(RXFreq==10800)RXFreq=10800;//频率加
elseRXFreq+=10;
Freq_Set(RXFreq);
DisplayFrq(RXFreq/100.0);
while(0!
=ScanKey());//按键释放
break;
}
case5:
{//声音减
if(Vol==0)
Vol=0;
else
Vol-=1;
Vol_Set(Vol);
DisplayVol(Vol);//显示音量
while(0!
=ScanKey());//按键释放
break;
}
case6:
{if(Vol==15)Vol=15;//声音加
elseVol+=1;
Vol_Set(Vol);
DisplayVol(Vol);//显示音量
while(0!
=ScanKey());//按键释放
break;
}
case7:
{if(mute==1)//静音
{
Mute_Set
(1);
Display_mute();//显示静音
while(0!
=ScanKey());//按键释放
mute=0;
break;
}
if(mute==0)
{
Mute_Set(0);
DisplayVol(Vol);//取消静音显示音量
mute=1;
}
while(0!
=ScanKey());
break;
}
case9:
{//电台减但是必须先按9进行电台搜索
while(0!
=ScanKey());//按键释放
Seek_direction(0);//