记一次51单片机外部中断问题

1.起因

由于最近正在做全地形小车,为了获取小车的两个编码器电机速度,所以我便想到了使用51单片机的外部中断进行计数,于是我便操作寄存器开启了单片机的外部中断。

代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <REGX52.H>

void Ex0_Init()
{
IT0 = 1; //中断模式设置(1:下降沿触发, 0:低电平触发
EX0 = 1; //使能外部中断0
EA = 1; //开总中断
}

void Ex1_Init()
{
IT1 = 1; //中断模式设置(1:下降沿触发, 0:低电平触发
EX1 = 1; //使能外部中断1
EA = 1; //开总中断
}

2.问题

在我开启了两个中断之后,我给下降沿低电平测试,结果发现中断0可以正常工作,中断1死活不能正常工作。于是我尝试更换了单片机芯片,仍然无法解决问题,此时我便排除了芯片问题。那么下一步我便更换了51开发板,发现仍然无法解决问题。此时我便排除了板子的电路问题。

那么硬件问题全部排除,最终只剩下一种可能。便是软件问题。

3.解决

我便翻出stc89c52rc的文档,找出了中断1初始化的配置,如下:

1
2
3
4
5
6
7
8
9
10
//External interrupt service routine

void main()
{
IT1 = 1;
EX1 = 1;
EA = 1;

while(1);
}

寥寥几行代码,我复制粘贴然后尝试,仍然无法解决。

此时,我就排除了初始化函数的问题。

于是我将所有其他函数全部注释。只留下中断,发现能够正常运行!经过我的排查,在我的程序中开启了一个定时器,这个定时器隔一段时间就会运行,然后打断外部中断。

到此,问题就浮出水面。

我将外部中断初始化改为以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <REGX52.H>

void Ex0_Init()
{
IT0 = 1; //中断模式设置(1:下降沿触发, 0:低电平触发
EX0 = 1; //使能外部中断0
EA = 1; //开总中断


PX0 = 1;

}

void Ex1_Init()
{
IT1 = 1; //中断模式设置(1:下降沿触发, 0:低电平触发
EX1 = 1; //使能外部中断1
EA = 1; //开总中断


PX1 = 1;
}

代码中px1 = 1;px0 = 0;为新增代码。

这两句代码给外部中断配置了优先级,使其不被定时器中断打扰。程序正常运行!问题解决。

4.总结

在51单片机中使用多个中断时,务必考虑优先级。
在配置任何外设时,务必配置完整,使外设可控。


记一次51单片机外部中断问题
http://jiangno.com/2024/11/02/24_11_2_it_problem/
作者
江の
发布于
2024年11月2日
许可协议