|
//該源程序已在實(shí)驗(yàn)板上調(diào)試通過,讀者可直接引用,并可利用軟件編程的靈活性,加以拓展,實(shí)現(xiàn)更為復(fù)雜的功能。 //此程序?qū)崿F(xiàn)計時秒表功能,時鐘顯示范圍00.00~99.99秒,分辨度:0.01秒 //定義0.01 秒、0.1 秒、1秒、10秒計時器 #include <pic.h> #include <math.h> unsigned char s0,s1,s2,s3; unsigned char s[4]; unsigned char k ,data ,sreg; unsigned int i; const table[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0XD8,0x80,0x90}; //不帶小數(shù)點(diǎn)的顯示段碼表 const table0[10]={0X40,0X79,0X24,0X30,0X19,0X12,0X02,0X78,0X00,0X10}; //帶小數(shù)點(diǎn)的顯示段碼表 //TMR0初始化子程序 void tmint() { T0CS=0; //TMR0工作于定時器方式 PSA=1; //TMR0不用分頻 T0IF=0; //清除TMR0的中斷標(biāo)志 T0IE=1; //TMR0中斷允許 } //spi顯示初始化子程序 void SPIINIT() { PIR1=0; SSPCON=0x30; SSPSTAT=0xC0; //設(shè)置SPI的控制方式,允許SSP方式,并且時鐘下降沿發(fā)送。與"74HC595,當(dāng)其 //SCLK從低到高跳變時,串行輸入寄存器"的特點(diǎn)相對應(yīng) TRISC=0xD7; //SDO引腳為輸出,SCK引腳為輸出 TRISA5=0; //RA5引腳置為輸出,輸出顯示鎖存信號 } //系統(tǒng)其它部分初始化子程序 void initial() { TRISB1=0; TRISB2=0; TRISB4=1; TRISB5=1; //設(shè)置與鍵盤有關(guān)的各口的輸入輸出方式 RB1=0; RB2=0; //建立鍵盤掃描的初始條件 } //SPI傳輸數(shù)據(jù)子程序 void SPILED(data) { SSPBUF=data; //啟動發(fā)送 do { ; }while(SSPIF==0); SSPIF=0; } //顯示子程序,顯示4位數(shù) void dispaly() { RA5=0; //準(zhǔn)備鎖存 for(k=4;k>0;k--) { data=s[k-1]; if(k==3) data=table0[data];//第二位需要顯示小數(shù)點(diǎn) else data=table[data]; SPILED(data); //發(fā)送顯示段碼 } for(k=0;k<4;k++) { data=0xFF; SPILED(data); //連續(xù)發(fā)送4個DARK,使顯示好看一些 } RA5=1; //最后給鎖存信號,代表顯示任務(wù)完成 } //軟件延時子程序 void DELAY() { for(i = 3553; --i ;) continue; } //鍵掃描子程序 void KEYSCAN() { while(1){ while(1) { dispaly(); //調(diào)用一次顯示子程序 if ((RB5==0)||(RB4==0)) break; } DELAY(); //若有鍵按下,則軟件延時 if ((RB5==0)||(RB4==0)) break;//若還有鍵按下,則終止循環(huán)掃描,返回 } } //等鍵松開子程序 void keyrelax() { while(1){ dispaly(); //調(diào)用一次顯示子程序 if ((RB5==1)&&(RB4==1)) break; } //為防止按鍵過于靈敏,每次等鍵松開才返回 } //系統(tǒng)賦值初始化子程序 void inizhi() { s0=0x00; s[0]=s0; s1=0x00; s[1]=s1; s2=0x00; s[2]=s2; s3=0x00; s[3]=s3; //s0=s1=s2=s3=0,并放入顯示緩沖數(shù)組中 sreg=0x00; //tmr0中斷次數(shù)寄存器清0 } //中斷服務(wù)程序 void interrupt clkint(void) { TMR0=0X13; //對TMR0寫入一個調(diào)整值。因?yàn)閷懭隩MR0后接著的 //兩個周期不能增量,中斷需要3個周期的響應(yīng)時間, //以及C語言自動進(jìn)行現(xiàn)場保護(hù)要消耗周期 T0IF=0; //清除中斷標(biāo)志 CLRWDT(); sreg=sreg+1; //中斷計數(shù)器加1 if(sreg==40) //中斷次數(shù)為40后,才對S0,S1,S2,S3 操作 { sreg=0; s0=s0+1; if(s0==10){ s0=0 ; s1=s1+1; if(s1==10){ s1=0 ; s2=s2+1; if(s2==10){ s2=0; s3=s3+1; if(s3==10) s3=0 ; } } } } s[0]=s0; s[1]=s1; s[2]=s2; s[3]=s3; } //主程序 main() { OPTION=0XFF; tmint(); //TMR0初始化 SPIINIT(); //spi顯示初始化 initial(); //系統(tǒng)其它部分初始化 di(); //總中斷禁止 while(1) { inizhi(); //系統(tǒng)賦值初始化 KEYSCAN(); //鍵掃描,直到開始鍵按下 keyrelax(); //等鍵松開 ei(); //總中斷允許 TMR0=0X08; KEYSCAN(); //鍵掃描直到停止鍵按下,在鍵掃描時有顯示 keyrelax() ; //等鍵松開 di(); //總中斷禁止 KEYSCAN(); //鍵掃描到清0鍵按下,在鍵掃描時有顯示 keyrelax() ; //等鍵松開 } } |