|
单片机FM收音机的实物图:
单片机FM收音机的pcb图:
单片机FM收音机的原理图:
源程序:
- /*****************************************************************
- FM收音机
- 作者:Anyrain
- 版本:1.0
- 说明:
-
- K1--- 向上搜索电台 K2--- 向下搜索电台
- K3--- 音量加 K4--- 音量减
-
- *****************************************************************/
- #include <reg52.h>
- #include <intrins.h>
- #include"delay.h"
- #include "12864.h"
- #include "i2c.h"
- #include"ds1302.h"
- sbit K1 = P3^0;
- sbit K2 = P3^2;
- sbit K3 = P3^1;
- sbit K4 = P3^3;
- unsigned long frequency;
- unsigned char key,timekey,fmkey,mimiflag=0;
- unsigned int count,num;
- // RDA5807 寄存器初始值设定
- unsigned char RDA_reg_data[8] =
- {
- 0xd0,0x00, // 02H 1 1 0 1 XX 0 0
- // 正常操作无静音 立体声 重低音 下搜索 停止搜索
- // 0 000 XX 0 0
- // 自动搜台 32.768 软件不复位 上电不使能
- 0x00,0x10, // 03H 0000000000 CHAN[9:0]
- // Frequency=Spacing(KHz)*CHAN+BAND
- // 0 0 10 00 SPACE
- // 调谐关 76-108MHz 100KHz
- 0x44,0x40, // 04H X 0 X0 0 X000
- // disable Seek/Tune Interrupt 去加重75us
- // 1 00 00 00
- // I2C使能 GPIO3高阻 GPIO2高阻 GPIO1高阻
- 0x88,0xA8, // 05H 1 0010000
- // reg0CH读产生中断 seek threshold
- // 10 00 1000 VOLUME
- // LANP 1.8mA 音量
- };
- /**************************************************************
- *********************连续写寄存器子函数************************/
- void RDA5807_write_reg(void)
- {
- unsigned char i;
- I2C_start(); // 收音模块写入操作
- I2C_write_byte(0x20); // 寄存器连续写操作
- for(i=0; i<8; i++)
- {
- I2C_write_byte(RDA_reg_data[i]);
- }
- I2C_stop();
- }
- /**********************************************************
- *******************连续读寄存器子函数*********************/
- void RDA5807_read_reg(unsigned char *reg_buf)
- {
- I2C_start(); // 收音模块读取操作
- I2C_write_byte(0x21); // 寄存器连续读操作
- reg_buf[0] = I2C_read_byte(I2C_ACK);
- reg_buf[1] = I2C_read_byte(I2C_ACK);
- reg_buf[2] = I2C_read_byte(I2C_ACK);
- reg_buf[3] = I2C_read_byte(I2C_NACK);
- I2C_stop();
- }
- /**********************************************************
- ******************模块上电初始化子函数********************/
- void RDA5807_power(void)
- {
- delayms(50); // 发送软件复位指令,软件复位
- RDA_reg_data[0] = 0x00;
- RDA_reg_data[1] = 0x02;
- RDA5807_write_reg(); //写指令
- delayms(10);
- RDA_reg_data[0] = 0xd2; // 收音模块默认参数,上电使能
- RDA_reg_data[1] = 0x01;
- RDA5807_write_reg(); //写指令
- }
- /**********************************************************
- ******************FM信号显示子函数********************
- void NowSignal()
- {
- unsigned char sin;
- unsigned char reg_data1[4] = {0x00, 0x00, 0x00, 0x00}; //接收寄存初始化
- RDA5807_read_reg(reg_data1);
- delayms(20);
- sin=(reg_data1[2]>>1)&0x7f;
- WriteCommand(0x80);
- if(sin<16)
- ShowChar(0x0,1);
- else if(sin<32)
- ShowChar(0x0,2);
- else if(sin<48)
- ShowChar(0x0,3);
- else
- ShowChar(0x0,4);
- }
- **********************************************************
- ********************收音模块自动寻台子函数****************/
- void RDA5807_FM_seek(void)
- {
- unsigned int chan;
- unsigned char reg_data[4] = {0x00, 0x00, 0x00, 0x00}; //接收寄存初始化
- RDA_reg_data[3] &=~(1 << 4) ; //调谐禁用
- RDA_reg_data[0] |= (1 << 0); //SEEK位置1 内部自动寻台使能
- RDA5807_write_reg();
- while(0 == (reg_data[0]&0x40)) // 读寄存器直到SF 标志置0,自动搜台结束
- {
- delayms(35);
- RDA5807_read_reg(reg_data); // 读取内部状态
- }
- // 获取当前工作频点
- chan = reg_data[0] & 0x03; //READCHAN[9:8]
- chan = reg_data[1] | (chan << 8); //READCHAN[9:0]
- chan = chan << 6; //READCHAN[15:6]
-
- // 保存当前工作频点
- RDA_reg_data[2] = (chan >> 8) & 0xff; //chan高八位送03H[15:8]
- RDA_reg_data[3] = (chan & 0xff); //低位送03H[7:6]
- }
- /**********************************************************
- *********************频率显示子函数************************/
- void show_frequency(void)
- {
- unsigned int display[5];
- unsigned int temp,i;
- temp = (RDA_reg_data[2]*256)+(RDA_reg_data[3]&0xc0); //xxxx xxxx oo00 0000
- temp = temp>>6; //0000 00xx xxxx xxoo
- frequency = (unsigned long)(100*temp+87000)/100; //M/10
-
- display[0] = (frequency)/1000 ; //百M最高位
- display[1] = (frequency%1000)/100; //十M位
- display[2] = (frequency%100)/10; //个M位
- display[3] = 10; //小数点'.'
- display[4] = (frequency%10); //ABC.X
- if(display[0] == 0)
- {
- display[0] = display[1];
- display[1] = display[2];
- display[2] = display[3];
- display[3] = display[4];
- display[4] = 18; //' '空格
- }
- for(i=0;i<5;i++)
- Displayen(1,6,24+8*i,display[i]) ; //频率显示
- }
- /**********************************************************
- *********************音量显示子函数***********************/
- void show_volume()
- {
- unsigned char temp,display0[2],i;
- temp = RDA_reg_data[7] & 0x0f; //取音量值min0-max15
- display0[0] = temp/10;
- display0[1] = temp%10;
- if(display0[0] == 0) //如果高位为0
- {
- display0[0] = display0[1]; //低位显存内容进入高位显存
- display0[1] = 18; //低位不显示
- }
-
- for(i=0;i<2;i++)
- Displayen(2,6,48+8*i,display0[i]) ; //音量值显示
- }
- /**********************************************************
- *********************按键扫描子函数***********************/
- void scan()
- {
- unsigned char keyx; //用来保存短按的值
- P3=0xff;
- if(!K1)
- {
- delayms(20);
- while(!K1)
- {
- TR0=1; //启动定时器
- if(!timekey)
- {
- if(!fmkey)
- keyx=1; //进入1状态
- }
- else keyx=5;
- while(!K1); //长按时间未到,频道增加
- }
- if(count<15)
- {
- key=keyx;
- TR0=0; //关中断 count清零
- count=0;
- }
- else //长按则进入设置
- {
- key=4; //进入4状态
- timekey=~timekey; //timekey=1,设置时间。0正常时钟
- count=0;
- TR0=0; //停止定时器
- }
-
- }
- if(!K2)
- {
- delayms(20);
- while(!K2)
- {
- TR0=1; //启动定时器
- if(!fmkey) //短按处理
- {
- if(timekey)
- keyx=6; //进入6状态 设置+
- else
- keyx=2; //进入2状态 音量加
- }
- else
- {
- if(timekey)
- keyx=6; //进入6状态 设置+
- }
-
- while(!K2); //长按时间未到
-
- }
- if(count<15)
- {
- key=keyx;
- TR0=0; //关中断 count清零
- count=0;
- }
- else //长按则进入fm设置
- {
- key=8;
- fmkey=~fmkey; //fmkey=1关FM,0开FM
- count=0;
- TR0=0; //停止定时器
- }
-
-
- }
- if(K3 == 0)
- {
- delayms(20);
- while(K3 == 0)
- { TR0=1;
- if(!fmkey)
- {
- if(timekey)
- keyx=7; //进入7状态 设置-
- else
- keyx=3; //进入3状态 音量减
- }
- else
- {
- if(timekey)
- keyx=7; //进入7状态 设置-
- }
- while(K3 == 0);
- }
- if(count<15)
- {
- key=keyx;
- TR0=0; //关中断 count清零
- count=0;
- }
- else //长按则背光点亮
- {
- mimiflag=~mimiflag;
- count=0;
- TR0=0; //停止定时器
-
- }
- }
-
- if(!K4)
- {
- delayms(20);
- while(!K4)
- {
- TR0=1; //启动定时器
- keyx=5;
- while(!K4); //长按时间未到,频道增加
- }
- if(count<15)
- {
- key=keyx;
- TR0=0; //关中断 count清零
- count=0;
- }
- else //长按则进入设置
- {
- key=4; //进入4状态
- timekey=~timekey; //timekey=1,设置时间, timekey=0正常时钟.
- count=0;
- TR0=0; //停止定时器
- }
-
- }
- }
- /**********************************************************
- ************************主函数***************************/
- void main(void)
- {
- unsigned char i,j,flag,onedone,flash=15; //闪烁标志的位置
- TMOD=0X11; //设置定时器0、1为工作方式1
- TH0=0xb1; //延时50ms
- TL0=0Xe0;
- EA=1; //开总中断
- ET0=1; //开定时中断
- ET1=1;
- TR1=1;
- InitLCD(); //lcd初始化
- initdisplay();
- Init_DS1302(); //将1302初始化
- Displaytime(); //初始化显示时间
- RDA5807_power(); //收音机模块上电
- show_frequency(); //显示收音机频率
- show_volume(); //显示声音
- while(1)
- {
- scan();
复制代码
完整源程序下载:
单片机FM收音机资料.rar
(359.18 KB, 下载次数: 351)
|
评分
-
查看全部评分
|