国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

嵌入式-stm32-江科大-EXTI外部中斷

這篇具有很好參考價(jià)值的文章主要介紹了嵌入式-stm32-江科大-EXTI外部中斷。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

一:EXTI外部中斷(external interrupt)

1.1 STM32 中斷系統(tǒng)

嵌入式-stm32-江科大-EXTI外部中斷,江科大-Stm32-學(xué)習(xí)筆記,嵌入式-STM32單片機(jī),stm32,單片機(jī),嵌入式硬件,mcu,#江科大

中斷是指在主程序運(yùn)行過(guò)程中,出現(xiàn)了特定的中斷觸發(fā)條件(中斷源),使得CPU暫停當(dāng)前的程序,轉(zhuǎn)而去處理中斷程序,處理完成后又返回原來(lái)被暫停的位置繼續(xù)執(zhí)行,當(dāng)中斷發(fā)生時(shí)是由硬件自動(dòng)調(diào)用中斷函數(shù)執(zhí)行的,期間編譯器會(huì)保護(hù)現(xiàn)場(chǎng)最后還原現(xiàn)場(chǎng)。使得中斷系統(tǒng)極大程度地提高程序的效率,就像是給自己定鬧鐘,可以不用擔(dān)心錯(cuò)過(guò)時(shí)間而可以安心睡覺(jué),在這個(gè)過(guò)程中,有如下概念:

  • 中斷優(yōu)先級(jí):當(dāng)有多個(gè)中斷源同時(shí)申請(qǐng)中斷時(shí),CPU會(huì)根據(jù)中斷源的輕重緩急進(jìn)行裁決,優(yōu)先響應(yīng)更加緊急的中斷源。
  • 中斷嵌套:當(dāng)一個(gè)中斷程序正在運(yùn)行時(shí),又有新的更高優(yōu)先級(jí)的中斷源申請(qǐng)中斷,CPU再次暫停當(dāng)前中斷程序,CPU再次暫停當(dāng)前中斷程序,轉(zhuǎn)而去處理新的中斷程序,處理完成后依次進(jìn)行返回。

stm32的F1系列總共有68個(gè)可屏蔽中斷通道(中斷源),包含EXTI、TIM、ADC、USART、SPI、I2C、RTC等多個(gè)外設(shè)。所有的中斷使用嵌套向量中斷控制器NVIC統(tǒng)一管理中斷,每個(gè)中斷通道都擁有16個(gè)可編程的優(yōu)先等級(jí),可對(duì)優(yōu)先級(jí)進(jìn)行分組,進(jìn)一步設(shè)置搶占優(yōu)先級(jí)和響應(yīng)優(yōu)先級(jí)。具體到某一個(gè)型號(hào)的芯片可能不會(huì)有這多中斷,具體需要查看的芯片手冊(cè)。下面是手冊(cè)中的中斷向量表節(jié)選:
嵌入式-stm32-江科大-EXTI外部中斷,江科大-Stm32-學(xué)習(xí)筆記,嵌入式-STM32單片機(jī),stm32,單片機(jī),嵌入式硬件,mcu,#江科大

  • 地址(最后一列):存儲(chǔ)中斷地址,這個(gè)地址列表也稱為中斷向量表。因?yàn)槌绦蛑械闹袛嗪瘮?shù)地址由編譯器來(lái)分配,所以中斷函數(shù)地址不固定。但由于硬件的限制,中斷跳轉(zhuǎn)只能跳轉(zhuǎn)到固定的地址執(zhí)行程序。所以為了讓硬件能跳轉(zhuǎn)到(一個(gè)地址不固定的)中斷函數(shù)里,就需要在內(nèi)存中定義一個(gè)固定的地址列表。當(dāng)中斷發(fā)生后,首先跳轉(zhuǎn)到這個(gè)固定的地址列表,編譯器會(huì)在這個(gè)固定的位置加上一條跳轉(zhuǎn)到中斷函數(shù)的代碼,于是中斷跳轉(zhuǎn)就可以跳轉(zhuǎn)到任意位置了。中斷地址列表就是中斷向量表,相當(dāng)于是中斷跳轉(zhuǎn)的跳板。C語(yǔ)言編程無(wú)需關(guān)注中斷向量表,匯編語(yǔ)言需要

嵌入式-stm32-江科大-EXTI外部中斷,江科大-Stm32-學(xué)習(xí)筆記,嵌入式-STM32單片機(jī),stm32,單片機(jī),嵌入式硬件,mcu,#江科大

上圖給出了嵌套向量中斷控制器NVIC的基本結(jié)構(gòu)示意圖。在stm32中,NVIC用于統(tǒng)一管理中斷和分配中斷優(yōu)先級(jí),屬于內(nèi)核外設(shè),是CPU的小助手,可以讓CPU專注于運(yùn)算。從上圖可以看出:

  • NVIC有很多輸入口,每個(gè)都代表一個(gè)中斷線路,如EXTI、TIM、ADC等。
  • 每個(gè)中斷線路上的斜杠n表示n條線,因?yàn)橐粋€(gè)外設(shè)可能會(huì)同時(shí)占用多個(gè)中斷通道。
  • NVIC只有一個(gè)輸出口,通過(guò)中斷優(yōu)先級(jí)確定中斷執(zhí)行的順序。

NVIC的中斷優(yōu)先級(jí)由優(yōu)先級(jí)寄存器的4位二進(jìn)制(十進(jìn)制0~15)決定,這4位可以進(jìn)行切分,分為高n位的搶占優(yōu)先級(jí)和低(4-n)位的響應(yīng)優(yōu)先級(jí)。
搶占優(yōu)先級(jí)高的可以中斷嵌套,響應(yīng)優(yōu)先級(jí)高的可以優(yōu)先排隊(duì),搶占優(yōu)先級(jí)和響應(yīng)優(yōu)先級(jí)均相同的按中斷號(hào)排隊(duì)。這個(gè)中斷號(hào)就是指中斷向量表的第二列“優(yōu)先級(jí)”。

用醫(yī)院的叫號(hào)系統(tǒng)來(lái)舉例子。假設(shè)醫(yī)生正在給某個(gè)病人看病,外面還有很多病人排隊(duì):

  1. 新來(lái)的病人 搶占優(yōu)先級(jí)高就相當(dāng)于直接進(jìn)屋打斷醫(yī)生,給自己看病。
  2. 新來(lái)的病人 響應(yīng)優(yōu)先級(jí)高就相當(dāng)于不打擾醫(yī)生,但直接插隊(duì),排在隊(duì)伍的第一個(gè)。

下表是NVIC優(yōu)先級(jí)的分組方式

