/*
目标板:916U实验板STC89C52RC @ 24MHz晶振
实验内容:
▲用一个按键实现调时,并将结果显示在4个数码管上
*/
#include
//端口定义:
sbit LED1 = P1^5;//一排LED引脚定义,低电平时亮
sbit LED = P1^5; //LED引脚定义,低电平时亮
sbit Key_K14 = P3^3; //独立按键K14(P3.3/INT1),按下时为低电平
sbit speak = P3^2;
sbit dp = P0^7;
extern unsigned int t = 0;
extern unsigned int dp1 = 0; dp2 = 0;
//4个共阳数码管显示驱动引脚定义
#define SegDispPort P0 //数码管各段驱动端口,低电平亮
sbit SegDispCom1 = P2^6; //第1个数码管公共端,低电平亮
sbit SegDispCom2 = P2^5; //第2个数码管公共端,低电平亮
sbit SegDispCom3 = P2^4; //第3个数码管公共端,低电平亮【倒置】
sbit SegDispCom4 = P2^3; //第4个数码管公共端,低电平亮【倒置】
//数码显示译码表,有小数点
const unsigned char NumTable[16]={ //共阳,0~F,无小数点
0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E} ;
const unsigned char NumTableDown[16]={ //倒置,共阳,0~F,有小数点
0xC0,0xCF,0xA4,0x86,0x8B,0x92,0x90,0xC7,0x80,0x82,
0x81,0x98,0xF0,0x8C,0xB0,0xB1};
unsigned char SegDispBuffer[4]= {0,0,0,0}; //四联体数码显示缓存
unsigned int nCounter=0; //计数值
unsigned int nTemp; //临时变量
//函数申明
void delay(unsigned int n);
void SegDispDynamic(void);
void Key_Scan_0(void);
//主程序
void main()
{
while(1) //主循环
{
SegDispDynamic(); //数码管动态扫描显示
Key_Scan_0(); //按键扫描
}
}
//按键扫描子程序
void Key_Scan_0(void)
{
#define keypad_0 Key_K14 //定义端口
#define keypad_0_DOWN 0 //定义按键"按下"时的电平
#define keypad_0_UP 1 //定义按键"释放"时的电平
static unsigned char mKey0SwapTask=0; //定义按键过程状态标记
switch(mKey0SwapTask) //按键iKey7检测mKey0SwapTask:按键过程状态标记
{
case 0: //有按键按下吗?
if(keypad_0==keypad_0_DOWN)
{
mKey0SwapTask=1;
}
break;
case 1: //键按下去抖延时
mKey0SwapTask=2; //延时一个系统时间
break;
case 2: //键值判断
if(keypad_0==keypad_0_DOWN)//"按下"有效
{
//////////////////////////////////////////
//这里执行按键"按下"时要做的事情
LED = 0; //LED灯亮
t =1;
mKey0SwapTask=3;
}
else mKey0SwapTask=0; //抖动
break;
case 3: //有松开吗?
if(keypad_0==keypad_0_UP)//判断按键是否松开
{
mKey0SwapTask=4;
}
//////////////////////////////////////////
t = 0;
speak = 0;//这里执行按键"按住"时要做的事情
//////////////////////////////////////////
break;
case 4: //键松开去抖延时
mKey0SwapTask=5; //延时一个系统时间break;
case 5: //键值判断
if(keypad_0==keypad_0_UP) //"释放"有效
{
//////////////////////////////////////////
//这里执行按键"释放"时要做的事情
LED = 1; //LED灯灭
speak = 1;
//////////////////////////////////////////
mKey0SwapTask=0; //去按键检测开始}
else mKey0SwapTask=3; //抖动
break;
default:
mKey0SwapTask = 0;
}
}
//数码管动态扫描显示
void SegDispDynamic(void)
{
static unsigned char index = 1 ; //扫描到的数码管编号
static unsigned int time = 1;
const unsigned int cntDelay = 2; //扫描演示时间, ms
static unsigned int nCounter = 20*60+35;//程序校时
if((time*cntDelay)%49000==0||t==1)//一分钟走的时间
{
nCounter++;
if(nCounter>1440)
{
nCounter=0;
}
if(nCounter%60==0)
{
speak = 0;一小时响一次
}
//转换成十进制,显示
nTemp = nCounter;
SegDispBuffer[0] = nTemp/600;
nTemp %= 600;
SegDispBuffer[1] = nTemp/60;
nTemp %=60;
SegDispBuffer[2] = nTemp/10;
nTemp %= 10;
SegDispBuffer[3] = nTemp;
}
switch(index)
{
case 1: //第1位有效
SegDispCom1 = 0;
SegDispPort = NumTable[SegDispBuffer[0]]; //正常译码
delay(cntDelay);
SegDispCom1 = 1;
break;
case 2: //第2位有效
SegDispCom2 = 0;
SegDispPort = NumTable[SegDispBuffer[1]]; //正常译码
dp = dp1;
delay(cntDelay);
SegDispCom2 = 1;
break;
case 3: //第3位有效
SegDispCom3 = 0;
SegDispPort = NumTableDown[SegDispBuffer[2]]; //倒置译码
dp = dp2;
delay(cntDelay);
SegDispCom3 = 1;
break;
case 4: //第4位有效
SegDispCom4 = 0;
SegDispPort = NumTableDown[SegDispBuffer[3]]; //倒置译码
delay(cntDelay);
SegDispCom4 = 1;
break;
default:
index=1;
break;
}
index++; //指向下一个数码
if(index>4)
{
index = 1; //返回到第一个数码管
}
time++;
if(time%250==0)
{
LED1 = 1;
dp1=!dp1;//冒号闪烁
dp2=!dp2;
speak = 1;
}
if(time==24501)
{
LED1 = 0;
time = 1;
}
}
//延时子程序,约1ms * n
void delay(unsigned int n)
{
unsigned int i,j;
for(i=0;i