//该程序通过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.51hei.com 提供此程序*/
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)
{
} /*等待中断*/
}
上一篇:CCP1模块产生分辨率为10位的PWM波形的程序
下一篇:单片机串行口通信程序汇编语言编写
推荐阅读最新更新时间:2024-03-16 13:15
- 热门资源推荐
- 热门放大器推荐
设计资源 培训 开发板 精华推荐
- Allegro MicroSystems 在 2024 年德国慕尼黑电子展上推出先进的磁性和电感式位置感测解决方案
- 左手车钥匙,右手活体检测雷达,UWB上车势在必行!
- 狂飙十年,国产CIS挤上牌桌
- 神盾短刀电池+雷神EM-i超级电混,吉利新能源甩出了两张“王炸”
- 浅谈功能安全之故障(fault),错误(error),失效(failure)
- 智能汽车2.0周期,这几大核心产业链迎来重大机会!
- 美日研发新型电池,宁德时代面临挑战?中国新能源电池产业如何应对?
- Rambus推出业界首款HBM 4控制器IP:背后有哪些技术细节?
- 村田推出高精度汽车用6轴惯性传感器
- 福特获得预充电报警专利 有助于节约成本和应对紧急情况