|
本帖最后由 jxjie1314 于 2019-8-20 21:24 编辑
单片机小白求助高手,在网上找到的FM发射控制程序,三个独立按键分别是频率加减键与立体声开关,加减键是短按步进0.1MHz,长按自动加减,释放停止加减,刚开始是一按加减键四位数码管就显示0000,按键也同时失效,后来把消抖延时加长到8000(原300)短按加减键显示正常,可以正常加减,但是长按还是不正常,长按可以加减,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=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;
}
|
|