|
電路原理圖如下:
51hei.png (70.26 KB, 下載次數(shù): 57)
下載附件
2022-5-15 03:52 上傳
51hei.png (40.35 KB, 下載次數(shù): 54)
下載附件
2022-5-15 03:53 上傳
- #include <reg52.h>
- #define uchar unsigned char //為宏定義,把unsigned char用uchar表示,方便書寫
- #define uint unsigned int //為宏定義,把unsigned int用uint表示,方便書寫
- void display(); //顯示函數(shù)聲明
- uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40}; //0~9,-共陰極段碼表數(shù)碼管段選編碼
- char hour =23, min =59, sec=55; //定義全局變量時分秒并賦值
- sbit addr_A=P2^0; //定義addr_A為P2口的第一位
- sbit addr_B=P2^1; //定義addr_B為P2口的第二位
- sbit addr_C=P2^2; //定義addr_C為P2口的第三位
- sbit P10 = P1^0; //定義P10為P1口的第一位
- sbit P11 = P1^1; //定義P11為P1口的第二位
- sbit P12 = P1^2; //定義P12為P1口的第三位
- sbit P13 = P1^3; //定義P13為P1口的第四位
- uchar mode = 0; //0, 1, 2, 3分別表示正常計時、調(diào)時、調(diào)分、調(diào)秒模式
- uchar flash = 0xff; //定義全局變量flash并賦值
- void delay(uint i) { //延時函數(shù)的聲明
- while(i--);
- }
- void initT0() { //初始化定時器函數(shù)聲明
- TMOD = 0x01; //計數(shù)器工作在方式一,16位計數(shù)器
- TH0 = (65536-50000)/256; //給定時器0裝初值,12MHZ晶振定時時間為50ms
- TL0 = (65536-50000)%256;
- EA =1; //開總中斷
- ET0 =1; //開定時器0分開關(guān)
- TR0 =1; //啟動定時器
- }
- void keyScan() { //鍵盤掃描函數(shù)
- static bit oldState = 1; //定義靜態(tài)局部變量,保存按鍵的舊狀態(tài),1表示按鍵彈起,0表示按鍵已按下
- if(!(P10&P11&P12&P13)) { //判斷是否可能有鍵按下
- delay(1000); //延時消抖
- if(!(P10&P11&P12&P13)) { //再次確認(rèn)當(dāng)前是否有鍵按下,且之前沒有鍵按下
- if(oldState) {
- oldState = 0; //將舊鍵狀態(tài)更新為已按下
- if(!P10) { //判斷按鍵P10是否按下
- mode++; //按下,mode模式加一
- if(mode>3) mode = 0; //判斷mode模式是否超出邊界,超出清零
- }
- else if(!P11) //判斷按鍵P11是否按下
- switch(mode) { //多分支選擇語句
- case 1:hour++;if(hour>23) hour = 0;break; //1模式下,小時加一;判斷小時是否超出邊界,超出清零;退出switch語句
- case 2:min++;if(min>59) min = 0;break; //2模式下,分鐘加一;判斷分鐘是否超出邊界,超出清零;退出switch語句
- case 3:sec++;if(sec>59) sec = 0;break; //3模式下,秒加一;判斷秒是否超出邊界,超出清零;退出switch語句
- }
- else if(!P12){ //判斷按鍵P12是否按下
- switch(mode) {
- case 1:hour--;if(hour<0) hour = 23;break; //1模式下,小時減一;判斷小時是否小于零,小于零給小時賦值23;退出switch語句
- case 2:min--;if(min<0) min = 59;break; //2模式下,分鐘減一;判斷分鐘是否小于零,小于零給分鐘賦值59;退出switch語句
- case 3:sec--;if(sec<0) sec = 59;break; //3模式下,秒減一;判斷秒是否小于零,小于零給秒賦值59;退出switch語句
- }
- //else //關(guān)閉鬧鐘
- }
- }
- }
- }
- else if(!oldState) oldState = 1; //檢測按鍵是否彈起
- }
- void main() { //主函數(shù)
- initT0(); //定時函數(shù)
- while(1){ //死循環(huán)
- keyScan(); //鍵盤掃描函數(shù)
- display(); //顯示函數(shù)
- }
- }
- void INT_T0() interrupt 1 //中斷服務(wù)程序,其中1是定時器0入口序號
- {
- static uchar counter = 0, counter_1=0; //定義靜態(tài)局部變量
- TR0 = 0; //關(guān)閉定時器
- TH0 = (65536-50000)/256; //給定時器0裝初值,12MHZ晶振定時時間為50ms
- TL0 = (65536-50000)%256;
- TR0 = 1; //啟動定時器
- counter++; //counter加一
- counter_1++; //counter_1加一
- if(counter_1==10) { //counter_1經(jīng)過0.5秒
- counter_1 = 0; //counter_1清零
- flash = ~flash; //全局變量flash按位取反
- }
- if(counter==20) { //counter經(jīng)過1秒
- counter = 0; //counter清零
- if(mode==0) sec++; //判斷模式mode是否在0模式,是,秒加一
- }
- if(sec>=60) { //判斷秒是否大于等于60
- sec = 0; //秒清零
- min++; //分加一
- }
- if(min>=60) { //判斷分鐘是否大于等于60
- min = 0; //分清零
- hour++; //小時加一
- }
- if(hour>=24) { //判斷小時是否大于等于24
- hour = 0; //給小時賦0
- }
- }
- void display() { //顯示函數(shù)
- uchar LED[8], i; //定義數(shù)組LED,局部變量i
- LED[0] = hour/10; //給數(shù)組的第一位賦值,為小時數(shù)值十位上的數(shù)
- LED[1] = hour%10; //給數(shù)組的第二位賦值,為小時數(shù)值個位上的數(shù)
- LED[2] = 10; //給數(shù)組的第三位賦值10
- LED[3] = min/10; //給數(shù)組的第四位賦值,為分鐘數(shù)值十位上的數(shù)
- LED[4] = min%10; //給數(shù)組的第五位賦值,為分鐘數(shù)值個位上的數(shù)
- LED[5] = 10; //給數(shù)組的第六位賦值10
- LED[6] = sec/10; //給數(shù)組的第七位賦值,為秒鐘數(shù)值十位上的數(shù)
- LED[7] = sec%10; //給數(shù)組的第八位賦值,為秒鐘數(shù)值個位上的數(shù)
-
- for(i=0;i<8;i++) { //FOR循環(huán),數(shù)碼管的位選
- addr_C = i/4; //最高位
- addr_B = i/2%2; //第二位
- addr_A = i%2; //最低位
- if(i==(mode-1)*3 || i==(mode-1)*3+1) P0=table[LED[i]] & flash;
- //mode 0 1 2 3 當(dāng)模式mode和i滿足關(guān)系
- //i 01 34 67 i == (mode-1)*3時
- //i == (mode-1)*3 數(shù)碼管閃爍
- else P0 = table[LED[i]]; //不滿足上述關(guān)系時,輸出數(shù)碼管的段選編碼
- delay(200); //數(shù)碼管延時
- P0 = 0X00; //數(shù)碼管消隱
- }
- }
-
復(fù)制代碼
|
評分
-
查看全部評分
|