600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > 基于51单片机TEA5767的FM数字收音机原理图程序设计

基于51单片机TEA5767的FM数字收音机原理图程序设计

时间:2019-08-05 05:53:27

相关推荐

基于51单片机TEA5767的FM数字收音机原理图程序设计

硬件设计

(末尾附文件)

该系统利主要由STC89C52单片机、液晶显示器、按键、调频收音模块TEA5767、功放LM386组成[1]。实际运行时,用TEA5767搜索频率,利用单片机STC89C52控制处理,经LM386芯片放大音频功率同时再通过液晶显示器显示频率,最终实现87.5MHz~108MHz调频广播的接收

系统以STC89C52单片机作为控制模块,无线FM模块作为调频选台模块。系统框图如图1-1所示。

原理图:

程序设计

/**************************************************************** ***************************************************************/#include <reg52.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned int#define DELAY5US _nop_();_nop_();_nop_();_nop_();_nop_();//**************TEA5767模块接线方法********************sbit SDA=P1^0;sbit SCL=P1^1;//*************频率调节按键接线************************sbit Key1=P1^2;sbit Key2=P1^3;//==============LCD1602接口连接方法=====================/*-----------------------------------------------------|DB0-----P0.0 | DB4-----P0.4 | RW-------P2.3 ||DB1-----P0.1 | DB5-----P0.5 | RS-------P2.4 ||DB2-----P0.2 | DB6-----P0.6 | E--------P2.2 ||DB3-----P0.3 | DB7-----P0.7 | ---------------------------------------------------*///================================================*/ #define LCM_DataP0 //LCD1602数据接口#define Busy 0x80 //用于检测LCM状态字中的Busy标识sbit LCM_RW= P2^6; //读写控制输入端,LCD1602的第五脚sbit LCM_RS= P2^5; //寄存器选择输入端,LCD1602的第四脚sbit LCM_E= P2^7; //使能信号输入端,LCD1602的第6脚//*****************参数定义*****************************unsigned long int FM_FREQ; //频率unsigned short int FM_PLL; //PLLuchar idata sbuf[5]; // 数据发送缓冲区uchar idata numbyte;uchar idata numbyte_AMP;uchar idata ADDRESS_AMP;uchar idata ADDRESS_SEND; //TEA5767发送地址uchar idata ADDRESS_RECEIVE; //TEA5767接收地址uchar idata rbuf[5]; // 数据接收缓冲区uchar idata ampint[5];uchar bdata PLL_HIGH; uchar bdata PLL_LOW; //设定用于搜索和预设的可编程频率合成器uchar bdata I2C_byte1;//发送的五字节TEA5767可位寻址的设置值uchar bdata I2C_byte2;uchar bdata I2C_byte3;uchar bdata I2C_byte4;uchar bdata I2C_byte5;sbit MUTE =I2C_byte1^7;//如果MUTE=1,则左右声道被静音;MUTE=0,左右声道正常工作 sbit SM = I2C_byte1^6; //SM=1,则处于搜索模式;SM=0,不处于搜索模式sbit SUD=I2C_byte3^7; //SUD=1,增加频率搜索;SUD=0,减小频率搜索uchar byte1; uchar byte2;uchar byte3;uchar byte4;uchar byte5;uchar num1,num2,num3,num4;uchar tab1[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};bit bdata NACK; // 错误标志位//**********相关函数声明**************************************void init(void); //TEA5767初始化void delay600ms(void); //延迟600msvoid delay100ms(void);//延迟100msvoid delay10ms();void delay1ms(void);//延迟1msvoid sendnbyte(uchar idata *sla, uchar n);//与sendbyte函数构成I2C数据发送函数void I2C_start(void);//I2C 传输开始void sendbyte(uchar idata *ch);void checkack(void); //检查应答讯号void stop(void);//I2C传输结束void AMP_sendnbyte(uchar idata *sla,uchar numbyte_AMP);void key_scan(void);//键扫描void search_up(void); //接收频率向上加void search_down(void); //接收频率向下减void setByte1Byte2(void); //设置第一第二字节频率void LCMInit(void);//LCD初始void DelayMs(uint Ms);//1MS基准延时程序void WriteDataLCM(uchar WDLCM);//LCD模块写数据void WriteCommandLCM(uchar WCLCM,BuysC); //LCD模块写指令uchar ReadStatusLCM(void);//读LCD模块的忙标void DisplayOneChar(uchar X,uchar Y,uchar ASCII);//在第X+1行的第Y+1位置显示一个字符void LCDshow(void);void DelayMs(uint Ms);void show();//开机问候语//*****************主程序******************************void main(void){numbyte = 5;numbyte_AMP=5;ADDRESS_SEND = 0xC0;// TEA5767写地址 1100 0000ADDRESS_RECEIVE=0XC1;//TEA5767读地址 1100 0001ADDRESS_AMP=0X8E;init();// 初始化TEA5767show();//开机问候语LCMInit();//LCD初始LCDshow();while(1){key_scan(); //键扫描}}//**************开机问候语**************************void show(){LCMInit();//LCD初始DisplayOneChar(0, 1,'H');//DisplayOneChar(0, 2,'e');//DisplayOneChar(0, 3,'l');//DisplayOneChar(0, 4,'l');//DisplayOneChar(0, 5,'o');//DisplayOneChar(0, 6, ',');DisplayOneChar(0, 7,'W');//DisplayOneChar(0, 8,'e');//DisplayOneChar(0, 9, 'l');DisplayOneChar(0, 10, 'c');DisplayOneChar(0, 11, 'o');DisplayOneChar(0, 12, 'm');DisplayOneChar(0, 13, 'e');DelayMs(500);DisplayOneChar(1, 1,' ');// 显示姓名DisplayOneChar(1, 2,' ');//DisplayOneChar(1, 3,' ');//DisplayOneChar(1, 4,' ');//DisplayOneChar(1, 5,' ');//DisplayOneChar(1, 6,' ');//DisplayOneChar(1, 7,' ');DisplayOneChar(1, 8,' ');//DisplayOneChar(1, 9,' ');//DisplayOneChar(1, 10,' ');DisplayOneChar(1, 11,' ');DisplayOneChar(1, 12,' ');DisplayOneChar(1, 13,' ');DisplayOneChar(1, 14,' ');DelayMs(500);}//**************按键扫描程序************************void key_scan(void){if(Key1==0){delay10ms();if(Key1==0){while(Key1==0);search_up(); //频率向上LCDshow();delay600ms();}}if(Key2==0){delay10ms();if(Key2==0){while(Key2==0);search_down(); //频率向下LCDshow();delay600ms();}}}//*********************LCD1602显示程序*********************void LCDshow(void){num1=FM_FREQ/100000000;num2=(FM_FREQ%100000000)/10000000;num3=(FM_FREQ%10000000)/1000000;num4=(FM_FREQ%1000000)/100000;DisplayOneChar(0, 4,'F');//DisplayOneChar(0, 5,'M');//DisplayOneChar(0, 6,'R');//DisplayOneChar(0, 7,'a');//DisplayOneChar(0, 8,'d');//DisplayOneChar(0, 9,'i');//DisplayOneChar(0, 10,'o');//DisplayOneChar(1, 4, tab1[num1]);DisplayOneChar(1, 5, tab1[num2]);DisplayOneChar(1, 6, tab1[num3]);DisplayOneChar(1, 7, '.');DisplayOneChar(1, 8, tab1[num4]);DisplayOneChar(1, 9,'M');//DisplayOneChar(1, 10,'H');//DisplayOneChar(1, 11,'Z');//}/*======================================================================LCM初始化======================================================================*/void LCMInit(void) {LCM_Data = 0;WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号DelayMs(5);WriteCommandLCM(0x38,0);DelayMs(5);WriteCommandLCM(0x38,0);DelayMs(5);WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号WriteCommandLCM(0x08,1); //关闭显示WriteCommandLCM(0x01,1); //显示清屏WriteCommandLCM(0x06,1); // 显示光标移动设置WriteCommandLCM(0x0C,1); // 显示开及光标设置DelayMs(100);}//==============================LCD1602显示子程序================================================// 写数据函数: E =高脉冲 RS=1 RW=0//======================================================================*/void WriteDataLCM(uchar WDLCM){ReadStatusLCM(); //检测忙LCM_Data = WDLCM;LCM_RS = 1;DelayMs(1);LCM_RW = 0;DelayMs(1);LCM_E = 0; //若晶振速度太高可以在这后加小的延时LCM_E = 0; //延时DelayMs(1);LCM_E = 1;}/*====================================================================写指令函数: E=高脉冲 RS=0 RW=0======================================================================*/void WriteCommandLCM(uchar WCLCM,BuysC) //BuysC为0时忽略忙检测{if (BuysC) ReadStatusLCM(); //根据需要检测忙LCM_Data = WCLCM;LCM_RS = 0;LCM_RW = 0;LCM_E = 0;LCM_E = 0;LCM_E = 1;}/*====================================================================正常读写操作之前必须检测LCD控制器状态:E=1 RS=0 RW=1;DB7: 0 LCD控制器空闲,1 LCD控制器忙。读状态======================================================================*/uchar ReadStatusLCM(void){LCM_Data = 0xFF;LCM_RS = 0;LCM_RW = 1;LCM_E = 0;LCM_E = 0;LCM_E = 1;while (LCM_Data & Busy); //检测忙信号 return(LCM_Data);}/*======================================================================功 能:在1602 指定位置显示一个字符:第一行位置0~15,第二行16~31说 明:第 X 行,第 y 列 注意:字符串不能长于16个字符======================================================================*/void DisplayOneChar( uchar X, uchar Y, uchar ASCII){X &= 0x1;Y &= 0xF; //限制Y不能大于15,X不能大于1if (X) Y |= 0x40; //当要显示第二行时地址码+0x40;Y |= 0x80; // 算出指令码WriteCommandLCM(Y, 0); //这里不检测忙信号,发送地址码WriteDataLCM(ASCII);}/*====================================================================设定延时时间:x*1ms====================================================================*/void DelayMs(uint Ms){uint i,TempCyc;for(i=0;i<Ms;i++){TempCyc = 250;while(TempCyc--);}}

.

文件仅供参考:

链接:/s/10tXZyQjqkFi-KFaApVWgHw

提取码:r0bg

.

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。