中断是一种机制,通过该机制,I / O或指令可以挂起处理器的正常执行,并像最高优先级一样为自己提供服务。例如,执行正常执行的处理器也可以连续监视某种事件或发生的中断。就是说,当发生外部中断(例如来自某个传感器的中断)时,处理器暂停其正常执行并首先处理该中断,然后继续其正常执行。
在此项目中,为了理解STM32F103C8中的中断,我们将按钮用作外部中断。在这里,我们将从0开始递增一个数字,并将其显示在16x2 LCD上,每按一下按钮,LED就会亮起,并且LCD显示屏上会显示INTERRUPT(中断)。释放按钮后,LED就会熄灭。
中断类型和ISR
中断可以大致分为两种类型:
硬件中断: 如果发给处理器的信号是从某个外部设备(例如按钮或传感器)发出的,或者是从其他一些产生信号并告诉处理器执行ISR中特定任务的硬件设备发出的,则称为硬件中断。
软件中断:由软件指令生成的中断。
中断服务程序
中断服务程序或中断处理程序是其中包含少量指令集的事件,并且在发生中断时,处理器首先执行ISR中存在的这些代码,然后继续执行中断之前执行的任务。
STM32中中断的语法
ISR在Arduino中具有以下语法AttachInterrupt(digitalPinToInterrupt(pin),ISR,模式),并且在STM32中也可以使用,因为我们使用arduino IDE上载代码。
- digitalPinToInterrupt(pin):像在Arduino开发板上的Uno一样,我们有2,3引脚,而在mega中,我们有2,3,18,19,20,21个中断。在STM32F103C8中,我们还具有中断引脚,任何GPIO引脚均可用于中断。我们只需要指定用于中断的输入引脚即可。但是,当同时使用多个中断时,我们可能需要遵循一些限制。
- ISR:它是一个中断处理程序函数,在发生外部中断时调用。它没有参数,并且返回类型无效。
- 模式:触发中断的过渡类型
- 上升:当引脚从低电平转变为高电平时触发中断。
- 下降:当引脚从高电平转换为低电平时触发中断。
- CHANGE(更改):当引脚从LOW转变为HIGH或从HIGH转变为LOW时(即,当引脚改变时)触发中断。
使用中断时的一些条件
- 中断服务程序功能(ISR)必须尽可能短。
- 延迟()函数在ISR内部不起作用,应避免使用。
所需组件
- STM32F103C8
- 按钮
- LED
- 电阻(10K)
- 液晶屏(16x2)
电路图和连接
按钮引脚的一侧连接到STM32的3.3V,另一侧通过下拉电阻连接到STM32的输入引脚(PA0)。
使用下拉电阻,以便在按下或释放按钮时,微控制器的输入只会变为高电平或低电平。否则,在没有下拉电阻的情况下,MCU可能会产生混淆,并将一些随机浮点值馈送到输入端。
STM32F103C8和LCD之间的连接
下表显示了LCD(16X2)与STM32F103C8微控制器之间的引脚连接。
STM32F103C8 |
液晶屏 |
地线 |
VSS |
+5伏 |
VDD |
至电位计中心PIN |
V0 |
PB0 |
RS |
地线 |
读写器 |
PB1 |
Ë |
PB10 |
D4 |
PB11 |
D5 |
PC13 |
D6 |
PC14 |
D7 |
+5伏 |
一种 |
地线 |
ķ |
编程STM32F103C8进行中断
本教程的程序很简单,并在本教程的结尾给出。我们不需要FTDI程序员来对STM32进行编程,只需将您的PC连接到STM32的USB端口即可开始使用Arduino IDE进行编程。了解有关通过USB端口编程STM32的更多信息。
正如我们在本教程中所说的那样,我们将从0开始递增一个数字,并将其显示在16x2 LCD上,每按一次按钮,LED就会亮起,并且LCD显示屏会显示“ INTERRUPT”(中断)。
首先 定义与STM32的LCD引脚连接。您可以根据需要对其进行修改。
const int rs = PB10,en = PB11,d4 = PB0,d5 = PB1,d6 = PC13,d7 = PC14;
接下来,我们 包括 LCD显示器的头文件。这将调用该库,其中包含STM32如何与LCD通信的代码。还要确保使用上面刚刚定义的引脚名称调用了 LiquidCrystal 函数。
包括
全局变量用于在ISR和主程序之间传递数据。我们将变量 ledOn 声明为volatile,也声明为Boolean以指定True或False。
volatile布尔值ledOn = false;
在 void setup() 函数内部,我们将显示介绍性消息,并在2秒钟后清除它。
lcd.begin(16,2); lcd.print(“电路图摘要”); delay(2000); lcd.clear();
同样在相同的 void setup() 函数中,我们需要指定输入和输出引脚。我们将引脚PA1设置为输出到LED,将PA0设置为从按钮输入。
pinMode(PA1,输出) pinMode(PA0,输入)
我们还将增加一个数字,因此声明一个值为零的变量。
int i = 0;
现在代码的重要部分是 attachInterrupt() 函数,它也包含在 void setup()中
attachInterrupt(digitalPinToInterrupt(PA0),buttonPressed,更改)
我们将 PA0 引脚指定为外部中断,而 buttonPressed 是当PA0引脚发生变化(从低到高或从高到低)时调用的功能。您还可以根据需要使用任何其他功能名称,引脚和模式。
在 void loop() 内部,我们从零开始增加一个数字(i),并在LCD(16x2)中打印该数字。
lcd.clear(); lcd.print(“ NUMBER:”); lcd.print(i); ++ i; 延迟(1000);
最重要的部分是根据在 attachInterrupt() 函数中使用的名称创建一个中断处理程序函数。我们使用了 buttonPressed, 因此在这里我们创建了一个函数 void buttonPressed()
void buttonPressed() { if(ledOn) { ledOn = false; digitalWrite(PA1,LOW); } else { ledOn = true; digitalWrite(PA1,HIGH); lcd.setCursor(0,1); lcd.print(“ Interrupt”); } }
此 buttonPressed() ISR的工作:
根据 ledOn 变量的值,LED点亮和熄灭。
按钮状态 |
ledOn(值) |
LED(红色) |
液晶屏(16x2) |
未压缩 |
假 |
关 |
-- |
按下 |
真正 |
上 |
显示“ INTERRUPT” |
如果 ledOn 值为false,则LED保持熄灭;如果 ledOn 值为True,则LED点亮,并且LCD显示屏上显示“ Interrupt”(中断)。
注意:有时可能会产生开关反跳效果,并且按下按钮时可能会触发多次触发,这是因为由于切换按钮的机械原因而产生了多个电压尖峰。可以通过引入RC滤波器来减少这种情况。
以下视频 显示了STM32F103C8中中断的完整 工作 。