娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

歷史上的今天

今天是:2024年09月01日(星期日)

正在發生

2021年09月01日 | STM32—中斷詳解(配合按鍵中斷代碼,代碼親測)

發布者:快樂微笑 來源: eefocus關鍵字:STM32  中斷  按鍵中斷 手機看文章 掃描二維碼
隨時隨地手機看文章

在STM32中執行中斷主要分三部分:

1.配置NVIC_Config()函數

2.配置EXTI_Config()函數

3.編寫中斷服務函數

(注:本文章所用代碼為中斷按鍵代碼,實現了按鍵進入中斷從而控制LED亮滅)


配置NVIC_Config()函數

NVIC 是嵌套向量中斷控制器,控制著整個芯片中斷相關的功能,它跟內核緊密耦合,是內核里面的一個外設。

NVIC_Config()函數代碼如下:


static void NVIC_Config(void) /* 主要是配置中斷源的優先級與打開使能中斷通道 */

{

NVIC_InitTypeDef NVIC_InitStruct ;

/* 配置中斷優先級分組(設置搶占優先級和子優先級的分配),在函數在misc.c */

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1) ;

/* 配置初始化結構體 在misc.h中 */

/* 配置中斷源 在stm32f10x.h中 */

NVIC_InitStruct.NVIC_IRQChannel = KEY1_EXTI_IRQN ;

/* 配置搶占優先級 */

NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1 ;

/* 配置子優先級 */

NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0 ;

/* 使能中斷通道 */

NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE ;

/* 調用初始化函數 */

NVIC_Init(&NVIC_InitStruct) ;

/* 對key2執行相同操作 */

NVIC_InitStruct.NVIC_IRQChannel = KEY2_EXTI_IRQN ;

NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1 ;

NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1 ;

NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE ;

NVIC_Init(&NVIC_InitStruct) ;

}


配置NVIC_Config()的目的是選擇中斷源的優先級以及打開中斷通道,主要功能通過配置NVIC初始化結構體NVIC_InitStruct來完成。通俗的講,STM32中有很多中斷,而當有多個中斷同時發生時就涉及到中斷執行的先后問題了,所以引入了中斷優先級的概念,中斷優先級越高中斷就越先執行。在這里我們只討論外部中斷的優先級,在 NVIC 有一個專門的寄存器:中斷優先級寄存器 NVIC_IPRx,用來配置外部中斷的優先級。優先級高低的比較包括搶占優先級和子優先級,先比較搶占優先級,如果搶占優先級相同就比較子優先級,從而得出中斷之間的優先級高低。NVIC的主要任務就是給對應的中斷源分配中斷優先級。 中斷優先級分配的原理繁雜,但固件庫編程的好處就是化繁為簡,我們只需要按照NVIC_InitStruct()中的內容進行配置就行。


接下來簡單講解一下NVIC_Config()函數的內容:


1.首先設置中斷優先級分組

中斷優先級分組其實是確立一個大綱,中斷優先級寄存器 NVIC_IPRx中有4個位用來確定優先級,中斷優先級的分組就是把這4個位分配在搶占優先級和子優先級中。比如設定一個位配置搶占優先級,其余三個位配置子優先級。通過函數NVIC_PriorityGroupConfig() ; 實現分組,詳細代碼如下:


1 /**

2 * 配置中斷優先級分組:搶占優先級和子優先級

3 * 形參如下:

4 * @arg NVIC_PriorityGroup_0: 0bit for 搶占優先級

5 *                       4 bits for 子優先級

6 * @arg NVIC_PriorityGroup_1: 1 bit for 搶占優先級

7 *                            3 bits for 子優先級

8 * @arg NVIC_PriorityGroup_2: 2 bit for 

9 *                            2 bits for 子優先級

10 * @arg NVIC_PriorityGroup_3: 3 bit for 搶占優先級

11 *                           1 bits for 子優先級

12 * @arg NVIC_PriorityGroup_4: 4 bit for 搶占優先級

13 *                           0 bits for 子優先級

14 * @注意 如果優先級分組為 0,則搶占優先級就不存在,優先級就全部由子優先級控制

15 */

