|
//該程序通過PORTB的"電平變化中斷"進(jìn)行鍵盤的輸入,使按下K1鍵時第一個數(shù)碼管顯示1,按下K2 鍵時第一個數(shù)碼管上顯示2,按下K3鍵時第一個數(shù)碼管上顯示3,按下K4鍵時第一個數(shù)碼管上顯示4對鍵盤的掃描采用中斷方式
#include "p18f458.h"
unsigned char data; unsigned int i; unsigned char j; const char table[20]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0XD8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x7f,0xbf,0x89,0xff};
void InterruptHandlerHigh(void);
/*初始化子程序*/ /* http://www.51hei.com 提供此程序*/ void initial() { INTCON=0x08; /*關(guān)閉所有中斷,B口變位中斷允許*/ INTCON2=0x01; /*使能B口弱上拉,B口變位中斷高優(yōu)先級*/ RCONbits.IPEN=1; /*使能中斷優(yōu)先級*/ TRISA=0x00; /*A口設(shè)置為輸出*/ TRISB=0XF0; /*RB1輸出,RB4輸入*/ TRISC=0x00; /*SDO引腳為輸出,SCK引腳為輸出*/ TRISE=0x00; /*E口設(shè)置為輸出*/ SSPCON1=0x30; /*SSPEN=1;CKP=1,F(xiàn)OSC/4*/ SSPSTAT=0xC0; /*時鐘下降沿發(fā)送數(shù)據(jù)*/ PIR1=0; /*清除SSPIF標(biāo)志*/ data=0X00; /*待顯示的寄存器賦初值*/ PORTBbits.RB1=0; PORTAbits.RA3=0; PORTE=0; /*將K1,K2,K3,K4四條列線置0*/ PORTB=PORTB; /*讀B口的值,為變位中斷創(chuàng)造條件*/ }
/*鍵服務(wù)子程序*/ void KEYSERVE() { PORTBbits.RB1=0; /*K1,K2置低電平,K3,K4置高電平*/ PORTAbits.RA3=0; /*RB4為0,表示按鍵為K1,K2中的一個*/ PORTE=3; /*RB4為1,表示按鍵為K3,K4中的一個*/ if(PORTBbits.RB4==0) { PORTBbits.RB1=0; /*K1置低電平,K2置高電平*/ PORTAbits.RA3=1; /*RB4為0,表示按鍵為K1;RB4為1,表示按鍵為K2*/ if(PORTBbits.RB4==0) j=0X01; else {j=0X02; PORTAbits.RA3=0;} } else { PORTEbits.RE0=0; /*K3置低電平,K4置高電平*/ PORTEbits.RE1=1; /*RB4為0,表示按鍵為K3;RB4為1,表示按鍵為K4*/ if(PORTBbits.RB4==0) j=0X03; else {j=0X04; PORTEbits.RE1=0;} } }
/*軟件延時子程序*/ void DELAY() { for(i = 6553; --i ;) continue; }
/*顯示子程序*/ void SPILED(char data) { PORTAbits.RA5=0; /*LACK送低電平,為鎖存做準(zhǔn)備*/ SSPBUF=data; /*啟動發(fā)送*/ do { ; }while(PIR1bits.SSPIF==0); /*等待發(fā)送完畢*/ PIR1bits.SSPIF=0; /*清除SSPIF標(biāo)志*/ PORTAbits.RA5=1; /*最后給鎖存信號,代表顯示任務(wù)完成*/ }
/*高優(yōu)先級中斷向量*/ #pragma code InterruptVectorHigh=0x08 void InterruptVectorHigh (void) { _asm goto InterruptHandlerHigh /*跳到中斷程序*/ _endasm }
/*高優(yōu)先級中斷程序*/ #pragma code #pragma interrupt InterruptHandlerHigh void InterruptHandlerHigh () { INTCONbits.RBIF=0; /*中斷標(biāo)志清0*/ DELAY(); /*軟件延時*/ PORTB=PORTB; /*讀PORTB的值,并改變中斷發(fā)生的條件,可屏蔽*/ /*一次按鍵松開時產(chǎn)生的無效的中斷,又可以防止按鍵*/ /*時間過長發(fā)生連續(xù)中斷*/ if(PORTBbits.RB4==0) { KEYSERVE(); /*進(jìn)行鍵盤的識別*/ PORTBbits.RB1=0; PORTAbits.RA3=0; PORTE=0; /*將K1,K2,K3,K4四條列線置0,以防止鍵掃描時改變*/ /*K1,K2,K3,K4的電平,從而改變中斷條件*/ INTCONbits.RBIF=0; /*鍵掃描時可能會產(chǎn)生"電平變化"而使置1,再清除一次*/ /*RBIF以求避免額外中斷*/ data=table[j]; /*獲得需要送出顯示的段碼*/ SPILED(data); } }
/*主程序*/ main() { initial(); /*系統(tǒng)初始化*/ INTCONbits.GIE=1; /*總中斷允許*/ while(1) { } /*等待中斷*/ }
|