stm32 外部中断学习
生活随笔
收集整理的這篇文章主要介紹了
stm32 外部中断学习
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
今天我們看看STM32的外部中斷實驗。
STM32 供 IO 口使用的中斷線只有 16 個,但是 STM32 的 IO 口卻遠遠不止 16 個,那么 STM32 是怎么把 16 個中斷線和 IO 口一一對應起來的呢?
STM32 這樣設計,GPIO 的管腳 GPIOx.0 ~ GPIOx.15 (x=A,B,C,D,E,F,G)分別對應中斷線 0~15.
這樣每個中斷線對應了 7 個 IO 口。以線 0 為例:它對應了 GPIOA.0、GPIOB.0、GPIOC.0、GPIOD.0、GPIOE.0、GPIOF.0、GPIOG.0。
但是一根中斷線每次只能連接到 1 個 IO 口上,這就需要通過配置來決定連到哪個IO口。
下面我們看看 GPIO 跟中斷線的映射關系圖:?
只截取了部分,但是其中的關系一目了然。舉例說,假如0號線和PA0相連,那么用的庫函數是:
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);
這個實驗,我們通過按鍵來觸發外部中斷。按鍵的電路原理圖如下:
這里從上到下4個按鍵分別接到MCU的PA0,PE4,PE3,PE2.
我們看看代碼。
首先是IO口的配置。
void key_init(void) { GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOE,ENABLE);//PORTA,PORTE時鐘使能//KEY0-->GPIOE.4, KEY1-->GPIOE.3, KEY2-->GPIOE.2,GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4; //PE2~4GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉輸入GPIO_Init(GPIOE, &GPIO_InitStructure);//WK_UP-->GPIOA.0 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //下拉輸入GPIO_Init(GPIOA, &GPIO_InitStructure);}
void EXTIx_Init(void) {EXTI_InitTypeDef EXTI_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //通過AFIO_EXTICRx配置GPIO線上的外部中斷/事件,必須先使能AFIO時鐘//注意:只有使用了AFIO的事件控制寄存器、AFIO的重映射功能以及外部中斷(EXTI)控制寄存器才需要開啟AFIO的時鐘//GPIOE.2-4中斷線的配置GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2);GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource3);GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource4);EXTI_InitStructure.EXTI_Line = EXTI_Line2 | EXTI_Line3 | EXTI_Line4; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿觸發EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure); //GPIOA.0中斷線配置GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0); EXTI_InitStructure.EXTI_Line = EXTI_Line0;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; //上升沿觸發EXTI_Init(&EXTI_InitStructure); //優先級配置NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure);NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); }
最后是中斷服務函數。
#define KEY3 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)//讀取按鍵WK_UPvoid EXTI0_IRQHandler(void) {delay_ms(10); //消除抖動if(KEY3==1) //WK_UP{ printf("您按下的是 WK_UP \r\n\r\n");}EXTI_ClearITPendingBit(EXTI_Line0); //清除中斷標志位 }其他服務函數類似,就不貼了。
看看實驗效果吧。
總結
以上是生活随笔為你收集整理的stm32 外部中断学习的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: stm32串口学习(二)
- 下一篇: stm32 独立看门狗学习