分組方式 搶占優(yōu)先級(jí) 響應(yīng)優(yōu)先級(jí)
分組0(n = 0) 0位,取值為0 4位,取值為0~15
分組1(n = 1) 1位,取值為0~1 3位,取值為0~7
分組2(n = 2) 2位,取值為0~3 2位,取值為0~3
分組3(n = 3) 3位,取值0~ 7 1位,取值為0~ 1
分組4(n = 4) 4位,取值為0~15 0位,取值為0

注:NVIC是內(nèi)核外設(shè),更多關(guān)于NVIC的介紹參考“STM32F10xxx Cortex-M3編程手冊(cè)”。 NVIC

  • 中斷分組的配置寄存器,在SCB_AIRCR中,PRIGROUP這三位就是用于配置中斷分組的。

1.2 STM32外部中斷EXTI

下圖是外部中斷向量表片選
嵌入式-stm32-江科大-EXTI外部中斷,江科大-Stm32-學(xué)習(xí)筆記,嵌入式-STM32單片機(jī),stm32,單片機(jī),嵌入式硬件,mcu,#江科大

中斷系統(tǒng)是管理和執(zhí)行中斷的邏輯結(jié)構(gòu),外部中斷是眾多能產(chǎn)生中斷的外設(shè)之一,而EXTI就是其中之一(比如USART、I2C,參考上面的NVIC基本結(jié)構(gòu)),上圖給出了外部中斷向量表。EXTI(external interrupt)外部中斷可以監(jiān)測(cè)指定的GPIO口的電平信號(hào),當(dāng)其指定的GPIO口產(chǎn)生電平變化時(shí),EXTI將立即向NVIC發(fā)出中斷申請(qǐng),經(jīng)過(guò)NVIC裁決后即可中斷CPU主程序,使得CPU執(zhí)行EXTI對(duì)應(yīng)的中斷程序。

  • 支持的觸發(fā)方式:上升沿/下降沿/雙邊沿/軟件觸發(fā)(上升沿就是低電平到高電平觸發(fā))
  • 支持的GPIO口:所有GPIO口,但相同的Pin不能同時(shí)觸發(fā)中斷(比如gpioa_Pin1與gpiob_pin1不能同時(shí)觸發(fā)中斷)。
  • 通道數(shù):16個(gè)GPIO_Pin,外加PVD輸出、RTC鬧鐘、USB喚醒、以太網(wǎng)喚醒,共20個(gè)。

注:后面這四個(gè)功能是為了實(shí)現(xiàn)一些特殊的功能,比如想實(shí)現(xiàn)某個(gè)時(shí)間讓stm32退出停止模式,由于外部中斷可以在低功耗模式的停止模式下喚醒stm32,就可以在GPIO口上連接一個(gè)RTC時(shí)鐘作為外部中斷。

  • 觸發(fā)響應(yīng)方式:中斷響應(yīng)/事件響應(yīng)。
  • 注意:
    中斷響應(yīng)就是正常的中斷流程,申請(qǐng)中斷讓CPU執(zhí)行中斷函數(shù);
  • 事件響應(yīng)就是外部中斷發(fā)生時(shí),不把外部信號(hào)給CPU,而是選擇觸發(fā)一個(gè)事件,將這個(gè)信號(hào)通向其他外設(shè),來(lái)觸發(fā)其他外設(shè)的操作,可以實(shí)現(xiàn)外設(shè)之間的聯(lián)合工作(中介分包)。

下圖是EXTI的基本結(jié)構(gòu)
嵌入式-stm32-江科大-EXTI外部中斷,江科大-Stm32-學(xué)習(xí)筆記,嵌入式-STM32單片機(jī),stm32,單片機(jī),嵌入式硬件,mcu,#江科大Alternate Fuction I/O:數(shù)據(jù)選擇器(交替作用)
記形狀:梯形(多個(gè)輸入一個(gè)輸出)

  • 最左側(cè):GPIO口的外設(shè),每個(gè)外設(shè)都有16個(gè)引腳。
  • AFIO中斷引腳選擇:本質(zhì)上就是數(shù)據(jù)選擇器,從前面16*n 個(gè)引腳中選擇16根端口號(hào)不重復(fù)的引腳出來(lái),連接到后面的EXTI通道中。在STM32中,AFIO主要完成兩個(gè)任務(wù):復(fù)用功能引腳重映射、中斷引腳選擇。下面是中斷引腳選擇的AFIO示意圖:
    嵌入式-stm32-江科大-EXTI外部中斷,江科大-Stm32-學(xué)習(xí)筆記,嵌入式-STM32單片機(jī),stm32,單片機(jī),嵌入式硬件,mcu,#江科大
  • PVD、RTC、USB、ETH:四個(gè)特殊功能的外設(shè)。
  • EXTI 邊沿檢測(cè)及控制:20個(gè)輸入通道、兩類輸出。一類輸出到NVIC中,并且將這20路輸出的9、10 路外部中斷合并在一起以節(jié)省通道;另一類輸出到其他外設(shè),直接就是20路輸出。
    注:上面這個(gè)EXTI的基本結(jié)構(gòu)也是編寫代碼時(shí)的主要參考圖!

下圖是EXTI 框圖(方向?yàn)閺淖蟮接遥?stm32F10系列參考手冊(cè)
嵌入式-stm32-江科大-EXTI外部中斷,江科大-Stm32-學(xué)習(xí)筆記,嵌入式-STM32單片機(jī),stm32,單片機(jī),嵌入式硬件,mcu,#江科大

上圖給出了參考手冊(cè)中的EXTI框圖?;具壿嬇c“EXTI的基本結(jié)構(gòu)”中所述相同,另外還有一些細(xì)節(jié):

  • 邊沿檢測(cè)電路+軟件中斷事件寄存器:這個(gè)幾個(gè)進(jìn)行或門輸出,便可以實(shí)現(xiàn)“上升沿/下降沿/雙邊沿/軟件觸發(fā)”這四種觸發(fā)方式。
  • 請(qǐng)求掛起寄存器:相當(dāng)于一個(gè)中斷標(biāo)志位,通過(guò)讀取該寄存器可以判斷是哪個(gè)通道觸發(fā)的中斷。
  • 中斷屏蔽寄存器/事件屏蔽寄存器:相當(dāng)于開(kāi)關(guān),只有置1,中斷信號(hào)才能繼續(xù)向左走。
  • 脈沖發(fā)生器:產(chǎn)生一個(gè)電平脈沖,用于觸發(fā)其他外設(shè)工作。

嵌入式-stm32-江科大-EXTI外部中斷,江科大-Stm32-學(xué)習(xí)筆記,嵌入式-STM32單片機(jī),stm32,單片機(jī),嵌入式硬件,mcu,#江科大

最后一個(gè)問(wèn)題,到底什么樣的設(shè)備需要用到外部中段呢?

