本帖最后由 fmdpj 于 2019-8-20 21:21 编辑
小白求助高手,在网上找到的FM发射控制程序,三个独立按键分别是频率加减键与立体声开关,加减键是短按步进0.1MHz,长按自动加减,释放停止加减,刚开始是一按加减键四位数码管就显示0000,按键也同时失效,后来把消抖延时加长到8000(原300)短按加减键会再显示0000可以正常加减,但是长按还是不正常,长按可以加减10到20秒就又显示0000按键同时失效,求高手指点
下面是源代码,请高手帮忙看看程序那里有问题,应该怎样改,谢谢!
- //使用AT89S52单片机,12MHz晶振,使用4位共阳数码管作为频率显示。
- //P1口输出段码,P2口扫描。
- //频率范围87.5MHz--108.0MHz
- //***********************************************************************
- #include <reg52.h>
- #include <intrins.h> //_nop_();延时函数调用
- #define LED_DATA P1 // 数码管段码输出
- #define LED_WEI P2 // 数码管位码输出,扫描口
- #define uchar unsigned char
- #define uint unsigned int
- sbit key_fr_up =P2^3; //频率增加键
- sbit key_fr_down =P2^2; //频率递减键
- sbit key_LTS_KZ =P2^1; //立体声控制键
- sbit LTS_LED =P3^3; //立体声显示//INT1
- sbit CE =P3^4; //锁存信号//CE
- sbit CLK =P3^5; //时钟信号//CLK
- sbit DA =P3^6; //数据信号//DA
- sbit dg =P1^7; //数码管小数点
- //sbit SDA=P3^2;//24C01 数据线
- //sbit SCL=P3^1;//24c01 时钟线
- uint f_data; //频率数值
- //uchar DataBye;//从24C01中读出的暂时存储区
- bit modo; //立体声数据寄存器
- uchar key_temp; //键盘有键按下标志位
- uint i;
- uchar code DATA[11]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xFF};
- //数码管显示字0-9,不显示
- uchar code WEI[4]={0x1f,0x2f,0x4f,0x8f}; //数码管扫描控制
- uchar data display[4]={0x00,0x00,0x00,0x00}; //数码管显示数据缓冲区
- //************************延时函数1******************************
- void Delay1(void)
- {
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- }
- ///***********************延时函数***********************************
- void delay(uint t)
- {
- for(;t>0;t--);
- }
- ///***************************显示函数******************************
- /// 4位数码管动态扫描
- ///*****************************************************************
- void xianshi(void)
- {
- uchar k;
- for(k=0;k<4;k++) //4位数码管显示
- {
- LED_DATA=DATA[display[k]];
- LED_WEI=WEI[k]; //先显示百位
- if(k==2){ dg=0; } //显示小数点
- delay(35);
- }
- LED_DATA=0xff; //清除显示
- }
- ///*************************显示数值处理函数***************************
- //*********************************************************************
- void xianshi_turn(void) //频率数据转换为显示用BCD码函数
- {
- uint fr;
- display[0]=f_data/1000; //求显示百位数
- if(display[0]==0)
- {
- display[0]=10;
- }
- fr=f_data%1000;
- display[1]=fr/100; //求显示十位数
- fr=fr%100;
- display[2]=fr/10; //求显示个位数
- display[3]=fr%10; //求显示小数位
- }
- //***********************综合显示函数*********************************
- //********************************************************************
- void T_Display(void)
- {
- xianshi_turn();
- xianshi();
- }
- ///*************************写数据函数*********************************
- //将数据送入BH1415中
- //*********************************************************************
- void send_16data(uint Data,uchar MODO)
- {
- uchar i;
- CLK=0;
- CE=0;
- CE=1; //连续保存高电平,可输入数据
- for(i=11;i>0;i--)
- {
- DA=Data & 0x01;
- //传输BH1415F2个字节频率控制11位D0-D10频率数据
- Data>>=1;
- Delay1();
- CLK=1;
- Delay1();
- CLK=0;
- }
- DA=MODO;
- Delay1();
- CLK=1; //MONO
- Delay1();
- CLK=0;
- Delay1();
- DA=0;
- Delay1(); //PD0
- CLK=1;
- Delay1();
- CLK=0;
- Delay1();
- DA=0;
- Delay1(); //PD1
- CLK=1;
- Delay1();
- CLK=0;
- Delay1();
- DA=1;
- Delay1(); //测试模式控制关闭
- CLK=1;
- Delay1();
- CLK=0;
- Delay1();
- DA=0;
- Delay1(); //测试模式控制关闭
- CLK=1;
- Delay1();
- CLK=0;
- CE=0; //输入数据结束
- }
- //*************************键盘处理函数*************************//
- //
- //
- //****************************************************************
- void KEY(void)
- {
- uint ii=0,jj=0; //记录频率增加的个数,若ii>4,f以5为增量增加
- uchar key_data; //若jj>4,f以5为增量减小
- P2=0x0F;
- P1=0x0F; //键盘扫描口断码输出初始化//
- if((P2&0x0F)!=0x0F)
- {
- delayms(10);
- if((P2&0x0F)!=0x0F) //防抖动测试
- {
- key_temp=1; //键盘有键按下标志位//
- key_data=P2&0x0F;
- switch(key_data)
- {
- case 0x07: //频率自动加//
- {
- f_data++;
- if(f_data>1080)
- f_data=875;
- T_Display();
- while(key_fr_up==0)
- {
- for(i=400;i>0;i--) //设置等待自动加频率的时间
- {
- delay(50);
- if(key_fr_up==1)break;
- }
- while(key_fr_up==0) //开始自动加频率
- {
- f_data++;
- ii++;
- if(ii>4)f_data+=5;
- if(f_data>1080)f_data=875;
- T_Display();
- for(i=110;i>0;i--) //设置长时间按键
- //后,自动加数字的速度//
- {
- delay(25);
- if(key_fr_up==1)break;
- }
- }
- }
- break;
- }
- case 0x0B://频率自动减//
- {
- f_data--;
- if(f_data<875)f_data=1080;
- T_Display();
- while(key_fr_down==0)
- {
- for(i=400;i>0;i--) //设置等待自动减频率的时间
- {
- delay(50);
- if(key_fr_down==1)break;
- }
- while(key_fr_down==0) //开始自动减频率
- {
- f_data--;
- ii++;
- if(ii>4) f_data-=5;
- if(f_data<875) f_data=1080;
- T_Display();
- for(i=110;i>0;i--) //设置长时间按键后,自动减数字的速度//
- {
- delay(25);
- if(key_fr_down==1) break;
- }
- }
- }
- break;
- }
- case 0x0D: //立体声控制
- {
- if(key_LTS_KZ==0)
- {
- modo=~modo;
- LTS_LED=~modo; //打开关闭立体声
- //WriteIIC_24C01(0x02,modo);
- }
- while(key_LTS_KZ==0);
- break;
- }
- default:
- {
- key_temp=0;
- break;
- }
- }
- }
- else
- key_temp=0;
- }
- else
- key_temp=0;
- }
- //**************************初始化程序**********************************//
- void CSH (void)
- { uint i;
- CE=0;
- CLK=0;
- DA=0;
- P2=0x0F;
- P1=0x0FF; //键盘接口、扫描口、段码输出口初始化
- for(i=0;i<4;i++) //开机
- display[i]=8; //显示
- for(i=0;i<500;i++) //显示
- xianshi(); //显示8888
- f_data=875;
- modo=1;//立体声关闭
- key_temp=0;
- }
- //***************************主程序MAIN()*******************************
- //TMOD:定时/计数器方式控制寄存器
- //TH0 TL0:定时计数器0
- //TR0:定时计数器0工作启停位
- //ET0:定时计数器0允许中断位
- //EA:中断允许/禁止位
- //***********************************************************************
- main()
- {
- CSH();//开机初始化
- delay(50);
- //modo=(bit)(DataByte);
- delay(50);
- send_16data(f_data,modo); //向1415送初始数据
- //DENGDAI();
- LTS_LED=~modo; //立体声打开
- TMOD=0x01; //定时计数器0工作方式1,16位自动启动方式
- TH0=0xEA;
- TL0=0xD0;
- TR0=1;
- ET0=1;
- EA=1; //开中断
- while(1) //启动键盘处理程序,同时等待中断
- {
- KEY();
- } //启动键盘处理程序,同时等待中断
- }
- //*****************************中断服务程序******************************
- //5.424ms中断一次
- //***********************************************************************
- void t0(void) interrupt 1 using 0
- {
- ET0=0;
- if(key_temp==1)
- {
- send_16data(f_data,modo); //向BH1415F发送数据
- }
- key_temp=0;
- xianshi_turn(); //显示数据转换
- xianshi();
- key_temp=1;
- TH0=0xEA;
- TL0=0xD0;
- ET0=1;
- }
复制代码
|