系列文章目录
提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
例如:
提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
了解外部中断触发方式及响应处理
样例:外部中断INT0 && INT1处理按键事件
提示:以下是本篇文章正文内容,下面案例可供参考
一、场景
样例功能:INT0按下计数+1,INT1按下计数-1,显示范围0~9999
二、编程实现
1.主函数:
开机界面显示默认初值1234,3s后进入按键检测,默认0000
变量PowerOnTimeCnt 在T0定时中断服务函数中执行++
void main()
{
INIT();
EA = 1;
while(PowerOnTimeCnt < 3000) //开机画面1234后开始显示0000,按键处理
{
P1 = 0Xfe; //test
}
while(1)
{
// ADC_Convert();
// Uart_Function();
Dis_Function();
Key_Exchange();
}
}
2.外部中断初始化
void EX0Init(void)
{
IT0 = 1; //外部中断0触发方式 0:电平触发(低电平有效)1:边沿触发(高->低负跳变)
EX0 = 1; //允许外部中断0中断
}
void EX1Init(void)
{
IT1 = 1; //外部中断1触发方式 0:电平触发(低电平有效)1:边沿触发(高->低负跳变)
EX1 = 1; //允许外部中断1中断
}
3.外部中断服务函数
void Ex0_ISR() interrupt 0
{
// fKeyEx0 = 1;
// if(vKeyEx0Cnt > 1) //消抖,有时按键检测不到
// {
// vKeyEx0Cnt = 0;
// fKeyEx0 = 0;
Delay_xms(4); //简单延时消抖
if(!KeyIn_Ex0)
{
KeyCnt_Ex++;
if(KeyCnt_Ex > 9999)
{
KeyCnt_Ex = 0;
}
}
// }
}
void Ex1_ISR() interrupt 2
{
// fKeyEx0 = 1;
// if(vKeyEx0Cnt > 1) //消抖,有时按键检测不到
// {
// vKeyEx0Cnt = 0;
// fKeyEx1 = 0;
Delay_xms(4); //简单延时消抖
if(!KeyIn_Ex1)
{
KeyCnt_Ex--;
if(KeyCnt_Ex > 9999)
{
KeyCnt_Ex = 9999;
}
}
// }
}
4.显示处理
SEG_DisBuf[0] = KeyCnt_Ex / 1000;
SEG_DisBuf[1] = KeyCnt_Ex / 100 % 10;
SEG_DisBuf[2] = KeyCnt_Ex / 10 % 10;
SEG_DisBuf[3] = KeyCnt_Ex % 10;
P.S.:若是不想显示高位的0,可以做成由高到低判断显示,如:
if(KeyCnt_Ex >= 1000)
SEG_DisBuf[0] = KeyCnt_Ex / 1000;
else
SEG_DisBuf[0] = 23; //熄灭
if(KeyCnt_Ex >= 100)
……… ………… ………
5.测试结果
总结
1.样例1中外部中断下的按键消抖一定要处理。仿真环境下不明显,实际电路下,按键按下一次会被加/减多个1。
@1@ 数码管扫描在T0定时中每1ms刷新一次,调试发现选择定时T0/T1中断服务函数中计数vKeyEx0Cnt的方法,此时无论选择延时1~10ms消抖,显示屏稳定,但是按键有时会被漏掉。怀疑是外部中断优先级最高,T0/T1未正常计数ms级,此时按键已经松开。
@2@ 样例中最终选择了占CPU时间的Delay_Xms()软件延时。缺点是按下时界面抖动,但未漏掉按键。(这里后续再优化)