答:對(duì)于stm32來(lái)說(shuō),若想獲取一個(gè)由外部驅(qū)動(dòng)的很快的突發(fā)信號(hào),就需要外部中斷。

  • 如旋轉(zhuǎn)編碼器,平常不會(huì)有什么變化,但是一旦擰動(dòng)時(shí),會(huì)產(chǎn)生一段時(shí)間變化很快的突發(fā)信號(hào),就需要stm32能在短時(shí)間內(nèi)快速讀取并處理掉這個(gè)數(shù)據(jù)。

  • 再如紅外遙控接收頭,平常也不會(huì)有什么變化,但是一旦接收到信號(hào)時(shí),這個(gè)信號(hào)也是轉(zhuǎn)瞬即逝的。

  • 但是不推薦按鍵使用外部中斷。因?yàn)橥獠恐袛嗖荒芎芎玫奶幚戆存I抖動(dòng)和松手檢測(cè)的問(wèn)題,所以要求不高時(shí),還是建議在主函數(shù)內(nèi)部循環(huán)讀取。

1.2 旋轉(zhuǎn)編碼器介紹
對(duì)射式紅外傳感器就是一種通用傳感器模塊,已經(jīng)在第三節(jié)“GPIO通用輸入輸出口”中介紹過(guò),不再贅述。本實(shí)驗(yàn)只介紹旋轉(zhuǎn)編碼器。

旋轉(zhuǎn)編碼器是一種用來(lái)測(cè)量位置、速度或旋轉(zhuǎn)方向的裝置,當(dāng)其旋轉(zhuǎn)軸旋轉(zhuǎn)時(shí),其輸出端可以與旋轉(zhuǎn)速度和方向?qū)?yīng)的方波信號(hào),讀取方波信號(hào)的頻率和相位信息即可得知旋轉(zhuǎn)軸的速度和方向。
嵌入式-stm32-江科大-EXTI外部中斷,江科大-Stm32-學(xué)習(xí)筆記,嵌入式-STM32單片機(jī),stm32,單片機(jī),嵌入式硬件,mcu,#江科大

如上圖,旋轉(zhuǎn)編碼器主要有三種類型:光柵式/機(jī)械觸點(diǎn)式/霍爾傳感器式。下面是這三種形式的介紹:

  1. 光柵式(老款鼠標(biāo)):配合對(duì)射式紅外傳感器使用,在旋轉(zhuǎn)過(guò)程中光柵式編碼盤會(huì)不斷地阻擋/透過(guò)紅外射線,于是模塊便會(huì)輸出高低電平交替的方波,方波的頻率便代表了旋轉(zhuǎn)速度。缺點(diǎn)是只有一路輸出,無(wú)法判斷轉(zhuǎn)動(dòng)方向。
  2. 機(jī)械觸點(diǎn)式:內(nèi)部使用機(jī)械觸點(diǎn)檢測(cè)通斷,A口和B口輸出的方波正交,具體看下面的介紹。當(dāng)然,也有機(jī)械觸點(diǎn)式編碼器可以一個(gè)引腳輸出速度信息,一一個(gè)引腳輸出旋轉(zhuǎn)方向信息。
  3. 霍爾傳感器式:直接附在電機(jī)后面的編碼器,中間是一個(gè)圓形磁鐵,旋轉(zhuǎn)時(shí)兩側(cè)的霍爾傳感器便可輸出正交的方波信號(hào)。
  4. 獨(dú)立的編碼器元件:輸入軸轉(zhuǎn)動(dòng)時(shí),輸出便有波形。

注:觸點(diǎn)式不適合高速旋轉(zhuǎn)的場(chǎng)景,常用于音量調(diào)節(jié)。非接觸式形式的電機(jī)可以用于電機(jī)測(cè)速。
嵌入式-stm32-江科大-EXTI外部中斷,江科大-Stm32-學(xué)習(xí)筆記,嵌入式-STM32單片機(jī),stm32,單片機(jī),嵌入式硬件,mcu,#江科大

上圖是機(jī)械觸點(diǎn)式旋轉(zhuǎn)編碼器-實(shí)物拆解

  • 圖片右側(cè)是旋轉(zhuǎn)編碼器的旋鈕,可以看到下面是一圈可以導(dǎo)電的金屬片。
  • 中間有一個(gè)大的按鍵開(kāi)關(guān)結(jié)構(gòu),也可以檢測(cè)通斷,但是該旋轉(zhuǎn)編碼器模塊沒(méi)有使用到該功能。
  • 左右兩組金屬觸點(diǎn)。內(nèi)部實(shí)際的連接如紅線標(biāo)注,C口接地,于是旋鈕在旋轉(zhuǎn)過(guò)程中就可以使A口、B口輸出高低交替的方波。方波頻率表示旋轉(zhuǎn)速度。
  • A口、B口配合旋鈕,可以產(chǎn)生相位相差90°的方波,稱為正交信號(hào)。順時(shí)針旋轉(zhuǎn)A口相位超前,逆時(shí)針旋轉(zhuǎn)B口相位超前。

嵌入式-stm32-江科大-EXTI外部中斷,江科大-Stm32-學(xué)習(xí)筆記,嵌入式-STM32單片機(jī),stm32,單片機(jī),嵌入式硬件,mcu,#江科大

  • R1、R2:上拉電阻。
  • R3、R4:輸出限流電阻,防止引腳電流過(guò)大。
  • C1、C2:濾波電容,濾除高頻不穩(wěn)定紋波。
    注:C口已經(jīng)默認(rèn)接地,只需關(guān)心A口、B口的高低變化及相位差即可。

1.3 實(shí)驗(yàn):對(duì)射式紅外傳感器計(jì)次

需求:利用stm32的外部中斷,對(duì) 對(duì)射式紅外傳感器 產(chǎn)生的下降沿進(jìn)行計(jì)次。

嵌入式-stm32-江科大-EXTI外部中斷,江科大-Stm32-學(xué)習(xí)筆記,嵌入式-STM32單片機(jī),stm32,單片機(jī),嵌入式硬件,mcu,#江科大上圖是對(duì)射式紅外傳感器計(jì)次-接線圖
下圖是對(duì)射式紅外傳感器計(jì)次-代碼調(diào)用
嵌入式-stm32-江科大-EXTI外部中斷,江科大-Stm32-學(xué)習(xí)筆記,嵌入式-STM32單片機(jī),stm32,單片機(jī),嵌入式硬件,mcu,#江科大代碼展示:OLED.h、OLED.c、OLED_Font.h代碼見(jiàn)第四節(jié)“OLED調(diào)試工具”,本節(jié)省略。
文章在這《嵌入式-stm32-江科大-OLED調(diào)試工具》

main.c

#include "stm32f10x.h"
#include "Delay.h"
#include "OLED.h"
#include "CountSensor.h"

