|
共陽數(shù)碼管 LED指示燈共陽
W1-位1-P2.4
W2-位2-P2.7
W3-位3-P2.6
W4-位4-P2.5
數(shù)碼管段:P0口
LED指示燈陰極;P1口+P2.0--P2.3口
K1 P3.2
K2 P3.3
共陽是碼管順序:由上至下順時(shí)針 W1 a f W2 W3 b---W4 g c dp d e
制作出來的實(shí)物圖如下:
單片機(jī)源程序如下:
/***************************************************************************
數(shù)碼管的顯示 LED 個(gè)性時(shí)鐘
單片機(jī):STC12C5A60S2或STC89C52RC
調(diào)時(shí)間時(shí)按鍵有連發(fā)功能
******************************************************************************/
//頭文件:
#include "reg52.h"
#define yes 1
#define no 0
#define keyon 0 //按鍵開
#define keyoff 1 //按鍵關(guān)
#define uchar unsigned char
#define uint unsigned int
//變量定義:
unsigned char qian,bai,shi,ge;
unsigned char hour,minute,secont;
unsigned int count;
unsigned char miaocount;
code unsigned char table[]=
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//共陽數(shù)碼管
code unsigned char table1[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
//表:共陽帶點(diǎn)數(shù)碼管 0-9
code unsigned char led[]={0xff,0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe,0xf7,
0xfb,0xfd,0xfe};//LED顯示數(shù)組
#define hidden 0xff;
//引腳定義:
sbit SMG_q=P2^4; //定義數(shù)碼管陽級(jí)控制腳(千位)
sbit SMG_b=P2^7; //定義數(shù)碼管陽級(jí)控制腳(百位)
sbit SMG_s=P2^6; //定義數(shù)碼管陽級(jí)控制腳(十位)
sbit SMG_g=P2^5; //定義數(shù)碼管陽級(jí)控制腳(個(gè)位)
//KEY 調(diào)整
sbit key1=P3^2;
sbit key2=P3^3;
bit IS5ms; //5ms 標(biāo)志位
bit IS10ms;//10ms標(biāo)志位
uchar w;//定義數(shù)碼管位變量
uchar preset=100;//預(yù)設(shè)置用來調(diào)整時(shí)間的精度
/***********************************************/
void init()
{
hour=0;
minute=0; //初始時(shí)間設(shè)置
TMOD=0x11;//16位定時(shí)器0和定時(shí)器1的工作方式
TH0=(65536-10027)/256;
TL0=(65566-10027)%256; //10ms 細(xì)調(diào)
EA=1; //總中斷允許
ET0=1; //允許TMR0中斷
TR0=1; //啟動(dòng)定時(shí)器
TH1=(65536-5000)/256;
TL1=(65566-5000)%256; //5ms
ET1=1;//允許TMR1中斷
TR1=1;//啟動(dòng)TMR1
}
/***************************************************/
//顯示函數(shù),參數(shù)為顯示內(nèi)容
void display()
{
qian=hour/10; //顯示時(shí)間的千位
bai=hour%10; //顯示時(shí)間的百位
shi=minute/10; //顯示時(shí)間的十位
ge=minute%10; //顯示時(shí)間的個(gè)位
if((w==1)&&(qian==0))
{
SMG_q=1;
SMG_b=1;
SMG_s=1;
SMG_g=1;
P0=hidden; //千位是0的話進(jìn)行消隱不顯示
}else
{
SMG_q=0;
SMG_b=1;
SMG_s=1;
SMG_g=1;
P0=table[qian]; //輸出顯示內(nèi)容
}
if(w==2) //百位
{
SMG_q=1;
SMG_b=0;
SMG_s=1;
SMG_g=1;
P0=table1[bai]; //輸出顯示內(nèi)容
}
if(w==3) //十位
{
SMG_q=1;
SMG_b=1;
SMG_s=0;
SMG_g=1;
P0=table[shi]; //輸出顯示內(nèi)容
}
if(w==4) //個(gè)位
{
SMG_q=1;
SMG_b=1;
SMG_s=1;
SMG_g=0;
P0=table[ge]; //輸出顯示內(nèi)容
}
w++; //位循環(huán)顯示
if(w>4)
{
w=1;
}
}
/*******************************/
/******************************/
void timer0() interrupt 1 //定時(shí)器0中斷
{
static uchar timecount,num=0;
TH0=(65536-10027)/256;
TL0=(65566-10027)%256; //10ms
timecount++; //10MS*100=1000ms時(shí)間計(jì)數(shù)
if(timecount>=preset) //預(yù)置值
{
timecount=0; //清0時(shí)間計(jì)數(shù)
++num; //LED位數(shù)+
if(num<=8) //P1口的8位顯示
{ P2=0xff;
P1=led[num];
}else if((num>=9)&&(num<=12)) //P2口的4位顯示
{
P1=0xff;
P2=led[num];
if(num==12)
{
num=0;
}
}
if(++secont>59) //如果59秒到
{
secont=0;
minute++; //分鐘+
if(minute>59) //如果59分到
{
minute=0;
hour++; //時(shí)+
if(hour>23) //如果時(shí)間大于23點(diǎn)
{
hour=0; //重回到0
}
}
}
}
}
/***********************/
void timer1(void) interrupt 3
{
static uchar count;
TH1=(65536-5000)/256;
TL1=(65566-5000)%256; //5ms,用來進(jìn)行數(shù)碼管掃描
IS5ms=yes;
count++;
if(count==2) // 每到10MS進(jìn)行一次鍵盤掃描
{
count=0;
IS10ms=yes; //10MS到的標(biāo)志
}
}
/********************************/
uchar GetKey() //按鍵掃描函數(shù)
{
uchar keyRetu=0; //返回的按鍵值
static uchar s_keyState=0,keyTime=0; //按鍵狀態(tài),按鍵按下的時(shí)間計(jì)數(shù)器
switch (s_keyState)
{
case 0:
if(key1==keyon) //檢測(cè)到有按鍵按下,轉(zhuǎn)到狀態(tài)1,相當(dāng)于是消抖過程
{
s_keyState=1;
}
if(key2==keyon)
{
s_keyState=4;
}
break;
case 1:
if(key1==keyon) //再次檢測(cè)到有按鍵,轉(zhuǎn)到狀態(tài)2
{
s_keyState=2;
keyTime=0; //清零按鍵時(shí)間計(jì)數(shù)器
}
else
{
s_keyState=0; //沒有檢測(cè)到按鍵,說明狀態(tài)0檢測(cè)到是一個(gè)抖動(dòng),重新轉(zhuǎn)到狀態(tài)0
}
break;
case 2:
if(key1==keyoff) //檢測(cè)到按鍵松開
{
s_keyState=0; //狀態(tài)轉(zhuǎn)到狀態(tài)0
keyRetu=1; //輸出1
}
else
{
if(++keyTime>=25) //按下時(shí)間>0.5s
{
s_keyState=3; //轉(zhuǎn)到狀態(tài)3
keyTime=0; //清零按鍵時(shí)間計(jì)數(shù)器
keyRetu=1; // 輸出1
}
}
break;
case 3:
if(key1==keyoff) //檢測(cè)到按鍵松開
{
s_keyState=0; //狀態(tài)轉(zhuǎn)到狀態(tài)0
}
else
{
if(++keyTime>=10) //按下時(shí)間>0.2s
{
keyTime=0; //清零按鍵時(shí)間計(jì)數(shù)器
keyRetu=1; // 輸出1
}
}
break;
case 4:
if(key2==keyon) //再次檢測(cè)到有按鍵,轉(zhuǎn)到狀態(tài)5
{
s_keyState=5;
keyTime=0; //清零按鍵時(shí)間計(jì)數(shù)器
}
else
{
s_keyState=0; //沒有檢測(cè)到按鍵,說明狀態(tài)0檢測(cè)到是一個(gè)抖動(dòng),重新轉(zhuǎn)到狀態(tài)0
}
break;
//
case 5:
if(key2==keyoff) //檢測(cè)到按鍵松開
{
s_keyState=0; //狀態(tài)轉(zhuǎn)到狀態(tài)0
keyRetu=2; //輸出2
}
else
{
if(++keyTime>=25) //按下時(shí)間>0.5s
{
s_keyState=6; //轉(zhuǎn)到狀態(tài)6
keyTime=0; //清零按鍵時(shí)間計(jì)數(shù)器
keyRetu=2; // 輸出2
}
}
break;
//
case 6:
if(key2==keyoff) //檢測(cè)到按鍵松開
{
s_keyState=0; //狀態(tài)轉(zhuǎn)到狀態(tài)0
}
else
{
if(++keyTime>=10) //按下時(shí)間>0.2s
{
keyTime=0; //清零按鍵時(shí)間計(jì)數(shù)器
keyRetu=2; // 輸出2
}
}
break;
}
return keyRetu; //返回鍵值
}
/**********************************************/
//主函數(shù),C語言的入口函數(shù):
void main()
{
init(); //端口及定時(shí)器初始化
while(1)
//死循環(huán)
{
if(IS5ms==yes) //5MS到的標(biāo)志
{
IS5ms=no;
display(); //調(diào)用顯示函數(shù)
}
if(IS10ms==yes) //10MS到的標(biāo)志
{
IS10ms=no;
switch(GetKey()) //掃描按鍵得到鍵值
{
case 1: //鍵值處理
hour++;
if(hour>23)
{
hour=0;
}
break;
case 2: //鍵值處理
minute++;
if(minute>59)
{
minute=0;
}
break;
}
}
}
}
|
評(píng)分
-
查看全部評(píng)分
|