16 void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)

17 {

18 // 設置優先級分組

19 SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;

20 }


2.優先級分組完畢后,是配置NVIC初始化結構體


typedef struct {

2 uint8_t NVIC_IRQChannel; // 中斷源

3 uint8_t NVIC_IRQChannelPreemptionPriority; // 搶占優先級

4 uint8_t NVIC_IRQChannelSubPriority; // 子優先級

5 FunctionalState NVIC_IRQChannelCmd; // 中斷使能或者失能

6 } NVIC_InitTypeDef;


初始化結構體的作用是,收集中斷源的信息(包括配置的是哪一個中斷源、中斷源的搶占優先級是多少、中斷源的子優先級是多少、中斷源的使能是否開啟)。


NVIC_IROChannel:用來設置中斷源,不同的中斷中斷源不一樣,且不可寫錯,即使寫錯了程序也不會報錯,只會導致不響應中斷。 stm32f10x.h 頭文件里面的 IRQn_Type 結構體定義,這個結構體包含了所有的中斷源。


NVIC_IRQChannelPreemptionPriority和NVIC_IRQChannelSubPriority 分別設置搶占優先級和子優先級,具體的值要根據中斷優先級分組來確定。


NVIC_IRQChannelCmd:設置中斷使能(ENABLE)或者失能(DISABLE),相當于一個電源總開關。


3.最后借助NVIC初始化函數將NVIC初始化結構體中的信息寫入相應的寄存器中 (體現了固件庫編程的優點,不需要我們深入到寄存器層次去,只需要掌握相應函數的配置即可)


配置EXTI_Config()函數

EXTI(External interrupt/event controller):外部中斷/事件控制器,管理了控制器的 20個中斷/事件線。每個中斷/事件線都對應有一個邊沿檢測器,可以實現輸入信號的上升沿檢測和下降沿的檢測。 EXTI 可以實現對每個中斷/事件線進行單獨配置,可以單獨配置為中斷或者事件,以及觸發事件的屬性。


按我的理解,EXTI是一個有著多達20個接口的控制器,它可以為每一個接入接口的信號源配置中斷(或事件)線、設置信號的檢測方式、設置觸發事件的性質,也就是說,傳入EXTI的僅僅是一個信號,EXTI的功能就是根據信號傳入的“線”對信號做出相應的處理,然后將處理后的信號轉向NVIC。 就像一個分揀機器,傳入的東西經過篩選處理被送往不同的地方,只是EXTI分揀的是信號罷了。 如果說NVIC是配置中斷源,那么EXTI就是向NVIC傳送中斷信號。


EXTI功能框圖:

在這里插入圖片描述

EXTI 可分為兩大部分功能,一個是產生中斷,另一個是產生事件,線路1-2-4-5是產生中斷的流程,20/代表著有20條相同的線路。


接下來講解一下EXTI_Config()函數代碼:


void EXTI_Config() /* 主要是連接EXTI與GPIO */

{

GPIO_InitTypeDef GPIO_InitStruct ;

EXTI_InitTypeDef EXTI_InitStruct ;

NVIC_Config();


/* 初始化要與EXTI連接的GPIO */

/* 開啟GPIOA與GPIOC的時鐘 */

RCC_APB2PeriphClockCmd(KEY1_EXTI_GPIO_CLK | KEY2_EXTI_GPIO_CLK, ENABLE) ;

GPIO_InitStruct.GPIO_Pin = KEY1_EXTI_GPIO_PIN ;

GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING ;

GPIO_Init(KEY1_EXTI_GPIO_PORT , &GPIO_InitStruct) ;

GPIO_InitStruct.GPIO_Pin = KEY2_EXTI_GPIO_PIN ;

GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING ;

GPIO_Init(KEY2_EXTI_GPIO_PORT , &GPIO_InitStruct) ;

/* 初始化EXTI外設 */

/* EXTI的時鐘要設置AFIO寄存器 */

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE) ;