int main(void)
{
	//模塊初始化
	OLED_Init();       //OLED初始化
	CountSensor_Init(); //計(jì)數(shù)傳感器初始化
	
	//OLED顯示,顯示靜態(tài)字符串
	OLED_ShowString(1,1,"Count:");  //一行一列顯示字符串
	Delay_ms(500);
	
	
	while(1)
	{
	OLED_ShowNum(2,1,CountSensor_Get(),5);
	}

}

CountSensor.h

#ifndef __COUNT_SENSOR_H
#define __COUNT_SENSOR_H

void CountSensor_Init(void);
uint16_t CountSensor_Get(void);


#endif

CountSensor.c

#include "stm32f10x.h"

uint16_t  CountSensor_Count;     //全局變量,中斷觸發(fā)次數(shù),用于計(jì)數(shù)
//默認(rèn)初始化為0

/**
  * 函    數(shù):對(duì)射式紅外傳感器-計(jì)數(shù)傳感器初始化 PB14
  * 參    數(shù):無(wú)
  * 返 回 值:無(wú)
  */
void CountSensor_Init(void)
{
	//1.開(kāi)啟時(shí)鐘
	//2.GPIO初始化
	//3.AFIO選擇中斷引腳
	//4.EXTI初始化
	//5.//NVIC配置,NVIC中斷分組
	
	
	//EXTI初始化
	//1.開(kāi)啟GPIO&AFIO的外設(shè)時(shí)鐘(EXTI和NVIC的時(shí)鐘是一直打開(kāi)的)
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
	//2.配置GPIO—PB14上拉輸入
	GPIO_InitTypeDef  GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IPU; //上拉輸入
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	//3.配置AFIO(庫(kù)函數(shù)在GPIO中)中斷引腳選擇
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource14);//將外部中斷的14號(hào)線映射到GPIOB,即選擇PB14為外部中斷引腳
	//4.配置EXTI初始化
	EXTI_InitTypeDef EXTI_InitStructure;//改名字
	EXTI_InitStructure.EXTI_Line = EXTI_Line14;
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿觸發(fā)
	EXTI_Init(&EXTI_InitStructure);
	
	//5.NVIC配置(庫(kù)函數(shù)在misc.h文件中,雜項(xiàng))
	//配置NVIC中斷分組
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	//配置中斷的優(yōu)先級(jí)分組,每個(gè)工程只能出現(xiàn)一次
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStructure);
}	
/**
  * 函    數(shù):獲取計(jì)數(shù)傳感器的計(jì)數(shù)值,輸出中斷觸發(fā)的次數(shù)
  * 參    數(shù):無(wú)
  * 返 回 值:計(jì)數(shù)值,范圍:0~65535
  */
uint16_t CountSensor_Get(void)
{
	return CountSensor_Count;
}	
   
/**
  * 函    數(shù):EXTI15_10外部中斷函數(shù)
  * 參    數(shù):無(wú)
  * 返 回 值:無(wú)
  * 注意事項(xiàng):此函數(shù)為中斷函數(shù),無(wú)需調(diào)用,中斷觸發(fā)后自動(dòng)執(zhí)行
  *           函數(shù)名為預(yù)留的指定名稱,可以從啟動(dòng)文件復(fù)制
  *           請(qǐng)確保函數(shù)名正確,不能有任何差異,否則中斷函數(shù)將不能進(jìn)入
  */
void EXTI15_10_IRQHandler(void)
{
	//中斷標(biāo)志位判斷
	if(EXTI_GetITStatus(EXTI_Line14) == SET)  //判斷是否是外部中斷14號(hào)線觸發(fā)的中斷
	{
		//如果出現(xiàn)數(shù)據(jù)亂跳的現(xiàn)象,可再次判斷引腳電平,以避免抖動(dòng)
		if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14) == 0 )
		{
			CountSensor_Count ++;  //計(jì)數(shù)值自增一次
		
		}
		EXTI_ClearITPendingBit(EXTI_Line4);//清除外部中斷14號(hào)線的中斷標(biāo)志位
											//中斷標(biāo)志位必須清除
											//否則中斷將連續(xù)不斷地觸發(fā),導(dǎo)致主程序卡死

	}
}










1.31 編程感想
  1. 對(duì)射式傳感器采用下降沿觸發(fā)(移除遮擋觸發(fā),硬件設(shè)計(jì))。
    傳感器無(wú)遮擋時(shí),DO輸出低電平;傳感器有遮擋時(shí),DO輸出高電平。所以放入遮擋物意味著觸發(fā)上升沿,移除遮擋相當(dāng)于下降沿。采用上升沿觸發(fā)計(jì)數(shù)可能不準(zhǔn)確,下降沿觸發(fā)計(jì)數(shù)準(zhǔn)確(實(shí)測(cè)),若傳感器采用上升沿觸發(fā)那么結(jié)論和上面相反,移除遮擋物的時(shí)候比較準(zhǔn)確。

  2. 中斷函數(shù)的名字從啟動(dòng)文件“stratup_stm32f10x_md”中來(lái),并且中斷函數(shù)都是無(wú)參無(wú)返回值的。

  3. 在CountSensor.c里面GPIO使用結(jié)構(gòu)體來(lái)初始化函數(shù)、外部中斷、ADC、串口都是一樣的操作。

  4. 學(xué)會(huì)使用keil調(diào)試,博主第一次燒錄程序發(fā)現(xiàn)計(jì)數(shù)傳感器沒(méi)有返回值,燈會(huì)閃計(jì)數(shù),但是不會(huì)反饋到顯示屏上。于是我先把老師的代碼燒錄運(yùn)行成功,說(shuō)明硬件沒(méi)問(wèn)題,就是自己代碼問(wèn)題,然后一直排除,通過(guò)用源碼替換自己寫的代碼過(guò)程中,發(fā)現(xiàn)是上一個(gè)實(shí)驗(yàn)的OLED.c問(wèn)題,CV工程師。

OLED.c(可以跳過(guò))

#include "stm32f10x.h"
#include "OLED_Font.h"

/*引腳配置*/
#define OLED_W_SCL(x)		GPIO_WriteBit(GPIOB, GPIO_Pin_8, (BitAction)(x))
#define OLED_W_SDA(x)		GPIO_WriteBit(GPIOB, GPIO_Pin_9, (BitAction)(x))

/*引腳初始化*/
void OLED_I2C_Init(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
 	GPIO_Init(GPIOB, &GPIO_InitStructure);
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
 	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	OLED_W_SCL(1);
	OLED_W_SDA(1);
}

/**
  * @brief  I2C開(kāi)始
  * @param  無(wú)
  * @retval 無(wú)
  */
void OLED_I2C_Start(void)
{
	OLED_W_SDA(1);
	OLED_W_SCL(1);
	OLED_W_SDA(0);
	OLED_W_SCL(0);
}

