如何在STM32F103C8中使用中断

描述

中断是一种机制,通过该机制,I/O 或指令可以暂停处理器的正常执行,并像具有最高优先级一样为自己提供服务。例如,执行正常执行的处理器也可以持续监视某种事件或中断的发生。也就是说,当发生外部中断(例如来自某些传感器)时,处理器暂停其正常执行并首先提供中断,然后继续其正常执行。

在本项目中,为了理解STM32F103C8中的中断,我们将使用按钮作为外部中断。在这里,我们将从 0 开始递增一个数字并将其显示在 16x2 LCD 上,每当按下按钮时,LED 就会亮起,LCD 显示屏就会显示中断。松开按钮后,LED 立即熄灭。

中断和 ISR 的类型

中断大致可分为两种类型:

硬件中断:如果发给处理器的信号来自某些外部设备(如按钮或传感器)或来自某些其它硬件设备,则其产生信号并告诉处理器执行ISR中存在的特定任务称为硬件中断。

软件中断:由软件指令生成的中断。

中断服务例程

中断服务例程或中断处理程序是包含一小组指令的事件,当发生中断时,处理器首先执行 ISR 中存在的这些代码,然后继续执行中断前正在执行的任务。

STM32中断的语法

ISR在Arduino中具有以下语法attachInterrupt(digitalPinToInterrupt(pin),ISR,mode),并且在STM32中也可以使用相同的语法,因为我们使用arduino IDE上传代码。

数字引脚到中断(引脚):就像在Arduino板Uno中一样,我们有引脚2,3,在mega中我们有2,3,18,19,20,21用于中断。在STM32F103C8中,我们也有中断引脚,任何GPIO引脚都可用于中断。我们只是指定用于中断的输入引脚。但是,在同时使用多个中断时,我们可能需要遵循一些限制。

ISR:它是发生外部中断时调用的中断处理程序函数。它没有参数和 void 返回类型。

模式:触发中断的转换类型

上升:当引脚从低电平转换到高电平时触发中断。

下降:当引脚从高电平转换到低电平时触发中断。

更改:当引脚从低电平转换到高电平或从高电平转换到低电平时(即,当引脚变化时),触发中断。

使用中断时的一些条件

中断服务例程功能 (ISR) 必须尽可能短。

延迟 () 函数在 ISR 中不起作用,应避免使用。

所需组件

STM32F103C8

按钮

发光二极管

电阻器 (10K)

液晶显示器 (16x2)

电路图和连接

中断

按钮引脚的一侧通过下拉电阻连接到STM32的3.3V,另一侧通过下拉电阻连接到STM32的输入引脚(PA0)。

使用下拉电阻,以便微控制器仅在按下或松开按钮时在其输入端获得高电平或低电平。否则,如果没有下拉电阻,MCU可能会感到困惑,并向输入提供一些随机浮动值。

中断

STM32F103C8与液晶显示器之间的连接

下表显示了LCD(16X2)和STM32F103C8微控制器之间的引脚连接。

 

