中斷是一種機(jī)制,通過(guò)該機(jī)制,I/O 或指令可以暫停處理器的正常執(zhí)行,并像具有最高優(yōu)先級(jí)一樣為自己提供服務(wù)。例如,執(zhí)行正常執(zhí)行的處理器也可以持續(xù)監(jiān)視某種事件或中斷的發(fā)生。也就是說(shuō),當(dāng)發(fā)生外部中斷(例如來(lái)自某些傳感器)時(shí),處理器暫停其正常執(zhí)行并首先提供中斷,然后繼續(xù)其正常執(zhí)行。
在本項(xiàng)目中,為了理解STM32F103C8中的中斷,我們將使用按鈕作為外部中斷。在這里,我們將從 0 開(kāi)始遞增一個(gè)數(shù)字并將其顯示在 16x2 LCD 上,每當(dāng)按下按鈕時(shí),LED 就會(huì)亮起,LCD 顯示屏就會(huì)顯示中斷。松開(kāi)按鈕后,LED 立即熄滅。
中斷和 ISR 的類型
中斷大致可分為兩種類型:
硬件中斷:如果發(fā)給處理器的信號(hào)來(lái)自某些外部設(shè)備(如按鈕或傳感器)或來(lái)自某些其它硬件設(shè)備,則其產(chǎn)生信號(hào)并告訴處理器執(zhí)行ISR中存在的特定任務(wù)稱為硬件中斷。
軟件中斷:由軟件指令生成的中斷。
中斷服務(wù)例程
中斷服務(wù)例程或中斷處理程序是包含一小組指令的事件,當(dāng)發(fā)生中斷時(shí),處理器首先執(zhí)行 ISR 中存在的這些代碼,然后繼續(xù)執(zhí)行中斷前正在執(zhí)行的任務(wù)。
STM32中斷的語(yǔ)法
ISR在Arduino中具有以下語(yǔ)法attachInterrupt(digitalPinToInterrupt(pin),ISR,mode),并且在STM32中也可以使用相同的語(yǔ)法,因?yàn)槲覀兪褂胊rduino IDE上傳代碼。
數(shù)字引腳到中斷(引腳):就像在Arduino板Uno中一樣,我們有引腳2,3,在mega中我們有2,3,18,19,20,21用于中斷。在STM32F103C8中,我們也有中斷引腳,任何GPIO引腳都可用于中斷。我們只是指定用于中斷的輸入引腳。但是,在同時(shí)使用多個(gè)中斷時(shí),我們可能需要遵循一些限制。
ISR:它是發(fā)生外部中斷時(shí)調(diào)用的中斷處理程序函數(shù)。它沒(méi)有參數(shù)和 void 返回類型。
模式:觸發(fā)中斷的轉(zhuǎn)換類型
上升:當(dāng)引腳從低電平轉(zhuǎn)換到高電平時(shí)觸發(fā)中斷。
下降:當(dāng)引腳從高電平轉(zhuǎn)換到低電平時(shí)觸發(fā)中斷。
更改:當(dāng)引腳從低電平轉(zhuǎn)換到高電平或從高電平轉(zhuǎn)換到低電平時(shí)(即,當(dāng)引腳變化時(shí)),觸發(fā)中斷。
使用中斷時(shí)的一些條件
中斷服務(wù)例程功能 (ISR) 必須盡可能短。
延遲 () 函數(shù)在 ISR 中不起作用,應(yīng)避免使用。
所需組件
STM32F103C8
按鈕
發(fā)光二極管
電阻器 (10K)
液晶顯示器 (16x2)
電路圖和連接
按鈕引腳的一側(cè)通過(guò)下拉電阻連接到STM32的3.3V,另一側(cè)通過(guò)下拉電阻連接到STM32的輸入引腳(PA0)。
使用下拉電阻,以便微控制器僅在按下或松開(kāi)按鈕時(shí)在其輸入端獲得高電平或低電平。否則,如果沒(méi)有下拉電阻,MCU可能會(huì)感到困惑,并向輸入提供一些隨機(jī)浮動(dòng)值。
STM32F103C8與液晶顯示器之間的連接
下表顯示了LCD(16X2)和STM32F103C8微控制器之間的引腳連接。
STM32F103C8 | 液晶顯示器 |
接地 | VSS |
(55 | 電壓輸出 |
前往電位計(jì)中心引腳 | V0 |
PB0 | RS |
接地 | 烏爾曼 |
PB1 | E |
PB10 | D4 |
PB11 | D5 |
電腦13 | D6 |
電腦14 | D7 |
(55 | 一個(gè) |
接地 | K |
對(duì)STM32F103C8進(jìn)行中斷編程
本教程的程序很簡(jiǎn)單,在本教程結(jié)束時(shí)給出。我們不需要FTDI編程器來(lái)編程STM32,只需將PC連接到STM32的USB端口,然后使用Arduino IDE開(kāi)始編程。了解有關(guān)通過(guò)USB端口對(duì)STM32進(jìn)行編程的更多信息。
正如我們?cè)诒窘坛讨兴f(shuō),我們將從 0 遞增一個(gè)數(shù)字并將其顯示在 16x2 LCD 上,每當(dāng)按下按鈕時(shí),LED 就會(huì)亮起,LCD 顯示屏顯示“中斷”。
首先使用STM32定義LCD引腳連接。您可以根據(jù)需要對(duì)其進(jìn)行修改。
const int rs= PB10,en= PB11,d4= PB0,d5= PB1,d6= PC13,d7= PC14;
接下來(lái),我們包括LCD顯示器的頭文件。這將調(diào)用包含STM32如何與LCD通信的代碼的庫(kù)。還要確保使用我們上面剛剛定義的引腳名稱調(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)
我們還將增加一個(gè)數(shù)字,因此聲明一個(gè)值為零的變量。
int i = 0;
現(xiàn)在代碼的重要部分是attachInterrupt()函數(shù),它也包含在 void setup() 中
attachInterrupt(digitalPinToInterrupt(PA0),buttonPressed,CHANGE)
我們?yōu)橥獠恐袛嘀付艘_PA0,按鈕按下是當(dāng)PA0引腳中存在變化(從低到高或從高到低)時(shí)要調(diào)用的函數(shù)。您還可以根據(jù)需要使用任何其他功能名稱、引腳和模式。
在 void loop() 中,我們從零遞增一個(gè)數(shù)字 (i),并在 LCD(16x2) 中打印該數(shù)字。
lcd.clear();
lcd.print("NUMBER:");
lcd.print(i);
++i;
delay(1000);
最重要的部分是根據(jù)我們?cè)?attachInterrupt() 函數(shù)中使用的名稱創(chuàng)建一個(gè)中斷處理程序函數(shù)。我們使用了buttonPress,所以這里我們創(chuàng)建了一個(gè)函數(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 打開(kāi)和關(guān)閉。
按鈕狀態(tài) | 發(fā)光二極管(值) | 指示燈(紅色) | 液晶顯示器(16x2) |
無(wú)壓 | 假 | 關(guān)閉 | - |
壓 | 真 | 上 | 顯示“中斷” |
如果 ledOn 值為假,則 LED 保持關(guān)閉狀態(tài),如果 ledOn 值為真,則 LED 亮起,LCD 顯示屏顯示“中斷”。
注意:有時(shí)可能會(huì)有開(kāi)關(guān)去抖動(dòng)效應(yīng),按下按鈕時(shí)可能會(huì)計(jì)算多次觸發(fā),這是因?yàn)橛捎谇袚Q按鈕的機(jī)械原因?qū)е码妷撼霈F(xiàn)幾個(gè)尖峰。這可以通過(guò)引入RC濾波器來(lái)減少。
//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)注
242文章
23252瀏覽量
660572 -
中斷
+關(guān)注
關(guān)注
5文章
898瀏覽量
41470 -
STM32F103C8
+關(guān)注
關(guān)注
1文章
23瀏覽量
8083
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論