中斷系統
- 中斷:在主程序運行過程中,出現了特定的中斷觸發條件(中斷源),使得CPU暫停當前正在運行的程序,轉而去處理中斷程序,處理完成后又返回原來被暫停的位置繼續運行
- 中斷優先級:當有多個中斷源同時申請中斷時,CPU會根據中斷源的輕重緩急進行裁決,優先響應更加緊急的中斷源
- 中斷嵌套:當一個中斷程序正在運行時,又有新的更高優先級的中斷源申請中斷,CPU再次暫停當前中斷程序,轉而去處理新的中斷程序,處理完成后依次進行返回
中斷執行流程
?????
?????
NVIC基本結構
CPU相當于一個醫生,NVIC相當于叫號系統,EXTI、TIM、ADC、USART相當于病人,看這里面誰的更緊急誰就優先級越小。
NVIC優先級分組
響應優先級:上個病人在看病,這個病人看病完了之后,緊急的病人即使后來的,也會最先進去看病,插隊的優先級。
搶占優先級:如果這個病人更加緊急,并且此時已經有人在看病,那么就會把看病的人放在一邊,先讓更緊急的病人看病,看完之后再看放在一邊的病人。
EXTI簡介
- EXTI(Extern Interrupt)外部中斷
- EXTI可以監測指定GPIO口的電平信號,當其指定的GPIO口產生電平變化時,EXTI將立即向NVIC發出中斷申請,經過NVIC裁決后即可中斷CPU主程序,使CPU執行EXTI對應的中斷程序
- 支持的觸發方式:上升沿/下降沿/雙邊沿/軟件觸發
- 支持的GPIO口:所有GPIO口,但相同的Pin不能同時觸發中斷
- 通道數:16個GPIO_Pin,外加PVD輸出、RTC鬧鐘、USB喚醒、以太網喚醒
- 觸發響應方式:中斷響應/事件響應
EXTI基本結構
AFIO復用IO口
- AFIO主要用于引腳復用功能的選擇和重定義
- 在STM32中,AFIO主要完成兩個任務:復用功能引腳重映射、中斷引腳選擇
EXTI框圖
旋轉編碼器介紹
- 旋轉編碼器:用來測量位置、速度或旋轉方向的裝置,當其旋轉軸旋轉時,其輸出端可以輸出與旋轉速度和方向對應的方波信號,讀取方波信號的頻率和相位信息即可得知旋轉軸的速度和方向
- 類型:機械觸點式/霍爾傳感器式/光柵式
建議
盡量別在中斷函數里調用復雜函數,可以執行一個標志位,在主函數或其他函數里執行其他代碼。
代碼部分
配置流程
1、開啟時鐘;
2、開啟AFIO時鐘;
3、GPIO配置;
4、選擇用作EXTI線路的GPIO引腳;
5、EXTI配置;
6、配置NVIC優先級分組;
7、NVIC配置;
8、找到EXTI函數并在里面寫用戶代碼(在startup_stm32f10x_md.s中)。
中斷配置
1 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // 1.開啟GPIOB時鐘2 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); // 2.開啟AFIO時鐘3 4 GPIO_InitTypeDef GPIO_InitStructure; // 3.GPIO配置5 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;6 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;7 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;8 GPIO_Init(GPIOB, &GPIO_InitStructure);9 10 GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14); // 4.選擇用作EXTI線路的GPIO引腳 11 12 EXTI_InitTypeDef EXTI_InitStructure; // 5.EXTI配置 13 EXTI_InitStructure.EXTI_Line = EXTI_Line14; 14 EXTI_InitStructure.EXTI_LineCmd = ENABLE; 15 EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; 16 EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; 17 EXTI_Init(&EXTI_InitStructure); 18 19 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 6.配置NVIC優先級分組 20 21 NVIC_InitTypeDef NVIC_InitSturcture; // 7.NVIC配置 22 NVIC_InitSturcture.NVIC_IRQChannel = EXTI15_10_IRQn; 23 NVIC_InitSturcture.NVIC_IRQChannelCmd = ENABLE; 24 NVIC_InitSturcture.NVIC_IRQChannelPreemptionPriority = 1; 25 NVIC_InitSturcture.NVIC_IRQChannelSubPriority = 1; 26 NVIC_Init(&NVIC_InitSturcture);
1 void EXTI15_10_IRQHandler(void) // 8.找到EXTI函數并在里面寫用戶代碼(函數在Startup_stm32f10x_md.s)2 {3 if (EXTI_GetITStatus(EXTI_Line14) == SET)4 { 5 if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) == 0)6 {7 CountSensor_Count++;8 } 9 EXTI_ClearITPendingBit(EXTI_Line14); 10 } 11 }