📄 main.c
字号:
#include<reg52.h>
unsigned code ledmod[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,
0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x00,0x00}; //显示段代码
unsigned code ledsel[4]={0xfe,0xfd,0xfb,0xf7}; //显示位选代码
unsigned char data led[4];//显示缓冲,用于主程序和定时中断显示数据传递
sbit key_set = P3^4;//设定键
sbit key_clr = P3^5;//清除键(退出键)
sbit key_add = P3^6;//加数键
sbit key_mov = P3^7;//移位键
/****************************************************************************
* 函数原型: void function wait_5ms(void);
* 功 能: 提供5ms延时(时钟频率为12MHz)。
****************************************************************************/
void wait_5ms( void ) {
register int i ;
for ( i=0 ; i<2000 ; i++ )
;
}
/***********************************************************************/
void delay( unsigned int ki )
{for(;ki>0;ki--)
{wait_5ms();}
}
/***************************************************/
//键盘扫描程序,
//返回键值,无键按下返回0
//******************************************************/
char key(void)
{
//*********扫描set键****************************
key_set=1;wait_5ms();//把按键口线置高设为输入,延时等待稳定
if(key_set==0)//初判断
{
key_set=1;wait_5ms();
if(key_set==0);//再次确定按下
{
while(key_set==0)key_set=1;//等待按键释放
}
return 1; //返回键值
}
//*********扫描clr键****************************
key_clr=1;wait_5ms();//把按键口线置高设为输入,延时等待稳定
if(key_clr==0)//初判断
{
key_clr=1;wait_5ms();
if(key_clr==0);//再次确定按下
{
while(key_clr==0)key_clr=1;//等待按键释放
}
return 2;//返回键值
}
//*********扫描add键**********************
key_add=1;wait_5ms();//把按键口线置高设为输入,延时等待稳定
if(key_clr==0)//初判断
{
key_add=1;wait_5ms();
if(key_add==0);//再次确定按下
{
while(key_add==0)key_add=1;//等待按键释放
}
return 3; //返回键值
}
//*********扫描clr键******************************
key_mov=1;wait_5ms();//把按键口线置高设为输入,延时等待稳定
if(key_mov==0)//初判断
{
key_mov=1;wait_5ms();
if(key_mov==0); //再次确定按下
{
while(key_mov==0)key_mov=1;//等待按键释放
}
return 4;//返回键值
}
return 0;//无键按下返回0
}
// ******************************
//把dat拆成BCD码送显示缓冲
void set_disp(unsigned int dat)
{
if(dat<9999)
{
led[3]=dat/1000;dat=dat%1000;
led[2]=dat/100;dat=dat%100;
led[1]=dat/10;led[0]=dat%10;
}
}
//*****************************
//设定琐相环输出频率
void setF(unsigned int dat)
{
//使用 MOV @R0,A使PLL的分频器的分频系数高低8位数据同时输出
//最大限度降低频率设定切换过程中的影响
//参数传递时,dat的高8位在R6,低8位在R7
#pragma ASM
MOV A,R7
MOV R0,A
MOV A,R6
MOV @R0,A
#pragma endasm
}
/*================================== */
void main(void)
{
unsigned char i=0,counter,set_S=255;
unsigned int temp,tempf=500;
unsigned char data ledbuf[4];//显示缓冲备份
//counter为主程序循环次数计数器,
//set_S为当前的设定操作状态,为255时为非设定状态,为0、1、2、3时分别表示当前设定的位
//tempf为当前的频率值,
//i和temp是在程序运行时的辅助变量
TMOD=0x01;TH0=0xfe;TL0=0x18; TR0=1;ET0=1;EA=1;
//初始定时器,16位定时模式
setF(tempf);//设置PLL产生的频率
set_disp(tempf);//刷新显示
loop:
for(;;)
{
i=key();//扫描键盘
switch(i)
{
case 1 : //设定键按下
if (set_S>4)//如果原来为非设定状态
{
set_S=0;//进入设定状态
ledbuf[3]=led[3];//备份显示值,用于设定
ledbuf[2]=led[2];
ledbuf[1]=led[1];
ledbuf[0]=led[0];
}
else //如果原来为设定状态
{
temp=ledbuf[3]*1000+ledbuf[2]*100+ledbuf[1]*10+ledbuf[0]; //转换设定值
if((temp>=500)&&(temp<=1000))//判断设定值是否合法
{
tempf=temp;//记录新的频率值
setF(tempf);//设置PLL产生新的频率
}
set_disp(tempf);//刷新显示
set_S=255;//退出设定状态
}
break;
case 2 ://退出键按下
set_S=255;//退出设定状态
set_disp(tempf);//显示回原来的频率值
break;
case 3 ://加值键按下
if(++ledbuf[set_S]>9)//设定值加1并判断是否大于9,
{
ledbuf[set_S]=0;//大于9,变为0
}
break;
case 4: //移位键按下
if(++set_S>3)//指向下一位,如果超过最后一位,指回第一位
{
set_S=0;
}
break;
}
wait_5ms();
if(set_S<4)//如果处于设定状态,控制当前显示位闪烁
{
if(++counter==100)//主程序运行了一百遍,约为100个wait_5ms()的时间
{
led[set_S]=16;//不显示
}
if(counter==200)//主程序运行了2百遍,约为200个wait_5ms()的时间
{
counter=0;//重新计数
led[set_S]=ledbuf[set_S];//显示
}
}
}
goto loop;//避免程受干扰,跳出主循环
goto loop;
goto loop;
goto loop;
}
/*================TIME0显示=====================*/
void timer0 (void) interrupt 1 using 1
{static unsigned char k;//显示的位
TH0=0xfc;TL0=0x18;//重装定时值
P3=P3|0x0f; //灭显
if(k==2)//是否应该显示小数点
{
P1=ledmod[led[k]]|0x80;//送段代码并点亮小数点 (|0x80点亮小数点)
}
else
{
P1=ledmod[led[k]];//送段代码
}
P3=P3&ledsel[k];//送位选信号
k=(++k)&3;// 限制
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -