//該程序通過PORTB的"電平變化中斷"進行鍵盤的輸入,使按下K1鍵時第一個數碼管顯示1,按下K2
//鍵時第一個數碼管上顯示2,按下K3鍵時第一個數碼管上顯示3,按下K4鍵時第一個數碼管上顯示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.zg4o1577.cn 提供此程序*/
void initial()
{
INTCON=0x08; /*關閉所有中斷,B口變位中斷允許*/
INTCON2=0x01; /*使能B口弱上拉,B口變位中斷高優先級*/
RCONbits.IPEN=1; /*使能中斷優先級*/
TRISA=0x00; /*A口設置為輸出*/
TRISB=0XF0; /*RB1輸出,RB4輸入*/
TRISC=0x00; /*SDO引腳為輸出,SCK引腳為輸出*/
TRISE=0x00; /*E口設置為輸出*/
SSPCON1=0x30; /*SSPEN=1;CKP=1,FOSC/4*/
SSPSTAT=0xC0; /*時鐘下降沿發送數據*/
PIR1=0; /*清除SSPIF標志*/
data=0X00; /*待顯示的寄存器賦初值*/
PORTBbits.RB1=0;
PORTAbits.RA3=0;
PORTE=0; /*將K1,K2,K3,K4四條列線置0*/
PORTB=PORTB; /*讀B口的值,為變位中斷創造條件*/
}
/*鍵服務子程序*/
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送低電平,為鎖存做準備*/
SSPBUF=data; /*啟動發送*/
do
{
;
}while(PIR1bits.SSPIF==0); /*等待發送完畢*/
PIR1bits.SSPIF=0; /*清除SSPIF標志*/
PORTAbits.RA5=1; /*最后給鎖存信號,代表顯示任務完成*/
}
/*高優先級中斷向量*/
#pragma code InterruptVectorHigh=0x08
void InterruptVectorHigh (void)
{
_asm
goto InterruptHandlerHigh /*跳到中斷程序*/
_endasm
}
/*高優先級中斷程序*/
#pragma code
#pragma interrupt InterruptHandlerHigh
void InterruptHandlerHigh ()
{
INTCONbits.RBIF=0; /*中斷標志清0*/
DELAY(); /*軟件延時*/
PORTB=PORTB; /*讀PORTB的值,并改變中斷發生的條件,可屏蔽*/
/*一次按鍵松開時產生的無效的中斷,又可以防止按鍵*/
/*時間過長發生連續中斷*/
if(PORTBbits.RB4==0)
{
KEYSERVE(); /*進行鍵盤的識別*/
PORTBbits.RB1=0;
PORTAbits.RA3=0;
PORTE=0; /*將K1,K2,K3,K4四條列線置0,以防止鍵掃描時改變*/
/*K1,K2,K3,K4的電平,從而改變中斷條件*/
INTCONbits.RBIF=0; /*鍵掃描時可能會產生"電平變化"而使置1,再清除一次*/
/*RBIF以求避免額外中斷*/
data=table[j]; /*獲得需要送出顯示的段碼*/
SPILED(data);
}
}
/*主程序*/
main()
{
initial(); /*系統初始化*/
INTCONbits.GIE=1; /*總中斷允許*/
while(1)
{
} /*等待中斷*/
}