/* 選擇作為EXTI線的GPIO引腳 */

GPIO_EXTILineConfig( KEY1_GPIO_PORTSOURCE , KEY1_GPIO_PINSOURCE) ;

/* 配置中斷or事件線 */

EXTI_InitStruct.EXTI_Line = KEY1_EXTI_LINE ;

/* 使能EXTI線 */

EXTI_InitStruct.EXTI_LineCmd = ENABLE ;

/* 配置模式:中斷or事件 */

EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt ;

/* 配置邊沿觸發 上升or下降 */

EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising ;

EXTI_Init(&EXTI_InitStruct) ;

GPIO_EXTILineConfig( KEY2_GPIO_PORTSOURCE , KEY2_GPIO_PINSOURCE) ;

EXTI_InitStruct.EXTI_Line = KEY2_EXTI_LINE ;

EXTI_InitStruct.EXTI_LineCmd = ENABLE ;

EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt ;

EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling ;

EXTI_Init(&EXTI_InitStruct);

}


代碼可大體分為三部分:

配置GPIO相應引腳、配置EXTI并連接GPIO引腳、傳入NVIC_Config()


1.配置GPIO相應引腳

該代碼是通過按鍵產生一個電平信號,然后經EXTI處理傳入NVIC產生中斷的,所以要配置連接按鍵的GPIO引腳,主要是設置相應的引腳模式為浮空輸入 。老規矩,先開啟相應GPIO的時鐘,然后配置引腳初始化結構體,再利用初始化函數將初始化結構體寫入寄存器中。


2.配置EXTI并連接GPIO引腳

要操作外設,首先要打開相關的時鐘,EXTI掛載在APB2總線上,并且開啟時鐘時要操作AFIO寄存器 ,準備工作就緒后連接GPIO相應的引腳到EXTI中,前面說了EXTI有20個接口,所以特定的引腳有特定的接口,所以要根據GPIO_EXTILineConfig();函數選擇用作EXTI線的GPIO引腳,函數說明如下


/**

  * @brief  Selects the GPIO pin used as EXTI Line.

  * @param  GPIO_PortSource: selects the GPIO port to be used as source for EXTI lines.

  *   This parameter can be GPIO_PortSourceGPIOx where x can be (A..G).

  * @param  GPIO_PinSource: specifies the EXTI line to be configured.

  *   This parameter can be GPIO_PinSourcex where x can be (0..15).

  * @retval None

  */

void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource)

{

  uint32_t tmp = 0x00;

  /* Check the parameters */

  assert_param(IS_GPIO_EXTI_PORT_SOURCE(GPIO_PortSource));

  assert_param(IS_GPIO_PIN_SOURCE(GPIO_PinSource));

  

  tmp = ((uint32_t)0x0F) << (0x04 * (GPIO_PinSource & (uint8_t)0x03));

  AFIO->EXTICR[GPIO_PinSource >> 0x02] &= ~tmp;

  AFIO->EXTICR[GPIO_PinSource >> 0x02] |= (((uint32_t)GPIO_PortSource) << (0x04 * (GPIO_PinSource & (uint8_t)0x03)));

}


其實對應的EXTI線就對應GPIO引腳號,這樣看起來還比較直觀。


連接好GPIO引腳與EXTI后就該配置EXTI的初始化結構體了,結構體如下:


typedef struct 

{

uint32_t EXTI_Line; // 中斷/事件線

EXTIMode_TypeDef EXTI_Mode; // EXTI 模式

EXTITrigger_TypeDef EXTI_Trigger; // 觸發類型

FunctionalState EXTI_LineCmd; // EXTI 使能

 } EXTI_InitTypeDef;


配置此結構體主要是:選擇相應的EXTI線 、選擇觸發模式、選擇產生的結果(中斷還是事件)、是否使能EXTI線。


