|
/************************************************************
作品名字:簡易聲光報時時鐘(12小時和24小時可轉換)
功能:六位數碼管顯示時分秒
二十四小時制和十二小時制可切換
十二小時制紅燈亮,二十四小時制紅燈滅
當時間在凌晨0點~中午12點之間時,黃燈亮,此時按切換按鍵數碼管的示數不會變化
制作說明:P0接數碼管段選,P2低6位接數碼管位
**************************************************************/
#include<reg52.h> //包含庫文件
#define uc unsigned char
#define ui unsigned int //宏定義,就是定義ui代替unsigned int,方便下面程序調用
sbit LED=P3^2;//定義LED
sbit key0=P3^3;//定義小時切換按鍵
sbit key1=P3^4;//定義調小時按鍵
sbit key2=P3^5;//定義調分鐘按鍵
sbit key3=P3^6;//定義秒清零按鍵
sbit wan=P3^7;//上下午指示燈
uc min,hour,sec,num;//分鐘,小時,秒,定時器計時變量
bit bdata zhi;//小時制標志位
uc code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};/*0,1,2,3,4,5,6,7,8,9,.*///共陰極編碼
void delay(ui x)//延時函數,大約延時1ms
{
ui i,j;
for(i=0;i<x;i++)
for(j=0;j<121;j++); //執行121次大約延時1ms
}
void display()//掃描顯示函數,高位到低位
{
P0=tab[hour/10];//小時數據是一個兩位數,除以10得到的商是十位數,然后調用數組內的對應數字的編碼賦值給P0口,顯示對應數字
P2=0xdf;//11011111 選擇對應位
delay(1);//延時
P2=0xff;//關閉位選
P0=(tab[hour%10])|0x80;//給第二位后加“點(段選接線最高位是小數點,所以就按位或0x80就是在最高位賦值1,就是顯示小數點)
P2=0xef;//11101111
delay(1);
P2=0xff;
P0=tab[min/10];
P2=0xf7;//11110111
delay(1);
P2=0xff;
P0=(tab[min%10])|0x80;//給第四位后加“點”
P2=0xfb;//11111011
delay(1);
P2=0xff;
P0=tab[sec/10];
P2=0xfd;//11111101
delay(1);
P2=0xff;
P0=tab[sec%10]; //秒數據是一個兩位數,%是取余運算,就是除以10的余數,得到個位數字
P2=0xfe;//11111110
delay(1);
P2=0xff;
}
void keyscan()//鍵盤掃描,開關接地
{
if(key0==0) //檢測到按鍵按下
{
delay(5); //延時去抖
if(key0==0) //再次判斷按鍵是否按下
{
LED=~LED; //LED取反操作
zhi=~zhi; //小時制取反
if((hour>=12)&&(zhi==0))//小時大于等于12點時,且小時制等于0,也就是12小時制
{
hour=hour-12; //將當前小時數據減12賦值給hour
}
if((zhi==1)&&(wan==1))//小時制為24小時。是下午時
{
hour=hour+12;//將小時數據加12賦值給hour
}
}
while(!key0) display();//判斷是否松開,按鍵不送開時,key0是0,取反就是1,一直成立,就一直執行后面的顯示函數,按鍵松開就跳出
}
if(key1==0) //加小時按鍵按下
{
delay(5);
if((key1==0)&&(zhi==0)) //12小時制
{
hour++; //小時加
if(hour==12) //加到12點
{
hour=0; //小時清零
wan=~wan; //切換上下午
}
}
if((key1==0)&&(zhi==1)) //24小時制
{
hour++; //小時加
if(hour==24) //加到24點
hour=0; //清零
}
while(!key1) display();//判斷是否松開
}
if(key2==0) //分加按鍵按下
{
delay(5);
if(key2==0)
{
min++; //分加
if(min==60) //加到60
min=0; //分清零
}
while(!key2) display();//判斷是否松開
}
if(key3==0)//秒清零按鍵
{
delay(5);
if(key3==0)
{sec=0;} //秒清零
while(!key3) display();//判斷是否松開
}
}
void init() //系統初始化函數
{
sec=0;//一通電,顯示12:30:00
min=30;
hour=12;
LED=1; //led點亮
zhi=1; //默認是24小時制
wan=1; //下午
TMOD=0x01;//設置定時器0工作方式1
TH0=(65536-50000)/256;
TL0=(65536-50000)%256; //定時器初值50ms
EA=1; //打開中斷總開關
ET0=1; //打開中斷允許開關
TR0=1; //打開定時開關
}
void shizhi() //小時制函數
{
if(hour>=12) //小時能加到大于12點,說明是24小時制
wan=1; //卻換到下午
if((hour<12)&&(zhi==1))//小時小于12并且是24小時制
wan=0; //切換到上午
}
void main()//主函數
{
init(); //調用初始化函數
while(1) //進入循環
{
display(); //調用顯示函數
keyscan();//掃描是否有鍵按下
shizhi(); //小時制函數
}
}
void time0() interrupt 1 //定時器0工作函數
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256; //進入中斷后重新賦初值50ms
num++; //變量加
if(num==20) //加20次就是1s
{
num=0; //變量清零
sec++; //秒變量加
if(sec==60) //秒加到60
{
sec=0; //秒清零
min++; //分加
if(min==60)//分加到60
{
min=0; //分清零
hour++;//小時加
if((hour==12)&&(zhi==0)) //小時加到12,小時制為12
{
wan=~wan; //切換上下午
hour=0; //小時清零
}
if((hour==24)&&(zhi==1)) //小時加到24,小時制為24小時制
{
hour=0; //小時清零
}
}
}
}
}
|
評分
-
查看全部評分
|