51計算機
#include <REGX51.H> #define uchar unsigned char #define uint unsigned int #define PIN0 P0 //數碼管段選端 sbit LSA=P2^2; //38譯碼器數碼管位選 sbit LSB=P2^3; sbit LSC=P2^4; sbit beep = P1^5; sbit start=P3^2; //啟動/暫停按鈕 sbit reset=P3^3; //復位按鈕 uint cnt=0; //1s的次數的計數值 uint num=0; //進入中斷次數的計數值(一次50ms) uint num1=0; //0.1s的次數的計數值 uint num2=0; uchar code table[]={0x3f,0x06,0x5b, 0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f}; //不帶小數點的共陰極數碼管段碼0-9 uchar code table1[]={0xbf,0x86, 0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef}; //帶小數點的共陰極數碼管段碼0-9 //<spanstyle="font-size:14px;"> char code table2[]={0xc0,0xf9,0xa4, 0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //不帶小數點的共陽極數碼管段碼0-9 void Display(uint w,uint a,uint b,uintc,uint d); //聲明顯示函數 void InitTimer0(); //聲明定時器初始化函數 void Delayms(uint x); //聲明延時函數 void main() { uintms100=0;uint ms10=0; //秒的十分位 uints,s1,min,minu=0; //依次是秒的個位,秒的十位,分的個位,分的十位 InitTimer0(); //初始化定時器 while(1) //進入死循環 { if(start==0) //檢測啟動/暫停鍵是否按下 Delayms(20);//延時消抖 { if(start==0) //消抖之后再次檢測 { TR0=~TR0; //定時器的控制位取反 while(!start); //等待按鍵釋放 } } if(reset==0) //檢測復位鍵是否按下 { Delayms(20); //延時消抖 if(reset==0) //消抖之后再次檢測 { num=0; num1=0; //進入中斷次數值清0 ms100=0; ms10=0; //十分位的計數值清0 cnt=0; //秒的計數值清0 minu=0; //分的計數值清0 while(!reset); //等待按鍵釋放 } } if(num1>=2) //檢測是否達到0.1s,(兩個50ms) { num1=0; //進入中斷次數值清零 ms10++; if(num2>=20) { ms10=0; ms100++; num2=0; } //秒的十分位的計數值加1 if(ms100>=10) //若秒的十分位計數值達到10 { ms100=0; //清零秒的十分位的計數值 num1=0;//</span><spanstyle="font-size:14px;"> </span><spanstyle="font-size:14px;">//進入中斷次數值置0 } } if(num>=200) //判斷計時時間是否達到1s(20個50ms) { num=0; //進入中斷次數值置0 cnt++; //秒的計數值加1 if(cnt>=60)//判斷是否達到60s { cnt=0; //若達到60s,將秒的計數值置零 minu++; while(1) { beep=~beep; Delayms(5); } //分的計數值加1 if(minu>=60) //判斷是否達到60分鐘,</span><span style="font-family:Arial, Helvetica,sans-serif;"><span style="font-size:10px;">一般秒表是用不到60分的,這是為了程序的嚴謹性</span></span><spanstyle="font-size:14px;"> { TR0=!TR0; //達到60分鐘則關閉定時器并清零所有的計數值 num1=0;//</span><spanstyle="font-size:14px;"> </span><spanstyle="font-size:14px;"> num=0; ms100=0; cnt=0; minu=0; } } } s=cnt%10; //從秒的計數值里面分離秒的個位 s1=cnt/10; //從秒的計數值里面分離秒的十位 min=minu%10; //從分的計數值里面分離分的個位 Display(ms100,s,s1,min,ms10); //顯示這5個數 } } void InitTimer0() //定時器初始化函數 { TMOD=0x01;//選擇定時器0的工作方式1 TH0=(65536-5000)/256; //裝初值(定時50ms),晶振11.0592MHz TL0=(65536-5000)%256; EA=1; //打開總中斷 ET0=1; //打開定時器中斷 TR0=0; //先不要啟動定時器 } void TIMER0() interrupt 1 //定時器中斷服務函數 { TH0=(65536-5000)/256; //重裝初值 TL0=(65536-5000)%256; num++; //讓進入中斷次數值加1,用于判斷是否達到1s num1++; num2++; //讓進入中斷次數值加1,用于判斷是否達到0.1s } void Delayms(uint x) //延時xms { uinti,j; for(i=x;i>0;i--) for(j=110;j>0;j--); } void Display(uint w,uint a,uint b,uintc,uint d) //定義顯示函數 { LSA=0; LSB=0; LSC=0; PIN0=table[d]; Delayms(5); LSA=1;LSB=0; LSC=0;PIN0=table[w]; //秒的十分位的段選 Delayms(5); LSA=0; LSB=1; LSC=0; PIN0=table[a]; //秒的個位的段選 Delayms(5); LSA=1; LSB=1; LSC=0; PIN0=table; //秒的十位的段選 Delayms(5); LSA=0; LSB=0; LSC=1; PIN0=table[c]; //分的個位的段選(帶小數點) //分的個位的位選 Delayms(5); }
|