EXTI_Line:中斷線選擇,可選 EXTI_0 至 EXTI_19(一共20個)。既然剛才配置好了與GPIO引腳對應的EXTI線,所以初始化結構體中的EXTI線就是與GPIO連接的那個線。


EXTI_Mode: EXTI 模式選擇,可選為產生中斷或者產生事件。就是決定信號的發展方向,是產生中斷呢?還是產生事件呢?此處是中斷。


EXTI_Trigger: EXTI 邊沿觸發模式,可選上升沿觸發、下降 沿 觸 發 或 者 上 升 沿 和 下 降 沿 都 觸 發。觸發信號。


EXTI_LineCmd:控制是否使能 EXTI 線,可選使能 EXTI 線或禁用。


初始化結構體配置完畢后交由初始化函數寫入相應的寄存器中。


3.傳入NVIC_Config()

之后就自動傳入NVIC中了。。。


編寫中斷服務函數

到這里就萬事俱備只欠東風了,中斷的觸發與處理及優先級定義都已經安排上了,最后一步就是編寫中斷函數的內容了,只要進入中斷就會執行中斷函數中的代碼,所以這是收尾工作。STM32的中斷服務函數不同于51單片機中的中斷服務函數,STM32的所有中斷函數都被偷偷安排了,每個中斷都有其固定的名字,只有找到這個名字,在這個固定的函數名下編寫中斷服務函數才是有效的,所有中斷函數的編寫都要在stm32f10x_it.c 中,如示:

在這里插入圖片描述

從所給的信息可得知外設的中斷服務函數的名字都存放在startup_stm32f10x_xx.s 中,而且是由匯編語言編寫,如示:

在這里插入圖片描述

可知EXTI線0到EXTI線4線都是單獨的中斷函數名、EXTI線5到EXTI線9共用一個中斷函數名、EXTI線10線到EXTI線15線共用一個中斷函數名。


我們要做的就是以相應的EXTI線的中斷函數名字在stm32f10x_it.c中編寫中斷函數 如下:


void EXTI0_IRQHandler(void)

{

if(  EXTI_GetITStatus(KEY1_EXTI_LINE)!=RESET)

{

LED1_TOGGLE;   //LED1的亮滅狀態反轉

}

EXTI_ClearITPendingBit(KEY1_EXTI_LINE);

}


void EXTI15_10_IRQHandler(void)

{

if(  EXTI_GetITStatus(KEY2_EXTI_LINE)!=RESET)

{

LED2_TOGGLE;   //LED2的亮滅狀態反轉

}

EXTI_ClearITPendingBit(KEY2_EXTI_LINE);

}


每次進入中斷函數后,靠ITStatus EXTI_GetITStatus(uint32_t EXTI_Line)讀取中斷是否執行 ,執行完之后要利用void EXTI_ClearITPendingBit(uint32_t EXTI_Line)清除清除中斷標志位,以免不斷進入中斷


大功告成

到此完整的中斷系統就已經完成,主函數只需調用即可!!!

(附上主函數及倆個頭文件)

希望可以一起交流學習

qq:2723808286


#include "stm32f10x.h"

#include "bsp_led.h"

#include "bsp_key.h"


int main(void)

LED_GPIO_Config();

EXTI_Config();

while(1) 

{

}

}


#ifndef __BSP_KEY_H

#define __BSP_KEY_H


#include "stm32f10x.h"


#define KEY1_EXTI_GPIO_CLK      RCC_APB2Periph_GPIOA

#define KEY1_EXTI_GPIO_PORT     GPIOA

#define KEY1_EXTI_GPIO_PIN      GPIO_Pin_0

#define KEY1_EXTI_IRQN          EXTI0_IRQn      /* 對應著引腳號 */

#define KEY1_EXTI_LINE          EXTI_Line0      /* 中斷、事件線對應引腳號 */

#define KEY1_GPIO_PORTSOURCE    GPIO_PortSourceGPIOA

#define KEY1_GPIO_PINSOURCE     GPIO_PinSource0

#define  KEY1_EXTI_IRQHANDLER       EXTI0_IRQHandler