/**
  * @brief  I2C停止
  * @param  無(wú)
  * @retval 無(wú)
  */
void OLED_I2C_Stop(void)
{
	OLED_W_SDA(0);
	OLED_W_SCL(1);
	OLED_W_SDA(1);
}

/**
  * @brief  I2C發(fā)送一個(gè)字節(jié)
  * @param  Byte 要發(fā)送的一個(gè)字節(jié)
  * @retval 無(wú)
  */
void OLED_I2C_SendByte(uint8_t Byte)
{
	uint8_t i;
	for (i = 0; i < 8; i++)
	{
		OLED_W_SDA(Byte & (0x80 >> i));
		OLED_W_SCL(1);
		OLED_W_SCL(0);
	}
	OLED_W_SCL(1);	//額外的一個(gè)時(shí)鐘,不處理應(yīng)答信號(hào)
	OLED_W_SCL(0);
}

/**
  * @brief  OLED寫命令
  * @param  Command 要寫入的命令
  * @retval 無(wú)
  */
void OLED_WriteCommand(uint8_t Command)
{
	OLED_I2C_Start();
	OLED_I2C_SendByte(0x78);		//從機(jī)地址
	OLED_I2C_SendByte(0x00);		//寫命令
	OLED_I2C_SendByte(Command); 
	OLED_I2C_Stop();
}

/**
  * @brief  OLED寫數(shù)據(jù)
  * @param  Data 要寫入的數(shù)據(jù)
  * @retval 無(wú)
  */
void OLED_WriteData(uint8_t Data)
{
	OLED_I2C_Start();
	OLED_I2C_SendByte(0x78);		//從機(jī)地址
	OLED_I2C_SendByte(0x40);		//寫數(shù)據(jù)
	OLED_I2C_SendByte(Data);
	OLED_I2C_Stop();
}

/**
  * @brief  OLED設(shè)置光標(biāo)位置
  * @param  Y 以左上角為原點(diǎn),向下方向的坐標(biāo),范圍:0~7
  * @param  X 以左上角為原點(diǎn),向右方向的坐標(biāo),范圍:0~127
  * @retval 無(wú)
  */
void OLED_SetCursor(uint8_t Y, uint8_t X)
{
	OLED_WriteCommand(0xB0 | Y);					//設(shè)置Y位置
	OLED_WriteCommand(0x10 | ((X & 0xF0) >> 4));	//設(shè)置X位置高4位
	OLED_WriteCommand(0x00 | (X & 0x0F));			//設(shè)置X位置低4位
}

/**
  * @brief  OLED清屏
  * @param  無(wú)
  * @retval 無(wú)
  */
void OLED_Clear(void)
{  
	uint8_t i, j;
	for (j = 0; j < 8; j++)
	{
		OLED_SetCursor(j, 0);
		for(i = 0; i < 128; i++)
		{
			OLED_WriteData(0x00);
		}
	}
}

/**
  * @brief  OLED顯示一個(gè)字符
  * @param  Line 行位置,范圍:1~4
  * @param  Column 列位置,范圍:1~16
  * @param  Char 要顯示的一個(gè)字符,范圍:ASCII可見(jiàn)字符
  * @retval 無(wú)
  */
void OLED_ShowChar(uint8_t Line, uint8_t Column, char Char)
{      	
	uint8_t i;
	OLED_SetCursor((Line - 1) * 2, (Column - 1) * 8);		//設(shè)置光標(biāo)位置在上半部分
	for (i = 0; i < 8; i++)
	{
		OLED_WriteData(OLED_F8x16[Char - ' '][i]);			//顯示上半部分內(nèi)容
	}
	OLED_SetCursor((Line - 1) * 2 + 1, (Column - 1) * 8);	//設(shè)置光標(biāo)位置在下半部分
	for (i = 0; i < 8; i++)
	{
		OLED_WriteData(OLED_F8x16[Char - ' '][i + 8]);		//顯示下半部分內(nèi)容
	}
}

/**
  * @brief  OLED顯示字符串
  * @param  Line 起始行位置,范圍:1~4
  * @param  Column 起始列位置,范圍:1~16
  * @param  String 要顯示的字符串,范圍:ASCII可見(jiàn)字符
  * @retval 無(wú)
  */
void OLED_ShowString(uint8_t Line, uint8_t Column, char *String)
{
	uint8_t i;
	for (i = 0; String[i] != '\0'; i++)
	{
		OLED_ShowChar(Line, Column + i, String[i]);
	}
}

/**
  * @brief  OLED次方函數(shù)
  * @retval 返回值等于X的Y次方
  */
uint32_t OLED_Pow(uint32_t X, uint32_t Y)
{
	uint32_t Result = 1;
	while (Y--)
	{
		Result *= X;
	}
	return Result;
}

/**
  * @brief  OLED顯示數(shù)字(十進(jìn)制,正數(shù))
  * @param  Line 起始行位置,范圍:1~4
  * @param  Column 起始列位置,范圍:1~16
  * @param  Number 要顯示的數(shù)字,范圍:0~4294967295
  * @param  Length 要顯示數(shù)字的長(zhǎng)度,范圍:1~10
  * @retval 無(wú)
  */
void OLED_ShowNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length)
{
	uint8_t i;
	for (i = 0; i < Length; i++)							
	{
		OLED_ShowChar(Line, Column + i, Number / OLED_Pow(10, Length - i - 1) % 10 + '0');
	}
}

/**
  * @brief  OLED顯示數(shù)字(十進(jìn)制,帶符號(hào)數(shù))
  * @param  Line 起始行位置,范圍:1~4
  * @param  Column 起始列位置,范圍:1~16
  * @param  Number 要顯示的數(shù)字,范圍:-2147483648~2147483647
  * @param  Length 要顯示數(shù)字的長(zhǎng)度,范圍:1~10
  * @retval 無(wú)
  */
void OLED_ShowSignedNum(uint8_t Line, uint8_t Column, int32_t Number, uint8_t Length)
{
	uint8_t i;
	uint32_t Number1;
	if (Number >= 0)
	{
		OLED_ShowChar(Line, Column, '+');
		Number1 = Number;
	}
	else
	{
		OLED_ShowChar(Line, Column, '-');
		Number1 = -Number;
	}
	for (i = 0; i < Length; i++)							
	{
		OLED_ShowChar(Line, Column + i + 1, Number1 / OLED_Pow(10, Length - i - 1) % 10 + '0');
	}
}

/**
  * @brief  OLED顯示數(shù)字(十六進(jìn)制,正數(shù))
  * @param  Line 起始行位置,范圍:1~4
  * @param  Column 起始列位置,范圍:1~16
  * @param  Number 要顯示的數(shù)字,范圍:0~0xFFFFFFFF
  * @param  Length 要顯示數(shù)字的長(zhǎng)度,范圍:1~8
  * @retval 無(wú)
  */
