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