給你一個電路和程序,完全滿足你的要求,共陽數碼管,實際電路Q2、Q3要用PNP管才合理,位選a、b對調。圖中用NPN管只是為了仿真。#include <reg51.h>
#define uint unsigned int
#define uchar unsigned char
#define key_S 300 //宏定義短按(約20ms)
#define key_L 6000 //宏定義長按(約2/3s)
#define key_M 3000 //宏定義長按(約1/3s)
sbit K1 = P1^1; //定時設置端口
sbit OUT= P1^0; //輸出端口
sbit b=P3^1; //位選b端口
sbit a=P3^0; //位選a端口
uchar code table[]={ //共陽數碼管段碼0~f
0xc0,0xf9,0xa4,0xb0,
0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,
0xc6,0xa1,0x86,0x8e};
uint Cnt2ms=0; //定義2ms秒變量
uchar hour=8,min=59,sec=59; //定義時、分、秒變量
bit Twinkle; //閃爍標志
bit flag=0; //2ms數碼管動態顯示標志
bit Back=1; //倒計時標志
/***************************************
定時器T0/T1初始化程序 @11.0592MHz
***************************************/
void Timer_Init()
{
TMOD = 0x01; //設置T0模式1,T1模式2
TL0 = 0xCD; //設置定時初值2ms
TH0 = 0xF8; //設置定時初值2ms
TR0 = 1; //定時器0開始計時
EA=1; //開總中斷
ET0=1; //開定時器1中斷
}
/*************************
按鍵掃描程序
*************************/
void key_scan()
{
static uint count;//消抖計數變量
if(!K1)
{
count++;
if(count>=key_L) //長按快調
{
hour++;
if(hour>=25)
hour=0;
count=key_M;
}
}
else //按鍵抬起
{
if(count>key_S && count<key_L)//短按
{
hour++;
if(hour>=25)
hour=0;
}
count=0; //count清0
}
}
/********************************
數碼管顯示程序
********************************/
void display()
{
static uchar num=0; //分時顯示變量
if(flag==1)
{
flag=0;
switch(num)
{
case 0:
P2=0xff; //消隱
a=1;b=0; //時十位位碼
if(Back==0) P2=0xbf; //顯示"-"
else P2=table[hour/10]; //時十位段碼
num++;
break;
case 1:
P2=0xff; //消隱
a=0;b=1; //時個位位碼
if(Back==0) P2=0xbf; //顯示"-"
else
{
if(Twinkle==1) //時點閃爍
P2=table[hour%10]+0x80;//時個位段碼+點
else
P2=table[hour%10];
}
num=0;
break;
}
}
}
/********************************
主程序
********************************/
void main(void)
{
Timer_Init(); //初始化定時器
OUT=1; //加電輸出
while(1)
{
key_scan(); //按鍵掃描
display(); //顯示
if(hour==0)
{
OUT=0; //停止輸出
Back=0; //倒計時標志清0
}
else
{
OUT=1; //輸出
Back=1; //倒計時標志置1
}
}
}
/*-----------------------------
定時器0中斷服務程序 2m秒
------------------------------*/
void timer0() interrupt 1
{
TL0 = 0xCD; //設置定時初值2ms
TH0 = 0xF8; //設置定時初值2ms
flag=1;
if(Back==1)
{
Cnt2ms++; //時間變量Cnt2ms自+1
if(Cnt2ms<125) //閃爍頻率1Hz
Twinkle=1; //閃爍標志
else Twinkle=0;
if(Cnt2ms>=500) //在此可以調整精度
{
Cnt2ms=0; //變量Cnt2ms清0
sec--; //秒自-1
if(sec>=60) //如果秒>=60
{
sec=59; //秒清0
min--; //分自-1
if(min>=60) //分>=60
{
min=59; //分清0
hour--; //小時自-1
if(hour>=25) //小時>=25
hour=24; //小時清0
}
}
}
}
}
無標題.jpg (179.61 KB, 下載次數: 34)
下載附件
2018-3-6 14:40 上傳
|