void OLED_ShowHexNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length)
{
	uint8_t i, SingleNumber;
	for (i = 0; i < Length; i++)							
	{
		SingleNumber = Number / OLED_Pow(16, Length - i - 1) % 16;
		if (SingleNumber < 10)
		{
			OLED_ShowChar(Line, Column + i, SingleNumber + '0');
		}
		else
		{
			OLED_ShowChar(Line, Column + i, SingleNumber - 10 + 'A');
		}
	}
}

/**
  * @brief  OLED顯示數(shù)字(二進(jìn)制,正數(shù))
  * @param  Line 起始行位置,范圍:1~4
  * @param  Column 起始列位置,范圍:1~16
  * @param  Number 要顯示的數(shù)字,范圍:0~1111 1111 1111 1111
  * @param  Length 要顯示數(shù)字的長(zhǎng)度,范圍:1~16
  * @retval 無(wú)
  */
void OLED_ShowBinNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length)
{
	uint8_t i;
	for (i = 0; i < Length; i++)							
	{
		OLED_ShowChar(Line, Column + i, Number / OLED_Pow(2, Length - i - 1) % 2 + '0');
	}
}

/**
  * @brief  OLED初始化
  * @param  無(wú)
  * @retval 無(wú)
  */
void OLED_Init(void)
{
	uint32_t i, j;
	
	for (i = 0; i < 1000; i++)			//上電延時(shí)
	{
		for (j = 0; j < 1000; j++);
	}
	
	OLED_I2C_Init();			//端口初始化
	
	OLED_WriteCommand(0xAE);	//關(guān)閉顯示
	
	OLED_WriteCommand(0xD5);	//設(shè)置顯示時(shí)鐘分頻比/振蕩器頻率
	OLED_WriteCommand(0x80);
	
	OLED_WriteCommand(0xA8);	//設(shè)置多路復(fù)用率
	OLED_WriteCommand(0x3F);
	
	OLED_WriteCommand(0xD3);	//設(shè)置顯示偏移
	OLED_WriteCommand(0x00);
	
	OLED_WriteCommand(0x40);	//設(shè)置顯示開(kāi)始行
	
	OLED_WriteCommand(0xA1);	//設(shè)置左右方向,0xA1正常 0xA0左右反置
	
	OLED_WriteCommand(0xC8);	//設(shè)置上下方向,0xC8正常 0xC0上下反置

	OLED_WriteCommand(0xDA);	//設(shè)置COM引腳硬件配置
	OLED_WriteCommand(0x12);
	
	OLED_WriteCommand(0x81);	//設(shè)置對(duì)比度控制
	OLED_WriteCommand(0xCF);

	OLED_WriteCommand(0xD9);	//設(shè)置預(yù)充電周期
	OLED_WriteCommand(0xF1);

	OLED_WriteCommand(0xDB);	//設(shè)置VCOMH取消選擇級(jí)別
	OLED_WriteCommand(0x30);

	OLED_WriteCommand(0xA4);	//設(shè)置整個(gè)顯示打開(kāi)/關(guān)閉

	OLED_WriteCommand(0xA6);	//設(shè)置正常/倒轉(zhuǎn)顯示

	OLED_WriteCommand(0x8D);	//設(shè)置充電泵
	OLED_WriteCommand(0x14);

	OLED_WriteCommand(0xAF);	//開(kāi)啟顯示
		
	OLED_Clear();				//OLED清屏
}

1.4 實(shí)驗(yàn):旋轉(zhuǎn)編碼器計(jì)次

需求:利用stm32的外部中斷,對(duì)旋轉(zhuǎn)編碼器的轉(zhuǎn)動(dòng)進(jìn)行計(jì)次,順時(shí)針加、逆時(shí)針減,并顯示在OLED顯示屏上。
嵌入式-stm32-江科大-EXTI外部中斷,江科大-Stm32-學(xué)習(xí)筆記,嵌入式-STM32單片機(jī),stm32,單片機(jī),嵌入式硬件,mcu,#江科大上圖是旋轉(zhuǎn)編碼器計(jì)次的接線圖,下圖是代碼調(diào)用(除庫(kù)函數(shù)以外)
嵌入式-stm32-江科大-EXTI外部中斷,江科大-Stm32-學(xué)習(xí)筆記,嵌入式-STM32單片機(jī),stm32,單片機(jī),嵌入式硬件,mcu,#江科大
main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "CountSensor.h"
#include "Encoder.h"

int16_t Num;			//定義待被旋轉(zhuǎn)編碼器調(diào)節(jié)的變量

int main(void)
{
	/*模塊初始化*/
	OLED_Init();			//OLED初始化
	CountSensor_Init();		//計(jì)數(shù)傳感器初始化
	Encoder_Init();            //旋轉(zhuǎn)編碼器初始化
	
	/*顯示靜態(tài)字符串*/
	OLED_ShowString(1, 1, "Num:");	//1行1列顯示字符串Count:
	OLED_ShowString(2, 1, "Num+=:");	//1行1列顯示字符串Count:
	while (1)
	{	
		Num += Encoder_Get();
		OLED_ShowSignedNum(1, 7, CountSensor_Get(), 5);		//OLED不斷刷新顯示CountSensor_Get的返回值
		OLED_ShowSignedNum(2,8,Num,5);     //顯示Num
	}
}

Encoder.h

#ifndef __ENCODER_H
#define __ENCODER_H

void Encoder_Init(void);
int16_t Encoder_Get(void);

#endif

Encoder.c

#include "stm32f10x.h"

int16_t Encoder_Count;  //全局變量,用于計(jì)數(shù)旋轉(zhuǎn)編碼器的增量值

