本文为LED-执棋困局,csdn原创首发。
> 发布人:LED-执棋困局
> 欢迎大家与LED-执棋困局相互点赞+关注+收藏+评论,也祝大家生活安康,学业愉快,工作顺利。
> 我的格言是:“尽最大努力,做最好的自己!
版权声明:本文为CSDN博主「LCD-执棋困局」的原创文章。
博主原创:LED-执棋困局
目录
一、外部中断
1.1引脚INT0、INT1
外部中断0引脚为INT0,外部中断1引脚为INT1,通常与键盘连接,键盘一端接引脚,另一端接地。
1.2外部中断初始化
外部中断初始化比较简单,通常设置EA、IT0/IT1、EX0/EX1。
打开总中断EA=1——>设置触发方式IT0/IT1——>打开外部中断允许标志位EX0/EX1=1
1.3中断服务函数
外部中断0入口编号为0,外部中断1入口编号为2。
格式:void init() interrupt n
二、按键与LED
2.1项目功能
四个按键,要求按键要与2个外部中断结合,第一个按键启动流水灯,第二个按键停止流水灯功能,第三个按键正向流水灯,第四个按键反向流水灯。
2.2仿真设计
由于只有2个外部中断,但时要用4个按键,因此可以借助外设与元件--AND_4,将4个按键先连接到AND_4,在用一根线接到外部中断0。
不论哪个按键按下,该按键左端变成低电平,与另三个按键与运算,引脚INT0变成低电平,从而触发中断(这里是因为下降沿触发方式)。
要判断具体哪个按键按下,需要接P2低4位(等效于矩阵键盘的第一列的4个按键)。
2.3代码解析
以下三个代码块均为main.c
思路:可以先将外部中断0的初始化写出来,根据流水灯要实现启动停止和正反向功能,定义启动停止标志位ledok和流水灯方向标志位updown,接着在中断服务函数中通过判断按键哪个按下来这设置两个标志位,最后书写按键功能服务函数,来实现流水灯功能。
#include <reg51.h>
#include <intrins.h>
#include "delay.h"
void init0();
void key_service();
unsigned char temp;
unsigned char ledok=0;
unsigned char updown=1;
void main()
{
init0();
temp=0xfe;
while(1)
{
key_service();
}
}
void init0()
{
IT0=1;//下降沿触发
EA=1;//总中断打开
EX0=1;//外部中断
}
void int0() interrupt 0
{
switch(P2&0x0f)
{
case 0x0e:ledok=1;break;//启动
case 0x0d:ledok=0;break;//停止
case 0x0b:updown=1;break;//正向
case 0x07:updown=0;break;//反向
default:break;
}
}
P2&0x0f:因为只接P2低4位,4个键盘都在第一列,所以只需判断第几行,就可以判断按键哪个被按下。
key_service()是按键功能服务函数,采用if嵌套来实现流水灯功能,先判断是否启动,在启动条件再判断正向还是反向。此外,还使用了库函数法,_crol_(temp,1)就是将temp对应的8位二进制向左循环移1位,比如01011100循环左移1位就是10111001;_cror_(temp,1)就是将temp对应的8位二进制向右循环移1位,比如01011100循环右移1位就是00101110。
void key_service()
{
if(ledok)
{
P1=temp;
if(updown)
{
temp=_crol_(temp,1);
}
else
{
temp=_cror_(temp,1);
}
delay(2000);
}
}
2.4项目结果
2.5扩展功能
可以将前两个按键合成一个一键二义的按键,用于控制流水灯的启动暂停,这时可以定义一个标志位并利用~运算符。
同理,可以将后两个按键合成一个一键二义的按键,用于控制流水灯的正反向,这时可以定义一个标志位并利用~运算符。
三、总结
本次项目是一个按键、外部中断、LED但又不失基础的综合项目,为接下来的学习大有裨益!
最后,LED-执棋困局希望与大家相互点赞+关注+收藏+评论,相互借鉴,相互学习,不断成长!
下一文章我们将继续介绍按键与中断的综合性项目,我们敬请期待吧!!!