#define KEY2_EXTI_GPIO_CLK      RCC_APB2Periph_GPIOC

#define KEY2_EXTI_GPIO_PORT     GPIOC

#define KEY2_EXTI_GPIO_PIN      GPIO_Pin_13

#define KEY2_EXTI_IRQN          EXTI15_10_IRQn

#define KEY2_EXTI_LINE          EXTI_Line13

#define KEY2_GPIO_PORTSOURCE    GPIO_PortSourceGPIOC

#define KEY2_GPIO_PINSOURCE     GPIO_PinSource13

#define  KEY2_EXTI_IRQHANDLER       EXTI15_10_IRQHandler


void EXTI_Config(void);

#endif


#ifndef __BSP_LED_H

#define __BSP_LED_H


#include "stm32f10x.h"


#define LED1_GPIO_CLK   RCC_APB2Periph_GPIOC   /*時鐘*/

#define LED1_GPIO_PORT  GPIOC                  /*端口*/

#define LED1_GPIO_PIN   GPIO_Pin_2             /*引腳*/



#define LED2_GPIO_PIN   GPIO_Pin_3

#define LED2_GPIO_CLK   RCC_APB2Periph_GPIOC

#define LED2_GPIO_PORT  GPIOC


#define digitalTOGGLE(p,i)     {p->ODR ^=i;}

#define LED1_TOGGLE            digitalTOGGLE(LED1_GPIO_PORT,LED1_GPIO_PIN)

[1] [2]
關鍵字:STM32  中斷  按鍵中斷 引用地址:STM32—中斷詳解(配合按鍵中斷代碼,代碼親測)

上一篇:STM32—重定向printf和getchar函數到串口
下一篇:STM32—串口通訊詳解

0

推薦閱讀

隨著人工智能技術的不斷發展與應用,更多機器人服務場景的應用落地,人機交互將成為新時代的常態。對于電銷外呼行業,無論是電話銷售還是客服中心,智能電話機器人不僅可以幫助企業節約成本、降低人力成本,還能大幅度地提升電銷外呼工作效率,是人工電銷人員的最佳助手。其利用分析、知識工程、及智能語音等技術作為智能客服體系將開創智能交互服務與人...
“傳統工業機器人發展受到了一定制約,新一代的機器人增長乏力,新的公司在不斷倒閉關門,是不是機器人的冬天來了?還是機器人正處于進入春天的過渡期,也就是所謂的‘倒春寒’,即將迎來新的發展機遇?”在2019世界機器人大會現場,新松機器人自動化股份有限公司創始人、總裁曲道奎拋出了這個問題。 根據國際機器人聯合會數據,在全球經濟發展滯緩的環...
北斗22nm芯片一年內普及,將領先GPS兩代工藝據《中國經營報》8月31日報道,北斗正在為國產芯片“突圍”打開一道缺口。8月初,北斗三號全球衛星導航系統宣布正式商用后,近日中國衛星導航系統管理辦公室主任、北斗衛星導航系統新聞發言人冉承其在國新辦發布會上表示,北斗系統28nm工藝芯片已經量產,22nm工藝芯片即將量產。集微點評:隨著北斗應用逐步普及...
盡管當今的車輛在多種駕駛場景中實現了自動化,但背后真正推動汽車從部分自動駕駛實現全自動駕駛的不是汽車制造商,而是移動服務提供商,例如出租車公司、汽車租賃公司、送貨服務公司以及需要提供安全、高效、方便且經濟實用的公共和私人交通工具的城市。在完全自主的自動駕駛汽車駛上公共道路之前,它必須經歷六個不同的自動化等級,即從0級(無自動化)...

史海拾趣

問答坊 | AI 解惑

電源開關問題

我想用MOS管作為15V電壓的開關,3V的IO控制MOS管的導通狀態,仿真了一下,發現不好用,請各位大俠給點建議。 下面是電路:…

查看全部問答∨

有感于設計和抄板

