希望能給大家提供經驗,51單片機做的狀態機應用程序的電子表
0.png (23.45 KB, 下載次數: 58)
下載附件
2016-10-30 21:25 上傳
- #include <REGX51.H>
- #include <intrins.h>
- typedef unsigned char uint8;
- #define NT 29
- const uint8 THH=(65536-2000+NT)/256;
- const uint8 TLL=(65536-2000+NT)%256;
- uint8 code SEG7CC[]={0x3F,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x0};
- uint8 volatile LED[]={2,3,5,9,5,0};
- volatile uint8 hour=23;
- volatile uint8 minute=59;
- volatile uint8 sec=50;
- volatile uint8 mode=0;
- volatile uint8 isAddPush=0;
- void timeDly(unsigned int n);
- void tickProc();
- void main()
- {
- //char i,temp;
- EA=1; //總中斷開關
- ET0=1; //分中斷開關
- TMOD = 1; //設置為 16 位定時器模式。
- TR0=1; //啟動定時器 T0
- ET1=1;
- TR1=1;
- TMOD |= 0x10; //不更改原先的代碼
- PT0 =1;//時間的刷新比按鍵更重要
- PT1 =1;// 時間的刷新比按鍵更重要
- EX0=1;
- EX1=1;
- IT0=1;
- IT1=1;
- while(1)
- {
- tickProc();
-
- }
- } void tickProc()
- { static uint8 N=0;//記錄調用次數,實現閃爍
- switch(mode)
- {
- case 0://正常運行模式下,N 不變,秒定時器運行
- TR1 =1;
- break;
- case 1://模式 1 下,小時閃
- TR1 =0;
- N++;
- if(isAddPush)//如果有加鍵按下,小時加
- { if(++hour>23) hour=0;
- isAddPush=0;
- }
- if(N%2==0) //N 為偶數,小時數字滅
- {
- LED[0]=10;
- LED[1]=10;
- }
- else //N 為奇數,小時恢復正常數字,實現閃爍
- {
- LED[0]=hour/10;
- LED[1]=hour%10;
- }
- timeDly(500);
- break;
- case 2:
- TR1 =0;
- N++;
- if(isAddPush)
- { if(++minute>59) minute=0; isAddPush=0; }
- if(N%2==0)
- { LED[2]=10; LED[3]=10; }
- else
- { LED[2]=minute/10; LED[3]=minute%10; }
- timeDly(500);
- break;
- case 3:
- TR1 =0;
- N++;
- if(isAddPush)
- { if(++sec>59) sec=0; isAddPush=0; }
- if(N%2==0)
- { LED[4]=10; LED[5]=10; }
- else
- {
- LED[4]=sec/10; LED[5]=sec%10;
- }
- timeDly(500);
- break;
- default: mode=0;//增強抗干擾能力
- }
- }
- void int0ISR()interrupt 0
- { timeDly(10);//消除抖動
- IE0 =0;//二次進入同類中斷,中斷標志位會保留,防止處理 2 次。
- if(P3_2) return;//松開按鍵,后邊沿,不處理
- if(++mode>3) mode=0;
- LED[0]=hour/10; //模式變后,閃的位置也會變,要重置正常顯示情況
- LED[1]=hour%10;
- LED[2]= minute/10;
- LED[3]= minute%10;
- LED[4] = sec/10;
- LED[5] = sec%10; }
- void int1ISR() interrupt 2
- { timeDly(10);
- IE1 =0;
- if(P3_3) return;
- isAddPush=1;//有按鍵則置位標志位,這個處理較為復雜,在主循環中處理。
- }
-
- void timeDly(unsigned int n)
- {
- unsigned int i;
- for(; n>0; n--)
- for(i=123; i>0; i--);
- }
- void t1ISR() interrupt 3
- {
- static uint8 N=0;//記錄中斷次數
- TH1 = (65536-62500)/256;
- TL1 = (65536-62500)%256;
-
- if(++N>=16)
- {
- N=0;
- ET0 =0;//時分秒比顯示定時刷新重要,暫時先關刷新中斷
- if(++sec>59)
- {
- sec=0;
- if(++minute>59)
- {
- minute =0;
- if(++hour>23)
- hour=0;
- }
- }
- LED[0]=hour/10;//時分秒有改變,重置顯示緩沖區
- LED[1]=hour%10;
- LED[2]= minute/10;
- LED[3]= minute%10;
- LED[4] = sec/10;
- LED[5] = sec%10;
-
- ET0 =1;
- }
- }
- void t0ISR() interrupt 1
- {
- static uint8 N=0;
-
- switch(N)
- {
- case 0:
- P2 = (1<<5);
- P1 = SEG7CC[ LED[5]];
- break;
- case 1:
- P2 = (1<<4);
- if(LED[4]!=0)
- P1 = SEG7CC[ LED[4]];
- else
- P1 = SEG7CC[10];//秒高位為 0,則不顯示
- break;
- case 2:
- P2 = (1<<3);
- P1 = SEG7CC[ LED[3]];
- if(mode==0) //如果是正常顯示,則將這個位置的小數點點亮
- P1 = SEG7CC[ LED[3]] | 0x80;
- break;
- case 3:
- P2 = (1<<2);
- if(LED[2]!=0)
- P1 = SEG7CC[ LED[2]];
- else
- P1 = SEG7CC[10];//分鐘高位為 0,則不顯示
- break;
- case 4:
- P2 = (1<<1);
- P1 = SEG7CC[ LED[1]];
- if(mode==0) //如果是正常顯示,則將這個位置的小數點點亮
- P1 = SEG7CC[ LED[1]] | 0x80;
- break;
- case 5:
- P2 = 1;
- if(LED[0]!=0)
- P1 = SEG7CC[LED[0]];
- else
- P1 = SEG7CC[10];//小時高位為 0,則不顯示
- break;
- default:
- N=0;//出錯,令 N 歸零。
- }
- if(++N>5) N=0;
- TH0 = THH;
- TL0 = TLL;
-
- }
復制代碼
0.png (73.73 KB, 下載次數: 55)
下載附件
2016-10-30 21:25 上傳
所有資料打包下載:
新建文件夾.rar
(51.65 KB, 下載次數: 14)
2016-10-30 20:29 上傳
點擊文件名下載附件
不錯哦! 下載積分: 黑幣 -5
|