單片機源程序如下:
- #include"reg51.h"
- #include"LCD1602_elc.h"
- #include"delay_elc.h"
- //#include"time1.h"
- #include"clock.h"
-
- uint idata n=0; //計數
- uint idata num=0; //進入中斷次數的計數值,1s的次數的計數值(一次1ms,1000次為1s)
- uint idata num1=0; //0.01s(10ms)的次數的計數值
-
- void time1()
- {
- uchar set=0;
- uint sec=58; //秒
- uint min=58; //分
- uint hour=23; //時
- uint day=4; //日
- uint week=4; //周幾
- uint month=7; //月
- uint year=2019; //年
- uint time[6]={0,0,0,0,0,0};//定義一個有6個地址的數組,分別存時,分,秒的個位和十位。
- time0_init(); //初始化定時器
- LcdInit(); //顯示測試
-
-
-
-
- while (1)
- {
- if(K1==0)
- {
- delay_ms(20);
- if(K1==0)
- {
- TR0=!TR0;
- while(!K1);
- }
- }
- if(K2==0)
- {
- delay_ms(20);
- if(K2==0)
- {
- set++;
-
- if(set>7)
- {
- set=1;
- // TR0=!TR0;
- }
- while(!K2);
- }
- }
-
- if(K3==0)
- {
- delay_ms(20);
- if(K3==0)
- {
- switch(set)
- {
- case 1:hour++;
- if(hour>23)
- {
- hour=0;
- day++;
- week++;
- if(week>7)
- {
- week=1;
- }
- }
- break;
- case 2:min++;
- if(min>=60)
- {
- min=0;
- hour++;
- if(hour>23)
- {
- hour=0;
- day++;
- week++;
- if(week>7)
- {
- week=1;
- }
- }
- }
- break;
- case 3:sec++;
- if(sec>59)
- {
- sec=0;
- min++;
- if(min>59)
- {
- min=0;
- hour++;
- if(hour>23)
- {
- hour=0;
- day++;
- week++;
- if(week>7)
- {
- week=1;
- }
- }
- }
- }
- break;
- case 4:year++;
- if(year%4==0 && year%100!=0 ||year%400==0)//如果是閏年
- {
- week=week+366%7;
- if(week>7)
- {
- week=week-7;
- }
- }
- else //如果是平年
- {
- week=week+365%7;
- if(week>7)
- {
- week=week-7;
- }
- }
- break;
- case 5:month++;
- if(year%4==0 && year%100!=0 ||year%400==0) //如果是閏年
- {
- switch(month)
- {
- case 1:case 3: case 5: case 7: case 8: case 10: case 12:
- week=week+31%7;
- if(week>7)
- {
- week=week-7;
- }
- break;
- case 2:
- week=week+29%7;
- if(week>7)
- {
- week=week-7;
- }
- break;
- case 4: case 6: case 9: case 11:
- week=week+30%7;
- if(week>7)
- {
- week=week-7;
- }
- break;
- }
- }
- else
- {
- switch(month)
- {
- case 1:case 3: case 5: case 7: case 8: case 10: case 12:
- week=week+31%7;
- if(week>7)
- {
- week=week-7;
- }
- break;
- case 2:
- week=week+28%7;
- if(week>7)
- {
- week=week-7;
- }
- break;
- case 4: case 6: case 9: case 11:
- week=week+30%7;
- if(week>7)
- {
- week=week-7;
- }
- break;
- }
- }
- break;
- case 6:day++;
- week++;
- if(week>7)
- {
- week=1;
- }
- break;
- case 7:week++;
- day++;
- if(week>7)
- {
- week=1;
- }
- break;
- }
- while(!K3);
- }
- }
- if(n>=1000) //當n=1000時,表示1s到了
- {
- n=0;
- sec++; //秒加1
- if(sec>=60) //當秒滿60時,清零,分加1
- {
- sec=0;
- min++;
- if(min>=60) //當分滿60時,清零,時加1
- {
- min=0;
- hour++;
- if(hour>=24) //當時滿24時,清零
- {
- hour=0;
- day++;
- week++;
- if(week>7)
- {
- week=1;
- }
-
- }
- }
- }
-
-
- }
- time[0]=sec%10;//秒的個位
- time[1]=sec/10;//秒的十位
- time[2]=min%10;//分的個位
- time[3]=min/10;//分的十位
- time[4]=hour%10;//時的個位
- time[5]=hour/10;//時的十位 //這一步放在if(n>=1000)的外面更好
- if(year%4==0 && year%100!=0 ||year%400==0)//如果是閏年
- {
- switch(month)
- {
- case 1:case 3: case 5: case 7: case 8: case 10: case 12:
- if(day>31)
- {
- day=1;
- month++;
- if(month>12)
- {
- month=1;
- year++;
- }
- }
- break;
- case 2:
- if(day>29)
- {
- day=1;
- month++;
- if(month>12)
- {
- month=1;
- year++;
- }
- }
- break;
- case 4: case 6: case 9: case 11:
- if(day>30)
- {
- day=1;
- month++;
- if(month>12)
- {
- month=1;
- year++;
- }
- }
- }
- }
- else //如果是平年
- {
- switch(month)
- {
- case 1:case 3: case 5: case 7: case 8: case 10: case 12:
- if(day>31)
- {
- day=1;
- month++;
- if(month>12)
- {
- month=1;
- year++;
- }
- }
- break;
- case 2:
- if(day>28)
- {
- day=1;
- month++;
- if(month>12)
- {
- month=1;
- year++;
- }
- }
- break;
- case 4: case 6: case 9: case 11:
- if(day>30)
- {
- day=1;
- month++;
- if(month>12)
- {
- month=1;
- year++;
- }
- }
- }
- }
- DigDisplay(time[5],time[4],time[3],time[2],time[1],time[0],year,month,day,week);
- }
-
- }
- void secwatch1()
- {
- uint cnt=0; //1s的次數的計數值
- uint ms10=0,ms100=0; //秒的十分位,秒的百分位
- uint s,s1,min,min1,minu=0;
- //依次是秒的個位,秒的十位,分的個位,分的十位,“minu”表示分的計數位,即多少個一分鐘,一分鐘加1,
- // InitTimer0(); //初始化定時器
- time0_init(); //初始化定時器
- LcdInit(); //顯示測試
- while(1) //進入死循環
- {
- if(K1==0) //檢測啟動/暫停鍵是否按下
- {
- delay_ms(20); //延時消抖
- if(K1==0) //消抖之后再次檢測
- {
- TR0=!TR0; //定時器的控制位取反
- while(!K1); //等待按鍵釋放
- }
- }
-
- if(K2==0) //檢測復位鍵是否按下
- {
- delay_ms(20); //延時消抖
- if(K2==0) //消抖之后再次檢測
- {
- num=0;
- num1=0; //進入中斷次數值清0
- ms100=0; //百分位的計數值清0
- ms10=0; //十分位的計數值清0
- cnt=0; //秒的計數值清0
- minu=0; //分的計數值清0
- while(!K2); //等待按鍵釋放
- }
- }
- if(num1>=10) //檢測是否達到0.01s,(10個1ms)
- {
- num1=0; //進入中斷次數值清零
- ms100++; //秒的百分位的計數值加1
- if(ms100>=10) //若秒的百分位計數值達到10
- {
- ms100=0; //清零秒的百分位的計數值
- num1=0; //進入中斷次數值置0
- ms10++; //秒的十分位計數值加1
- if(ms10>=10) //若秒的十分位計數值達到10
- {
- ms10=0; //清零秒的十分位的計數值
- num1=0; //進入中斷次數值置0
- }
- }
- }
-
- if(num>=1000) //判斷計時時間是否達到1s(1000個1ms)
- {
- num=0; //進入中斷次數值置0
- cnt++; //秒的計數值加1
- if(cnt>=60) //判斷是否達到60s
- {
- cnt=0; //若達到60s,將秒的計數值置零
- minu++; //分的計數值加1
- if(minu>=60) //判斷是否達到60分鐘一般秒表是用不到60分的,這是為了程序的嚴謹性
- {
- TR0=!TR0; //達到60分鐘則關閉定時器并清零所有的計數值
- num1=0;//
- num=0;
- ms10=0;
- ms100=0;
- cnt=0;
- minu=0;
-
- }
- }
- }
- s=cnt%10; //從秒的計數值里面分離秒的個位
- s1=cnt/10; //從秒的計數值里面分離秒的十位
- min=minu%10; //從分的計數值里面分離分的個位
- min1=minu/10; //從分的計數值里面分離分的十位
-
- Display(min1,min,s1,s,ms10,ms100); //顯示這5個數
- //DigDisplay(min1,min,s1,s,ms10,ms100,0,0,0,0); //顯示這5個數
- }
- }
-
- void time0_init() //定時器初始化函數
- {
- TMOD=0x01; //選擇方式1
- TH0=0xFC; //初值為FC
- TL0=0x19; //運行值為19
- EA=1; //開總中斷
- ET0=1; //開定時器0中斷
- TR0=0; //先不打開定時器0
- }
- void timer0() interrupt 1 //定時器0中斷
- {
- TMOD=0x01; //選擇方式1
- TH0=0xFC; //重裝初值為FC
- TL0=0x19; //運行值為19
- n++;
- num++; //讓進入中斷次數值加1,用于判斷是否達到1s
- num1++; //讓進入中斷次數值加1,用于判斷是否達到0.01s
-
- }
- void DigDisplay(unsigned int a ,unsigned int b,unsigned int c,unsigned int d,unsigned int e,unsigned int f,unsigned int g,unsigned int h,unsigned int i,unsigned int j)
- {
- LCD1602_NUM(1,1,a);
- LCD1602_NUM(1,2,b);
- LCD1602_SYB(1,3,":");
- LCD1602_NUM(1,4,c);
- LCD1602_NUM(1,5,d);
- LCD1602_SYB(1,6,":");
- LCD1602_NUM(1,7,e);
- LCD1602_NUM(1,8,f); //時間顯示
- LCD1602_NUM(2,1,g);
- LCD1602_NUM(2,6,h);
- LCD1602_NUM(2,9,i);
- LCD1602_NUM(2,12,j); //日期顯示
-
- }
- void Display(unsigned int a ,unsigned int b,unsigned int c,unsigned int d,unsigned int e,unsigned int f)
- {
- LCD1602_NUM(1,1,a);
- LCD1602_NUM(1,2,b);
- LCD1602_SYB(1,3,":");
- LCD1602_NUM(1,4,c);
- LCD1602_NUM(1,5,d);
- LCD1602_SYB(1,6,":");
- LCD1602_NUM(1,7,e);
- LCD1602_NUM(1,8,f); //秒表顯示
- }
復制代碼
|