`TEA5767数码管显示调频收音机
在深圳本地目前能收到如下电台![]()
/*****************************************************************************************' @% P' m2 U4 u$ c+ R* i* ?( M
unsigned char radio_write_data[5] = {0x2c,0xe1,0x70,0x16,0x80}; //频率为93.9MHz 广东音乐电台
unsigned char radio_write_data[5] = {0x30,0x5c,0x70,0x16,0x80}; //频率为101.2MHz 广东电台音乐之声" `, a! V' U, B3 U, o. z
unsigned char radio_write_data[5] = {0x31,0x38,0x70,0x16,0x80}; //频率为103.0MHz 广东珠江经济电台
unsigned char radio_write_data[5] = {0x31,0xd7,0x70,0x16,0x80}; //频率为104.3MHz 宝安广播电台
unsigned char radio_write_data[5] = {0x32,0x20,0x70,0x16,0x80}; //频率为104.9MHz 中央人民广播电台华夏之声1 F% m% ^ z, R$ t: L) j6 i/ d' Q# m) T
unsigned char radio_write_data[5] = {0x33,0x2d,0x70,0x16,0x80}; //频率为107.1MHz 中国国际广播电台环球资讯) v+ r7 [0 h/ q- s: {$ z; L" f
/***************************************************************************************/
- /**********************************************************************************************
- AT89S52+12MHZ+TEA5767的数码管显示调频收音机
- 本程序使用数码管显示频率 晶振是用12M 已通过测试,收音机的频率调节是用计算的方法 将显示的频率算好后写到TEA5767# u& R; " D( F6 i/ }& x& H2 k
- 芯片里面实现调节的 两个按键实现自加或自减频率 加了连续加减功能!
- 使用的是在淘宝上买的4.5元/片的简化版的TEA5767模块.
- 2012-05-08
- /*****************************************************************************************/
- #include < reg51.h >
- #define uchar unsigned char
- #define uint unsigned int
- /*********************************************************************************************/
- ***it SDA = P3^0; //接在TEA5767的数据端口
- ***it SCL = P3^1; //接在TEA5767的时钟端口
- ***it KEY1 = P3^4; //频率增加按键端口
- ***it KEY2 = P3^5; //频率减小按键端口
- ***it KEY3 = P3^6; //频率增加按键端口
- ***it KEY4 = P3^7; //频率减小按键端口
- #define duan P0 //频率显示的数码管段选P0端口
- //#define gy //使用共阴极时屏蔽这行
- ***it dula=P2^6;
- ***it wela=P2^7;
- uchar IF,ADC,CH;
- //bit RF,STEREO;
- #ifdef gy
- unsigned char code dispbit[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};//显示位码
- unsigned char code dispcode[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};//数码管显示编码2
- /***************************************************************************************
- unsigned char code dispcode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00}; //数码管显示编码
- unsigned char code dispbit[]={0x7e,0x7d,0x7b,0x77,0x6f,0x5f};/*定义点亮的数码管与数组的关系*/
- #endif
- /***************************************************************************************
- unsigned char radio_write_data[5] = {0x2c,0xe1,0x70,0x16,0x80}; //频率为93.9MHz 广东音乐电台
- unsigned char radio_write_data[5] = {0x30,0x5c,0x70,0x16,0x80}; //频率为101.2MHz 广东电台音乐之声
- unsigned char radio_write_data[5] = {0x31,0x38,0x70,0x16,0x80}; //频率为103.0MHz 广东珠江经济电台
- unsigned char radio_write_data[5] = {0x31,0xd7,0x70,0x16,0x80}; //频率为104.3MHz 宝安广播电台
- unsigned char radio_write_data[5] = {0x32,0x20,0x70,0x16,0x80}; //频率为104.9MHz 中央人民广播电台华夏之声
- unsigned char radio_write_data[5] = {0x33,0x2d,0x70,0x16,0x80}; //频率为107.1MHz 中国国际广播电台环球资讯
- /*****************************************************************************************/
- unsigned char radio_read_data[5];
- unsigned char radio_write_data[5];
- unsigned long frequency = 104900; //开机初始化的电台频率为104.9MHz中央民广播电台华夏之声
- unsigned int PLL; //计算频率合成时用的变量
- /****************************************************************************************/
- void Delayus(unsigned char x)
- for(;x > 0;x--);
- /*****************************************************************************************/
- void iic_start() //启动总线传输
- SDA = 1;
- Delayus(4);
- SCL = 1;
- Delayus(4);
- SDA = 0;
- Delayus(4);
- SCL = 0;
- Delayus(4);
- }
- /**********************************************************************************************/
- void iic_stop() //结束总线传输
- {
- SCL = 0;
- Delayus(4);
- SDA = 0;1
- Delayus(4);
- SCL = 1;
- Delayus(4);
- SDA = 1;
- Delayus(4);
- }
- /********************************************************************************************/
- void iic_ack() //发送应答位
- {
- SDA = 0;
- Delayus(4);
- SCL = 1;
- Delayus(4);
- SCL = 0;
- Delayus(4);
- SDA = 1;
- Delayus(4);
- }
- /****************************************************************************************/
- bit iic_testack()
- {
- bit ErrorBit;
- SDA = 1;
- Delayus(4);
- SCL = 1;
- Delayus(4);
- ErrorBit = SDA;
- Delayus(4);
- SCL = 0;
- return ErrorBit;
- }
- /*********************************************************************************************/
- void iic_write8bit(unsigned char input) //写一个字节的数据到总线上
- {
- unsigned char temp;
- for(temp = 8;temp > 0;temp--)
- SDA = (bit)(input & 0x80);
- Delayus(4);
- SCL = 1;
- Delayus(4);
- SCL = 0;
- Delayus(4);
- input = input << 1;
- }
- }
- /*********************************************************************************************/
- uchar iic_rdbyt() //从总线上读取一个字节的数据
- {
- uchar a = 0,i = 0;
- for(i = 0;i < 8;i++)
- {
- SDA = 1;
- SCL = 1;
- if(SDA == 1)
- {
- a = (a << 1) + 1;
- SCL = 0;
- }
- else if(SDA == 0)
- a = a << 1;
- SCL = 0;
- }
- }
- return(a);
- }
- /***********************************************************************************/
- void delays (unsigned char b) //按键消抖用的延时程序
- {
- unsigned char i;
- for(b;b > 0;b--)
- for(i = 0;i < 250;i++);
- }
- /**************************************************************************************/!
- void radio_write(void) //写入TEA5767
- {
- unsigned char i;
- iic_start(); //启动总线传输
- iic_write8bit(0xc0); //TEA5767写地址
- if(!iic_testack())
- {
- for(i = 0;i < 5;i++)
- {
- iic_write8bit(radio_write_data); //写一个字节的数据到总线上
- iic_ack(); //发送应答位
- }) i7 }
- }
- iic_stop(); //结束总线传输
- }
- /**************************************************************************************/
- //将显示的频率算好后写到TEA5767芯片里面实现调节,不用考虑TEA5767用于搜台的相关位:SM,SUD
- //写模式$ E' I. O B4 u' G0 r
- //数据字节1 数据字节2 数据字节3 数据字节4 数据字节5
- void search()
- {
- PLL = (unsigned int)((float)((frequency + 225)) / (float)8.192); //计算合成频率数据 频率单位:k
- /*********************************************************************************************/
- //数据字节1的格式 radio_write_data[0]
- //位7(高位) 位6 位5 位4 位3 位2 位1 位0(低位)
- // MUTE SM PLL13 PLL12 PLL11 PLL10 PLL9 PLL8/ R C)
- //7 MUTE 如果MUTE=1 则左右声道被静音;MUTE=0 左右声道正常工作。
- //6 SM 如果SM=1 则处于搜索模式 SM=0 不处于搜索模式
- //5到0 PLL[13:8] 设定用于搜索和预设的可编程频率合成器。
- radio_write_data[0] = PLL / 256; //将算好的频率高位数据存入将要TEA5767的数组里
- /************************************************************************************************/
- //数据字节2的格式 radio_write_data[1]
- //位7(高位) 位6 位5 位4 位3 位2 位1 位0(低位)
- // PLL7 PLL6 PLL5 PLL4 PLL3 PLL2 PLL1 PLL01
- //PLL[7:0] 设定用于搜索和预设的可编程频率合成器。
- radio_write_data[1] = PLL % 256; //将算好的频率低位数据存入将要TEA5767的数组里
- /***********************************************************************************************/
- //数据字节3的格式 radio_write_data[2]
- //位7(高位) 位6 位5 位4 位3 位2 位1 位0(低位)
- // SUD SSL1 SSL0 HLSI MS ML MR SWP1
- //SUD SUD=1 增加频率搜索 SUD=0 减小频率搜索。
- //SLL[1:0] 搜索停止标准:见下表1。
- //SSL0 SSL1 搜索停止标准
- // 0 0 在搜索模式下禁止
- // 0 1 低:ADC输出大小为5
- // 1 0 中:ADC输出大小为7
- // 1 1 高:ADC输出大小为10
- //HLSI 高/低充电电流切换:HLSI=1 高充电电流 HLSI=0 低充电电流
- //MS 立体声/单声道:MS=1 单声道 MS=0 立体声
- //ML 左声道静音:ML=1 左声道静音并置立体声 ML=0 左声道正常。
- //MR 右声道静音:MR=1 右声道静音并置立体声 MR=0 右声道正常
- //SWP1 软件可编程端口1:SWP1=1 端口1高电平 SWP1=0 端口1低电平。
- radio_write_data[2] = 0x70; //这是TEA5767开立体声 关静音
- /******************************************************************************************/
- //数据字节4的各个位描述 radio_write_data[3]
- //位7(高位) 位6 位5 位4 位3 位2 位1 位0(低位))
- // SWP2 STBY BL XTAL SMUTE HCC SNC SI
- //SWP2 软件可编程端口2:SWP2=1,端口2高电平;SWP2=0,端口2低电平。
- //STBY 等待:STBY=1 处于待机模式,STBY=0,退出待机模式。
- //BL 波段制式:BL=1 日本调频制式 BL=0,美国/欧洲调频制式。
- //XTAL 如果XTAL=1 那么fxtal=32.768KHz;如果XTAL=0 那么fxtal=13MHz
- //SMUTE 软件静音:SMUTE=1 软静音打开;SMUTE=0,软静音关闭。
- //HCC 白电平切割:HCC=1 高电平切割打开 HCC=0 高电平切割关闭。
- //SNC 立体声噪声去除:如果SNC=1,立体声消噪除打开,如果SNC=0,立体声消噪除关闭。
- //SI 搜索标志位:SI=1 SWPORT1输出准备好信号 SI=0 SWPORT1作为软件可编程端口1用。
- radio_write_data[3] = 0x16; //中国制式 采用32768晶振 软静音关 立体声消噪声开
- /*****************************************************************************************/
- //数据字节5的格式 radio_write_data[4]
- //位7(高位) 位6 位5 位4 位3 位2 位1 位0(低位)
- // PLLREF DTC -- -- -- -- -- --
- //若PLLREF=1 6.5MHz的锁相环参考频率启用;若PLLREF=0 6.5MHz的锁相环参考频率关闭。
- //若DTC=1 去加重时间常数为75us;若DTC=0 去加重时间常数为50us。
- //位5到0 未用 状态不必考虑。
- radio_write_data[4] = 0x80; //6.5M锁相环开 去加重时间50US
- /******************************************************************************************/
- radio_write(); //写入TEA5767
- }
- /********************************************************************************************
- //读模式
- //数据字节1 数据字节2 数据字节3 数据字节4 数据字节5
- //数据字节1的格式
- //位7(高位) 位6 位5 位4 位3 位2 位1 位0(低位)
- // RF BLF PLL13 PLL12 PLL11 PLL10 PLL9 PLL80 b. R/ ]8 d- s8 W
- //7 RF 准备好标志:RF=1 有一个频道被搜到或者一个制式已经符合;RF=0 没有频道被搜到。
- //6 BLF 波段制式:BLF=1 一个制式已经符合 BLF=0 没有制式已经符合。
- //5到0 PLL[13:8] 用于搜索和预设后的可编程频率合成器设定结果。
- //数据字节2的格式
- //位7(高位) 位6 位5 位4 位3 位2 位1 位0(低位)
- // PLL7 PLL6 PLL5 PLL4 PLL3 PLL2 PLL1 PLL0
- //数据字节2的各个位描述3
- //PLL[7:0] 设定用于搜索和预设后的可编程频率合成器设定结果。
- //数据字节3的格式
- //位7(高位) 位6 位5 位4 位3 位2 位1 位0(低位)
- // STEREO IF6 IF5 IF4 IF3 IF2 IF1 IF0
- //7 STEREO 立体声标志位:STEREO=1 立体声接收 STEREO=0 单声道接收。
- //6到0 IF[6:0] 中频计数器结果。
- //数据字节4的格式
- //位7(高位) 位6 位5 位4 位3 位2 位1 位0(低位)
- // LEV3 LEV2 LEV1 LEV0 CI3 CI2 CI1 0
- //7到4 LEV[3:0] ADC的输出
- //3到1 CI[3:1] 芯片验证号
- //0 ------ 该位内部置
- //数据字节5的格式
- //位7(高位) 位6 位5 位4 位3 位2 位1 位0(低位)
- // 0 0 0 0 0 0 0 0
- //7到0 ------ 预留为扩展用 由内部置0。
- /*******************************************************************************************/
- void delay()
- {
- uchar k;
- for(k = 0;k < 100;k++);
- }
- /*****************************************************************************************/
- void desplay(uint aa)
- {
- /*****************************************************************************************
- duan = tab[aa / 1000] | 0x80; //关这位数码管的小数点
- led1 = 0;
- delay();
- led1 = 1;
- duan = tab[aa % 1000 / 100] | 0x80; //关这位数码管的小数点
- led2 = 0;
- delay();
- led2 = 1;
- duan = tab[aa % 100 / 10] & 0x7f; //点亮这位数码管的小数点
- led3 = 0;
- delay();. };
- led3 = 1;
- duan = tab[aa % 10] | 0x80; //关这位数码管的小数点
- led4 = 0;
- delay();
- led4 = 1;
- /*************************************************************************************************/
- dula = 0;
- if((aa / 1000) == 0)
- duan = dispcode[aa / 1000 + 10]; //这位为0数码管不显示
- else
- duan = dispcode[aa / 1000]; //这位数码管显示频率百位
- dula = 1;
- dula = 0;
- wela = 0;
- duan = dispbit[2];
- wela = 1;
- wela = 0;
- delay();
- delay();
- delay();
- delay();
- delay();
- delay();
- dula = 0;
- duan = dispcode[aa % 1000 / 100]; //这位数码管显示频率十位
- dula = 1;
- dula = 0;
- wela = 0;
- duan = dispbit[3];
- wela = 1;
- tica, Arial, sans-serif; background-color: rgb(255, 255, 255);">wela = 0; + o1 E1 Y( a, f! a
- delay();
- delay();
- delay();
- delay();
- delay();
- delay();
- dula = 0;
- #ifdef gy
- duan = dispcode[aa % 100 / 10] & 0x7F; //这位数码管显示频率百位 开数码管的小数点
- #else;
- duan = dispcode[aa % 100 / 10] | 0x80; //这位数码管显示频率百位 开数码管的小数点
- #endif:
- dula = 1;
- dula = 0;
- wela = 0;
- duan = dispbit[4];
- wela = 1;
- wela = 0;
- delay();
- delay();
- delay();
- delay();
- delay();
- delay();
- dula = 0;
- duan = dispcode[aa % 10]; //这位数码管显示频率小数位1
- dula = 1;
- dula = 0;
- wela = 0;
- duan = dispbit[5];
- wela = 1;
- wela = 0;
- delay();
- delay();
- delay();
- delay();
- delay();
- delay();
- }
- /******************************************************************************************/
- //由频率计算PLL
- void get_pll(void)
- {
- unsigned char hlsi;
- unsigned int twpll = 0;
- hlsi = radio_write_data[2] & 0x10;
- if (hlsi)
- PLL = (unsigned int)((float)((frequency + 225) * 4) / (float)32.768); //频率单位
- else+ D:
- PLL = (unsigned int)((float)((frequency - 225) * 4) / (float)32.768); //频率单位:k
- }
- /*********************************************************************************************/
- //由PLL计算频率
- void get_frequency(void)//读TEA5767状态,并转换成频率
- {
- unsigned char hlsi;
- unsigned int npll = 0;f
- npll = PLL;; Q$ F# s! o% d: z f: E+ O
- hlsi = radio_write_data[2] & 0x10;
- if (hlsi)
- frequency = (unsigned long)((float)(npll) * (float)8.192 - 225); //频率单位:KHz
- else
- frequency = (unsigned long)((float)(npll) * (float)8.192 + 225); //频率单位:KHz! j' i1 o: A1 g
- }
- /****************************************************************************************/
- //读TEA5767状态,并转换成频率r
- void radio_read(void)//读收音机芯片数据7
- {
- unsigned char i;
- unsigned char temp_l,temp_h;
- PLL = 0;
- iic_stop(); //结束总线传输
- iic_start(); //启动总线传输
- iic_write8bit(0xc1); //TEA5767写地址
- if(!iic_testack())
- {
- for(i = 0;i < 5;i++)
- {
- radio_read_data = iic_rdbyt();//从总线上读取一个字节的数据
- iic_ack(); //发送应答位
- }
- }
- iic_stop(); //结束总线传输
- //RF = radio_read_data[0] & 0x80;
- IF = radio_read_data[2] & 0x7f; //去掉最高位就是IF值
- ADC = radio_read_data[3]; //去掉最高位就是IF值
- ADC >>= 4; L$ T9 r; p/ c
- //STEREO = radio_read_data[2] & 0x80; //最高位就是STEREO值
- temp_l = radio_read_data[1];
- temp_h = radio_read_data[0];
- temp_h &= 0x3f;
- PLL = temp_h * 256 + temp_l;
- get_frequency(); //读TEA5767状态,并转换成频率
- }
- /*******************************************************************************************/
- #define max_freq 108000;
- #define m
- //unsigned char aa[6] = {0};
- radio_write();//写收音机芯片数据
- if(dec)//自动搜台,mode=1,频率增加搜台
- {
- while(frequency < max_freq)//如果当前频率小于最大频率上限值
- {
- get_pll();//由频率计算PLL
- radio_write_data[0] = PLL / 256;
- radio_write_data[1] = PLL % 256;
- radio_write_data[2] = 0xA0; //增加频率搜索,低:ADC输出大小为5,高充电电流
- radio_write_data[3] = 0x11; //fxtal=32.768KHz,软件静音开
- radio_write_data[4] = 0x80; //6.5MHz的锁相环参考频率开,去加重时间常数为50us。
- radio_write_data[0] |= 0x40; //0100 0000 = SM / SM=1 则处于搜索模式
- radio_write(); //写入TEA5767
- desplay(frequency / 100); //调用显示
- radio_read(); //读收音机芯片数据
- //if((radio_read_data[0] & 0x80))//如果有一个频道被搜到或者一个制式已经符合
- if((IF < 0x3e) && (IF > 0x31) && (ADC > 4))//&&(STEREO)&&(RF))//如搜到电台
- {
- frequency += 100;
- return;
- }
- }
- frequency = min_freq;//将最小频率下限值赋给当前频率
- }
- else//自动搜台, mode=0:频率减小搜台
- {
- while(frequency > min_freq)//如果当前频率大于最小频率下限值
- {
- get_pll();//由频率计算PLL
- radio_write_data[0] = PLL / 256;
- radio_write_data[1] = PLL % 256;
- radio_write_data[2] = 0x20; //减小频率搜索,低:ADC输出大小为5,高充电电流
- radio_write_data[3] = 0x11; //fxtal=32.768KHz,软件静音开
- radio_write_data[4] = 0x80; //6.5MHz的锁相环参考频率开,去加重时间常数为50us。
- radio_write_data[0] |= 0x40; //0100 0000 = SM / SM=1 则处于搜索模式
- radio_write(); //写入TEA5767
- desplay(frequency / 100); //调用显示
- radio_read();//读收音机芯片数据
- //if((radio_read_data[0] & 0x80))//如果有一个频道被搜到或者一个制式已经符合
- if((IF < 0x3e) && (IF > 0x31) && (ADC > 4))//&&(STEREO)&&(RF))//如搜到电台
- {
- frequency -= 100;
- return;
- }
- }
- frequency = max_freq;//将最大频率上限值赋给当前频率
- }
- }
- /*****************************************************************************************/
- void main()
- {
- /************************************************************************************************
- //观察变量用/ }
- unsigned char B,D;
- frequency = 104900;
- PLL = (unsigned int)((float)((frequency + 225)) / (float)8.192);
- B = PLL/256;
- D = PLL % 256;
- delay();
- /***************************************************************************************************/
- delays(1000); //延时消抖
- search(); //写入初始化电台频率
- //radio_read();
- while(1)
- if(!KEY1) //手动设置频率
- {
- delays(250); //延时消抖
- frequency += 100;
- if(frequency > 108500) //频率如果大于108.5MHz
- frequency = 87500; //频率设定为87.5MHz
- search(); //将显示的频率算好后写到TEA5767芯片里面
- desplay(frequency / 100); //调用显示
- }
- /*************************************************************************************************/
- if(!KEY2) //手动设置频率,-0.1MHz;
- {
- delays(20); //延时消抖
- frequency -=100;
- if(frequency < 87500) //频率如果小于87.5MHz
- frequency = 108500; //频率设定为108.5MHz
- search(); //将显示的频率算好后写到TEA5767芯片里面
- desplay(frequency / 100); //调用显示
- }
- /*************************************************************************************************/
- if(!KEY3) //加频率
- {
- delays(250); //延时消抖
- if(!KEY3)
- {
- auto_search(1);//自动搜台,mode=1,频率增加搜台
- }
- while(!KEY3) desplay(frequency / 100);//调用显示
- }
- /****************************************************************************************************//
- if(!KEY4) //减频率
- {
- delays(20); //延时消抖
- if(!KEY4)
- {
- auto_search(0);//自动搜台mode=0:频率减小搜台
- }
- while(!KEY4) desplay(frequency / 100);//调用显示
- }
- desplay(frequency / 100); //调用显示
- }
- }
- /****************************************************************************************************/
复制代码
`
|