中斷是一種機制,通過該機制,I/O 或指令可以暫停處理器的正常執(zhí)行,并像具有最高優(yōu)先級一樣為自己提供服務(wù)。例如,執(zhí)行正常執(zhí)行的處理器也可以持續(xù)監(jiān)視某種事件或中斷的發(fā)生。也就是說,當發(fā)生外部中斷(例如來自某些傳感器)時,處理器暫停其正常執(zhí)行并首先提供中斷,然后繼續(xù)其正常執(zhí)行。
在本項目中,為了理解STM32F103C8中的中斷,我們將使用按鈕作為外部中斷。在這里,我們將從 0 開始遞增一個數(shù)字并將其顯示在 16x2 LCD 上,每當按下按鈕時,LED 就會亮起,LCD 顯示屏就會顯示中斷。松開按鈕后,LED 立即熄滅。
中斷和 ISR 的類型
中斷大致可分為兩種類型:
硬件中斷:如果發(fā)給處理器的信號來自某些外部設(shè)備(如按鈕或傳感器)或來自某些其它硬件設(shè)備,則其產(chǎn)生信號并告訴處理器執(zhí)行ISR中存在的特定任務(wù)稱為硬件中斷。
軟件中斷:由軟件指令生成的中斷。
中斷服務(wù)例程
中斷服務(wù)例程或中斷處理程序是包含一小組指令的事件,當發(fā)生中斷時,處理器首先執(zhí)行 ISR 中存在的這些代碼,然后繼續(xù)執(zhí)行中斷前正在執(zhí)行的任務(wù)。
STM32中斷的語法
ISR在Arduino中具有以下語法attachInterrupt(digitalPinToInterrupt(pin),ISR,mode),并且在STM32中也可以使用相同的語法,因為我們使用arduino IDE上傳代碼。
數(shù)字引腳到中斷(引腳):就像在Arduino板Uno中一樣,我們有引腳2,3,在mega中我們有2,3,18,19,20,21用于中斷。在STM32F103C8中,我們也有中斷引腳,任何GPIO引腳都可用于中斷。我們只是指定用于中斷的輸入引腳。但是,在同時使用多個中斷時,我們可能需要遵循一些限制。
ISR:它是發(fā)生外部中斷時調(diào)用的中斷處理程序函數(shù)。它沒有參數(shù)和 void 返回類型。
模式:觸發(fā)中斷的轉(zhuǎn)換類型
上升:當引腳從低電平轉(zhuǎn)換到高電平時觸發(fā)中斷。
下降:當引腳從高電平轉(zhuǎn)換到低電平時觸發(fā)中斷。
更改:當引腳從低電平轉(zhuǎn)換到高電平或從高電平轉(zhuǎn)換到低電平時(即,當引腳變化時),觸發(fā)中斷。
使用中斷時的一些條件
中斷服務(wù)例程功能 (ISR) 必須盡可能短。
延遲 () 函數(shù)在 ISR 中不起作用,應(yīng)避免使用。
所需組件
STM32F103C8
按鈕
發(fā)光二極管
電阻器 (10K)
液晶顯示器 (16x2)
電路圖和連接
按鈕引腳的一側(cè)通過下拉電阻連接到STM32的3.3V,另一側(cè)通過下拉電阻連接到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進行中斷編程
本教程的程序很簡單,在本教程結(jié)束時給出。我們不需要FTDI編程器來編程STM32,只需將PC連接到STM32的USB端口,然后使用Arduino IDE開始編程。了解有關(guān)通過USB端口對STM32進行編程的更多信息。
正如我們在本教程中所說,我們將從 0 遞增一個數(shù)字并將其顯示在 16x2 LCD 上,每當按下按鈕時,LED 就會亮起,LCD 顯示屏顯示“中斷”。
首先使用STM32定義LCD引腳連接。您可以根據(jù)需要對其進行修改。
const int rs= PB10,en= PB11,d4= PB0,d5= PB1,d6= PC13,d7= PC14;
接下來,我們包括LCD顯示器的頭文件。這將調(diào)用包含STM32如何與LCD通信的代碼的庫。還要確保使用我們上面剛剛定義的引腳名稱調(diào)用函數(shù) LiquidCrystal。
include
LiquidCrystal lcd (rs,en,d4,d5,d6,d7);
全局變量用于在 ISR 和主程序之間傳遞數(shù)據(jù)。我們將變量 ledOn 聲明為易失性,也聲明為布爾值以指定 True 或 False。
volatile boolean ledOn = false;
在 void setup() 函數(shù)中,我們將顯示一條介紹消息并在 2 秒后清除它。
lcd.begin(16,2);
lcd.print("CIRCUIT DIGEST");
delay(2000);
lcd.clear();
同樣在相同的void設(shè)置()函數(shù)中,我們需要指定輸入和輸出引腳。我們將引腳 PA1 用于輸出設(shè)置為 LED,將 PA0 設(shè)置為按鈕輸入。
pinMode(PA1,OUTPUT)
pinMode(PA0,INPUT)
我們還將增加一個數(shù)字,因此聲明一個值為零的變量。
int i = 0;
現(xiàn)在代碼的重要部分是attachInterrupt()函數(shù),它也包含在 void setup() 中
attachInterrupt(digitalPinToInterrupt(PA0),buttonPressed,CHANGE)
我們?yōu)橥獠恐袛嘀付艘_PA0,按鈕按下是當PA0引腳中存在變化(從低到高或從高到低)時要調(diào)用的函數(shù)。您還可以根據(jù)需要使用任何其他功能名稱、引腳和模式。
在 void loop() 中,我們從零遞增一個數(shù)字 (i),并在 LCD(16x2) 中打印該數(shù)字。
lcd.clear();
lcd.print("NUMBER:");
lcd.print(i);
++i;
delay(1000);
最重要的部分是根據(jù)我們在 attachInterrupt() 函數(shù)中使用的名稱創(chuàng)建一個中斷處理程序函數(shù)。我們使用了buttonPress,所以這里我們創(chuàng)建了一個函數(shù) 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:
根據(jù) ledOn 變量的值,LED 打開和關(guān)閉。
按鈕狀態(tài) | 發(fā)光二極管(值) | 指示燈(紅色) | 液晶顯示器(16x2) |
無壓 | 假 | 關(guān)閉 | - |
壓 | 真 | 上 | 顯示“中斷” |
如果 ledOn 值為假,則 LED 保持關(guān)閉狀態(tài),如果 ledOn 值為真,則 LED 亮起,LCD 顯示屏顯示“中斷”。
注意:有時可能會有開關(guān)去抖動效應(yīng),按下按鈕時可能會計算多次觸發(fā),這是因為由于切換按鈕的機械原因?qū)е码妷撼霈F(xiàn)幾個尖峰。這可以通過引入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
}
}
-
led
+關(guān)注
關(guān)注
240文章
23062瀏覽量
657045 -
中斷
+關(guān)注
關(guān)注
5文章
895瀏覽量
41349 -
STM32F103C8
+關(guān)注
關(guān)注
1文章
23瀏覽量
8066
發(fā)布評論請先 登錄
相關(guān)推薦
評論