void Encoder_Init(void)//旋轉(zhuǎn)編碼器初始化
{
	  /*開(kāi)啟時(shí)鐘*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);		//開(kāi)啟GPIOB的時(shí)鐘
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);		//開(kāi)啟AFIO的時(shí)鐘,外部中斷必須開(kāi)啟AFIO的時(shí)鐘
	
	/*GPIO初始化*/
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;//AB相分別接的是PB0和PB1
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);						//將PB0和PB1引腳初始化為上拉輸入
	
	/*AFIO選擇中斷引腳*/
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource0);//將外部中斷的0號(hào)線映射到GPIOB,即選擇PB0為外部中斷引腳
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource1);//將外部中斷的1號(hào)線映射到GPIOB,即選擇PB1為外部中斷引腳
	
	/*EXTI初始化*/
	EXTI_InitTypeDef EXTI_InitStructure;						//定義結(jié)構(gòu)體變量
	EXTI_InitStructure.EXTI_Line = EXTI_Line0 | EXTI_Line1;		//選擇配置外部中斷的0號(hào)線和1號(hào)線
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;					//指定外部中斷線使能
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;			//指定外部中斷線為中斷模式
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;		//指定外部中斷線為下降沿觸發(fā)
	EXTI_Init(&EXTI_InitStructure);								//將結(jié)構(gòu)體變量交給EXTI_Init,配置EXTI外設(shè)
	
	/*NVIC中斷分組*/
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);				//配置NVIC為分組2
																//即搶占優(yōu)先級(jí)范圍:0~3,響應(yīng)優(yōu)先級(jí)范圍:0~3
																//此分組配置在整個(gè)工程中僅需調(diào)用一次
																//若有多個(gè)中斷,可以把此代碼放在main函數(shù)內(nèi),while循環(huán)之前
																//若調(diào)用多次配置分組的代碼,則后執(zhí)行的配置會(huì)覆蓋先執(zhí)行的配置
	
	/*NVIC配置*/
	NVIC_InitTypeDef NVIC_InitStructure;						//定義結(jié)構(gòu)體變量
	NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;			//選擇配置NVIC的EXTI0線
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;				//指定NVIC線路使能
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;	//指定NVIC線路的搶占優(yōu)先級(jí)為1
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;			//指定NVIC線路的響應(yīng)優(yōu)先級(jí)為1
	NVIC_Init(&NVIC_InitStructure);								//將結(jié)構(gòu)體變量交給NVIC_Init,配置NVIC外設(shè)

	NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;			//選擇配置NVIC的EXTI1線
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;				//指定NVIC線路使能
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;	//指定NVIC線路的搶占優(yōu)先級(jí)為1
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;			//指定NVIC線路的響應(yīng)優(yōu)先級(jí)為2
	NVIC_Init(&NVIC_InitStructure);		

}


//打算每次調(diào)用get函數(shù)之后,返回count的變化值,用于外部加減一個(gè)變量
int16_t Encoder_Get(void)
{
	//使用Temp變量作為中繼,目的是返回Encoder_Count后將其清零,目的是給count清零
	//在這里,也可以直接返回Encoder_Count,直接返回就退出函數(shù)了沒(méi)辦法給count清零
	//下面這樣子又能獲取到count變化值,又能給count清零 
	//直接返回count會(huì)導(dǎo)致你扭一下,count就有一個(gè)值,Num就會(huì)一直變化了
	
	int16_t Temp;
	 Temp = Encoder_Count;
	 Encoder_Count= 0;
	return Temp;
}

void EXTI0_IRQHandler(void)//A口下降沿中斷函數(shù)
{
	if(EXTI_GetITStatus(EXTI_Line0) == SET)
	{
		
		if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) == 0) //PB1的下降沿觸發(fā)中斷,此時(shí)檢測(cè)另一相,等于1正轉(zhuǎn),等于0反轉(zhuǎn)
		{
			Encoder_Count --;  //此方向定義為反轉(zhuǎn),計(jì)數(shù)變量自減
		}
		
		EXTI_ClearITPendingBit(EXTI_Line0); //清除標(biāo)志中斷0號(hào)線的中斷標(biāo)志位
	}

}

void EXTI1_IRQHandler(void)//B口下降沿中斷函數(shù)
{
	if(EXTI_GetITStatus(EXTI_Line1) == SET)
	{
		if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) == 0) //PB1的下降沿觸發(fā)中斷,此時(shí)檢測(cè)另一相
		{
			Encoder_Count ++;  //此方向定義為正轉(zhuǎn),計(jì)數(shù)變量自增
		}
		
		EXTI_ClearITPendingBit(EXTI_Line1); //清除標(biāo)志中斷1號(hào)線的中斷標(biāo)志位
	}

}
1.41 編程感想
  1. 管理Hardware文件夾。本次實(shí)驗(yàn)繼承的是“OLED顯示屏”實(shí)驗(yàn)的代碼,而非“對(duì)射式紅外傳感器計(jì)次”。
  2. 注意每個(gè)模塊在使用的時(shí)候都要進(jìn)行初始化。
  3. 注意進(jìn)入中斷函數(shù)的時(shí)候要檢查中斷標(biāo)志位,,退出的時(shí)候清零中斷標(biāo)志位。
  4. 注意主函數(shù)和中斷函數(shù)不要操控同一個(gè)硬件,避免不必要的硬件沖突。中斷函數(shù)一般執(zhí)行簡(jiǎn)短快速的代碼,如操作中斷標(biāo)志位等。
  5. 在中斷函數(shù)內(nèi)部不要執(zhí)行長(zhǎng)時(shí)間函數(shù),中斷是快速的突發(fā)事件,必須要短。

參考:B站STM32江協(xié)自動(dòng)化&【哈工大虎慕】文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-824774.html

道友:沒(méi)有永久的巔峰也沒(méi)有永遠(yuǎn)的低谷,真正的強(qiáng)大不是忘記而是接受,接受世事無(wú)常、接受孤獨(dú)挫敗、接受突如其來(lái)的無(wú)力感、接受自己的不完美、接受困惑不安的焦慮和遺憾。