看到壇子里童鞋們在討論研發與抄襲的問題,特轉來一篇很不錯的文章,供大家參考。 說起抄板,其實我們10多年前就在干。     那是92、3年的一個夏天,在原來單位當電工,維修數控洗煤機的控制柜(我記得是夏天,印象很深:著短褲、汗衫 ...…

查看全部問答∨

10MBd Digital Optocoupler

10MBd Digital Optocoupler for High Insulation Voltage Applications Avago Technologies announced the release of a 10MBd Digital Optocoupler with high Insulation Voltage ratings for power supply and high-power motor control applic ...…

查看全部問答∨

The Future of DSP

The Future of DSPBy Gene Frantz, TI principal fellow  …

查看全部問答∨

6440/6443 SD controller DMA傳輸異常

自己寫了個簡單的SD Driver,從SD外設以DMA方式讀取數據時,碰到個奇怪的問題。 block size是512字節,傳輸的block是1024個block,DMA buffer boundary 是512KB。 對于所使用的DMA buffer,如果使用config.bib中Reserve的RAM,則可以正常進行DMA傳 ...…

查看全部問答∨

紅外線發射頻率檢測

各位大蝦,從幾個不同頻率的紅外發射器,如何讓機子識別頻率并且讀出相應的頻率 例如有兩個紅處發射器,分別是38k和42k頻率,現在我要讓自己的機子識別出從這兩個發射器中發射出來的頻率,如果是38K發射的在LCD中讀出“38”。 請問各位大蝦如何實 ...…

查看全部問答∨

快瘋了!為什么NdisAllocateMemoryWithTag藍屏!

NdisAllocateMemoryWithTag(&pChecksum,tcphdrlen,TAG); 此申請內存語句!但是一直藍屏!不知道為什么! DRIVER_CORRUPTED_EXPOOL (c5) An attempt was made to access a pageable (or completely invalid) address at an interrupt request ...…

查看全部問答∨

入網許可,認證相關

我想用單片機+gprs模塊建立一個簡易的遠程監控系統,在gprs模塊已有相關認證的情況下,如果我的系統想成為產品的話還需不需要到相關部門進行認證?比如說對整機或電路板設計方面的,還有入網許可方面的?請了解這方面的大蝦多多指教。 …

查看全部問答∨

那位大哥大姐了解vxWorks!

我需要一個程序,是關于VXWORKS的,具體要求是開兩個同步執行的任務,一個任務寫數據,一個任務讀數據,只要寫了新數據,另一個任務就讀取,那位大哥幫幫忙,發個代碼,必有重謝 ,QQ2 4 1 0 3 7 2 8 9.…

查看全部問答∨

跟STM32,難啊!

資料中文化速度太慢,出新片子太慢.產品線不全.ST跟LM在M3芯片應該是差不多同一個時候推出的,LM的產品多到眼花.ST的點著手指都能數出來.…

查看全部問答∨
小廣播
添点儿料...
无论热点新闻、行业分析、技术干货……
設計資源 培訓 開發板 精華推薦

最新單片機文章
何立民專欄 單片機及嵌入式寶典

北京航空航天大學教授,20余年來致力于單片機與嵌入式系統推廣工作。

 
EEWorld訂閱號

 
EEWorld服務號

 
汽車開發圈

 
機器人開發圈

電子工程世界版權所有 京ICP證060456號 京ICP備10001474號-1 電信業務審批[2006]字第258號函 京公網安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 安义县| 久治县| 石泉县| 双鸭山市| 河津市| 金华市| 奎屯市| 崇阳县| 新竹县| 阿荣旗| 泸州市| 土默特左旗| 南华县| 尖扎县| 济阳县| 永德县| 响水县| 休宁县| 潞西市| 渑池县| 瓮安县| 永和县| 永修县| 广丰县| 西充县| 新疆| 通城县| 梅州市| 江孜县| 都安| 鄂尔多斯市| 新安县| 沙坪坝区| 巴林左旗| 浦北县| 惠水县| 恩施市| 安义县| 北票市| 建湖县| 新竹市|