STM32F103C8 液晶显示器
接地 VSS
(55 电压输出
前往电位计中心引脚 V0
PB0 RS
接地 乌尔曼
PB1 E
PB10 D4
PB11 D5
电脑13 D6
电脑14 D7
(55 一个
接地 K

 

中断

对STM32F103C8进行中断编程

本教程的程序很简单,在本教程结束时给出。我们不需要FTDI编程器来编程STM32,只需将PC连接到STM32的USB端口,然后使用Arduino IDE开始编程。了解有关通过USB端口对STM32进行编程的更多信息。

正如我们在本教程中所说,我们将从 0 递增一个数字并将其显示在 16x2 LCD 上,每当按下按钮时,LED 就会亮起,LCD 显示屏显示“中断”。

首先使用STM32定义LCD引脚连接。您可以根据需要对其进行修改。

const int rs= PB10,en= PB11,d4= PB0,d5= PB1,d6= PC13,d7= PC14;    

接下来,我们包括LCD显示器的头文件。这将调用包含STM32如何与LCD通信的代码的库。还要确保使用我们上面刚刚定义的引脚名称调用函数 LiquidCrystal。

include                                         

LiquidCrystal lcd (rs,en,d4,d5,d6,d7);          

全局变量用于在 ISR 和主程序之间传递数据。我们将变量 ledOn 声明为易失性,也声明为布尔值以指定 True 或 False。

volatile boolean ledOn = false;

在 void setup() 函数中,我们将显示一条介绍消息并在 2 秒后清除它。

lcd.begin(16,2);                                                

lcd.print("CIRCUIT DIGEST");                                   

delay(2000);                                                   

lcd.clear();     

同样在相同的void设置()函数中,我们需要指定输入和输出引脚。我们将引脚 PA1 用于输出设置为 LED,将 PA0 设置为按钮输入。

pinMode(PA1,OUTPUT)

pinMode(PA0,INPUT)

我们还将增加一个数字,因此声明一个值为零的变量。

int i = 0;

现在代码的重要部分是attachInterrupt()函数,它也包含在 void setup() 中

attachInterrupt(digitalPinToInterrupt(PA0),buttonPressed,CHANGE)

我们为外部中断指定了引脚PA0,按钮按下是当PA0引脚中存在变化(从低到高或从高到低)时要调用的函数。您还可以根据需要使用任何其他功能名称、引脚和模式。

在 void loop() 中,我们从零递增一个数字 (i),并在 LCD(16x2) 中打印该数字。

lcd.clear();                                                    

lcd.print("NUMBER:");                                           

lcd.print(i);                  

++i;                                                           

delay(1000);   

最重要的部分是根据我们在 attachInterrupt() 函数中使用的名称创建一个中断处理程序函数。我们使用了buttonPress,所以这里我们创建了一个函数 void buttonPressed()

void buttonPressed()                                              

{                   

if(ledOn)                                                       

{

ledOn=false;                                                

digitalWrite(PA1,LOW);                                       

}

else

{

ledOn = true;                                                

digitalWrite(PA1,HIGH);                                     

lcd.setCursor(0,1);                                          

lcd.print("Interrupt");                                      

}

}

此按钮的工作按下()ISR:

根据 ledOn 变量的值,LED 打开和关闭。

 

按钮状态 发光二极管(值) 指示灯(红色) 液晶显示器(16x2)
无压 关闭 -
显示“中断”

 

如果 ledOn 值为假,则 LED 保持关闭状态,如果 ledOn 值为真,则 LED 亮起,LCD 显示屏显示“中断”。

注意:有时可能会有开关去抖动效应,按下按钮时可能会计算多次触发,这是因为由于切换按钮的机械原因导致电压出现几个尖峰。这可以通过引入RC滤波器来减少。

//INTERRUPTS IN STM32F103C8

//CIRCUIT DIGEST


const int rs= PB10,en= PB11,d4= PB0,d5= PB1,d6= PC13,d7= PC14; // declaring pin names and pin numbers of lcd

#include // including lcd display library

LiquidCrystal lcd (rs,en,d4,d5,d6,d7); // setting lcd and its parameters

volatile boolean ledOn = false; // variable declared as global



void setup() 


{

lcd.begin(16,2); // setting LCD as 16x2 type

lcd.print("CIRCUIT DIGEST"); // puts CIRCUIT DIGEST IN LCD

delay(2000); // delay time 

lcd.clear(); // clears lcd display

pinMode(PA1,OUTPUT); // set pin PA1 as output

pinMode(PA0,INPUT); // set pin PA0 as input 

int i = 0; // declare variable i and initiliaze with 0 


attachInterrupt(PA0,buttonPressed,CHANGE); // function for creating external interrupts



}


void loop() // void loops runs continuously



lcd.clear(); // clears lcd display

lcd.print("NUMBER:"); // puts NUMBER: in LCD display

lcd.print(i); // prints the values of i in LCD

++i; // increments value of i

delay(1000); // delays time 


}


void buttonPressed() //



if(ledOn) // if statement depends on LedOn value

{

ledOn=false; // Makes ledOn false if it is True

digitalWrite(PA1,LOW); // digital writs the low vale to PA1 pin makes led OFF

}

else

{

ledOn = true; // Makes ledOn True if it is False

digitalWrite(PA1,HIGH); // digital writs the HIGH vale to PA1 pin makes led ON

lcd.setCursor(0,1); // sets cursor at first column and second row 

lcd.print("Interrupt"); // puts INTERRUPT in LCD display

}

}

 


 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分