到了這里,關(guān)于嵌入式-stm32-江科大-EXTI外部中斷的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 嵌入式-Stm32-江科大基于標(biāo)準(zhǔn)庫(kù)的GPIO的八種模式

    嵌入式-Stm32-江科大基于標(biāo)準(zhǔn)庫(kù)的GPIO的八種模式

    (推薦先看文章:《 嵌入式-32單片機(jī)-GPIO推挽輸出和開(kāi)漏輸出》) 下文圖都是從參考手冊(cè)借閱:STM32F10xxx(中文),大概頁(yè)數(shù)是110/775左右 GPIO (General Purpose Input Output)通用輸入輸出口 可配置為8種輸入輸出模式 引腳電平:0V~3.3V,部分引腳可容忍5V(有FT標(biāo)識(shí)) 輸出模式 下可控

    2024年01月20日
    瀏覽(95)
  • 嵌入式-Stm32-江科大基于標(biāo)準(zhǔn)庫(kù)的GPIO4個(gè)小實(shí)驗(yàn)

    嵌入式-Stm32-江科大基于標(biāo)準(zhǔn)庫(kù)的GPIO4個(gè)小實(shí)驗(yàn)

    核心:本文共4個(gè)小實(shí)驗(yàn): 第一個(gè):LED燈閃爍 第二個(gè):LED流水燈 第三個(gè):按鍵控制LED 第四個(gè):光敏傳感器控制蜂鳴器 1.1 LED、蜂鳴器、面包板 LED:發(fā)光二極管,正向通電點(diǎn)亮,反向通電不亮。 有源蜂鳴器(本實(shí)驗(yàn)):內(nèi)部自帶振蕩源,將正負(fù)極接上直流電壓即可持續(xù)發(fā)聲,頻

    2024年01月21日
    瀏覽(30)
  • 【嵌入式學(xué)習(xí)筆記】嵌入式入門2——中斷(外部中斷)

    【嵌入式學(xué)習(xí)筆記】嵌入式入門2——中斷(外部中斷)

    打斷CPU執(zhí)行正常的程序,轉(zhuǎn)而處理緊急程序,然后返回原暫停的程序繼續(xù)運(yùn)行,就叫中斷 作用1: 實(shí)時(shí)控制在確定時(shí)間內(nèi)對(duì)相應(yīng)事件作出響應(yīng) ——定時(shí)器中斷 作用2: 故障處理檢測(cè)到故障,需要第一時(shí)間處理 ——外部中斷 作用3: 數(shù)據(jù)傳輸不確定數(shù)據(jù)何時(shí)會(huì)來(lái) ——串口中斷

    2024年02月08日
    瀏覽(66)
  • STM32--EXTI外部中斷

    STM32--EXTI外部中斷

    前文回顧---STM32--GPIO 相關(guān)回顧--有關(guān)中斷系統(tǒng)簡(jiǎn)介 目錄 STM32中斷 NVIC ?EXTI外部中斷 AFIO EXTI框圖 旋轉(zhuǎn)編碼器簡(jiǎn)介 對(duì)射式紅外傳感器工程 代碼: 旋轉(zhuǎn)編碼器工程 代碼: 先說(shuō)一下 基本原理 : 1. 中斷請(qǐng)求發(fā)生 :外部事件(如按鍵觸發(fā),定時(shí)器溢出等)引起中斷請(qǐng)求信號(hào); 2. 中

    2024年02月12日
    瀏覽(21)
  • 02:STM32--EXTI外部中斷

    02:STM32--EXTI外部中斷

    目錄 一:中斷 1:簡(jiǎn)歷 2:AFIO ?3:EXTI ?編輯 ?4:NVIC基本結(jié)構(gòu) 5:使用步驟 二:中斷的應(yīng)用 A:對(duì)外式紅外傳感計(jì)數(shù)器 1:連接圖?編輯 ?2:函數(shù)介紹 3:硬件介紹 ?4:計(jì)數(shù)代碼 B;旋轉(zhuǎn)編碼計(jì)數(shù)器 1:連接圖 ?2:硬件介紹 3:旋轉(zhuǎn)編碼器代碼: ????? ???中斷 :在主程序運(yùn)行過(guò)程中,出現(xiàn)了特定

    2024年02月13日
    瀏覽(16)
  • 【STM32】STM32學(xué)習(xí)筆記-EXTI外部中斷(11)

    【STM32】STM32學(xué)習(xí)筆記-EXTI外部中斷(11)

    中斷 :在主程序運(yùn)行過(guò)程中,出現(xiàn)了特定的中斷觸發(fā)條件(中斷源),使得CPU暫停當(dāng)前正在運(yùn)行的程序,轉(zhuǎn)而去處理中斷程序,處理完成后又返回原來(lái)被暫停的位置繼續(xù)運(yùn)行 中斷優(yōu)先級(jí) :當(dāng)有多個(gè)中斷源同時(shí)申請(qǐng)中斷時(shí),CPU會(huì)根據(jù)中斷源的輕重緩急進(jìn)行裁決,優(yōu)先響應(yīng)更加

    2024年02月04日
    瀏覽(21)
  • STM32標(biāo)準(zhǔn)庫(kù)——(5)EXTI外部中斷

    STM32標(biāo)準(zhǔn)庫(kù)——(5)EXTI外部中斷

    中斷 :在主程序運(yùn)行過(guò)程中,出現(xiàn)了特定的中斷觸發(fā)條件(中斷源),使得CPU暫停當(dāng)前正在運(yùn)行的程序,轉(zhuǎn)而去處理中斷程序,處理完成后又返回原來(lái)被暫停的位置繼續(xù)運(yùn)行 中斷優(yōu)先級(jí) :當(dāng)有多個(gè)中斷源同時(shí)申請(qǐng)中斷時(shí),CPU會(huì)根據(jù)中斷源的輕重緩急進(jìn)行裁決,優(yōu)先響應(yīng)更加

    2024年02月20日
    瀏覽(56)
  • 嵌入式學(xué)習(xí)筆記——STM32的USART收發(fā)字符串及串口中斷

    嵌入式學(xué)習(xí)筆記——STM32的USART收發(fā)字符串及串口中斷

    上一篇中,介紹了串口收發(fā)相關(guān)的寄存器,通過(guò)代碼實(shí)現(xiàn)了一個(gè)字節(jié)的收發(fā),本文接著上面的內(nèi)容,通過(guò)功能函數(shù)實(shí)現(xiàn)字符串的收發(fā),然后引入中斷解決收發(fā)過(guò)程中while()死等的問(wèn)題。 根據(jù)昨天的字符發(fā)送函數(shù),只需要稍作修改即可實(shí)現(xiàn)發(fā)送函數(shù)了,一個(gè)字符串的結(jié)尾會(huì)有一

    2024年02月03日
    瀏覽(36)
  • 【STM32教程】第四章 STM32的外部中斷EXTI

    【STM32教程】第四章 STM32的外部中斷EXTI

    案例代碼及相關(guān)資料下載鏈接: 鏈接:https://pan.baidu.com/s/1hsIibEmsB91xFclJd-YTYA?pwd=jauj? 提取碼:jauj?? 中斷系統(tǒng)的定義:中斷是指在主程序運(yùn)行過(guò)程中,出現(xiàn)了特定的中斷觸發(fā)條件(中斷源),使得CPU暫停當(dāng)前正在運(yùn)行的程序,轉(zhuǎn)而去處理中斷程序,處理完成后又返回原來(lái)被暫

    2024年02月09日
    瀏覽(28)
  • 嵌入式開(kāi)發(fā)--STM32用DMA+IDLE中斷方式串口接收不定長(zhǎng)數(shù)據(jù)

    嵌入式開(kāi)發(fā)--STM32用DMA+IDLE中斷方式串口接收不定長(zhǎng)數(shù)據(jù)

    之前講過(guò)用 利用IDLE空閑中斷來(lái)接收不定長(zhǎng)數(shù)據(jù) ,但是沒(méi)有用到DMA,其實(shí)用DMA會(huì)更加的高效,MCU也可以騰出更多的性能去處理應(yīng)該做的事情。 IDLE顧名思義,就是空閑的意思,即當(dāng)監(jiān)測(cè)到串口空閑超過(guò)1個(gè)串口的數(shù)據(jù)幀時(shí),會(huì)使?fàn)顟B(tài)寄存器(SR或ISR)的IDLE位置位,如果此時(shí)控制

    2024年04月17日
    瀏覽(39)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包