南寧軟件優(yōu)化網(wǎng)站建設超級外鏈
一,中斷系統(tǒng)的介紹
中斷:在主程序運行過程中,出現(xiàn)了特定的中斷觸發(fā)條件(中斷源),使得CPU暫停當前正在運行的程序,轉而去處理中斷程序,處理完成后又返回原來被暫停的位置繼續(xù)運行
中斷優(yōu)先級:當有多個中斷源同時申請中斷時,CPU會根據(jù)中斷源的輕重緩急進行裁決,優(yōu)先響應更加緊急的中斷源
中斷嵌套:當一個中斷程序正在運行時,又有新的更高優(yōu)先級的中斷源申請中斷,CPU再次暫停當前中斷程序,轉而去處理新的中斷程序,處理完成后依次進行返回
中斷通道,包含EXTI、TIM、ADC、USART、SPI、I2C、RTC等多個外設
使用NVIC統(tǒng)一管理中斷,每個中斷通道都擁有16個可編程的優(yōu)先等級,可對優(yōu)先級進行分組,進一步設置搶占優(yōu)先級和響應優(yōu)先級
具體串口通道需要查看手冊
二,NVIC(嵌套中斷向量控制器)
1,框架介紹
在stm32中,用來統(tǒng)一分配中斷優(yōu)先級和管理中斷的
2,NVIC優(yōu)先級分組
NVIC的中斷優(yōu)先級由優(yōu)先級寄存器的4位(0~15)決定,這4位可以進行切分,分為高n位的搶占優(yōu)先級和低4-n位的響應優(yōu)先級
搶占優(yōu)先級高的可以中斷嵌套,響應優(yōu)先級高的可以優(yōu)先排隊,搶占優(yōu)先級和響應優(yōu)先級均相同的按中斷號排隊
三,EXTI(外部中斷)介紹
1,介紹
- EXTI可以監(jiān)測指定GPIO口的電平信號,當其指定的GPIO口產生電平變化時,EXTI將立即向NVIC發(fā)出中斷申請,經過NVIC裁決后即可中斷CPU主程序,使CPU執(zhí)行EXTI對應的中斷程序
- 支持的觸發(fā)方式:上升沿/下降沿/雙邊沿/軟件觸發(fā)
- 支持的GPIO口:所有GPIO口,但相同的Pin不能同時觸發(fā)中斷(即不能PA1和PB1組合)
- 通道數(shù):16個GPIO_Pin,外加PVD輸出、RTC鬧鐘、USB喚醒、以太網(wǎng)喚醒
- 觸發(fā)響應方式:中斷響應/事件響應
2,EXTI基本結構
3,EXTI框圖
4,AFIO復用IO口
AFIO主要用于引腳復用功能的選擇和重定義
在STM32中,AFIO主要完成兩個任務:復用功能引腳重映射、中斷引腳選擇
5,庫函數(shù)介紹
1,配置外部中斷的流程:
- 1,配置RCC,把涉及的外設時鐘都打開
- 2,配置GPIO,選擇端口的輸入模式
- 3,配置AFIO
- 4,配置EXTI,選擇邊沿的觸發(fā)方式(比如:上升沿,下降沿或者雙邊沿),還有選擇中斷響應和事件響應
- 5,配置NVIC,給中斷選擇一個合適的優(yōu)先級,通過NVIC,外部中斷信號就能進入CPU
2,中斷初始化的配置示例
/*開啟時鐘*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //開啟GPIOB的時鐘RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //開啟AFIO的時鐘,外部中斷必須開啟AFIO的時鐘/*GPIO初始化*/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); //將PB14引腳初始化為上拉輸入/*AFIO選擇中斷引腳*/GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);//將外部中斷的14號線映射到GPIOB,即選擇PB14為外部中斷引腳/*EXTI初始化*/EXTI_InitTypeDef EXTI_InitStructure; //定義結構體變量EXTI_InitStructure.EXTI_Line = EXTI_Line14; //選擇配置外部中斷的14號線EXTI_InitStructure.EXTI_LineCmd = ENABLE; //指定外部中斷線使能EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //指定外部中斷線為中斷模式EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //指定外部中斷線為下降沿觸發(fā)EXTI_Init(&EXTI_InitStructure); //將結構體變量交給EXTI_Init,配置EXTI外設/*NVIC中斷分組*/NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //配置NVIC為分組2//即搶占優(yōu)先級范圍:0~3,響應優(yōu)先級范圍:0~3//此分組配置在整個工程中僅需調用一次//若有多個中斷,可以把此代碼放在main函數(shù)內,while循環(huán)之前//若調用多次配置分組的代碼,則后執(zhí)行的配置會覆蓋先執(zhí)行的配置/*NVIC配置*/NVIC_InitTypeDef NVIC_InitStructure; //定義結構體變量NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; //選擇配置NVIC的EXTI15_10線NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //指定NVIC線路使能NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //指定NVIC線路的搶占優(yōu)先級為1NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //指定NVIC線路的響應優(yōu)先級為1NVIC_Init(&NVIC_InitStructure); //將結構體變量交給NVIC_Init,配置NVIC外設
?以下是外部中斷的中斷函數(shù),相當于C51的外部中斷服務號
void EXTI15_10_IRQHandler(void)
{if (EXTI_GetITStatus(EXTI_Line14) == SET) //判斷是否是外部中斷14號線觸發(fā)的中斷{/*如果出現(xiàn)數(shù)據(jù)亂跳的現(xiàn)象,可再次判斷引腳電平,以避免抖動*/if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) == 0){CountSensor_Count ++; //計數(shù)值自增一次}EXTI_ClearITPendingBit(EXTI_Line14); //清除外部中斷14號線的中斷標志位//中斷標志位必須清除//否則中斷將連續(xù)不斷地觸發(fā),導致主程序卡死}
}
?四,TIM定時器介紹
1,定時器類型介紹
- 定時器可以對輸入的時鐘進行計數(shù),并在計數(shù)值達到設定值時觸發(fā)中斷
- 16位計數(shù)器、預分頻器、自動重裝寄存器的時基單元,在72MHz計數(shù)時鐘下可以實現(xiàn)最大59.65s的定時
- 不僅具備基本的定時中斷功能,而且還包含內外時鐘源選擇、輸入捕獲、輸出比較、編碼器接口、主從觸發(fā)模式等多種功能
- 根據(jù)復雜度和應用場景分為了高級定時器、通用定時器、基本定時器三種類型
注意:每個不同單片機的型號是不同的,在使用某個外設之前,一定要查看一下是不是有這個外設?
2,基本定時器
- 解釋:
- 首先,預分頻器,計數(shù)器,自動重裝載寄存器,它們三個構成了最基本的計數(shù)計時電路,這一塊也成為時基單元
- ?基本定時器只能選擇內部時鐘,其中內部時鐘的來源是RCC的TIMxCLK,這里的頻率值一般都是系統(tǒng)的主頻72MHz,所有通向時基單元的計數(shù)基準主頻就是72MHz
- 實際分頻系數(shù)==預分頻系數(shù)的值+1,其中這個預分頻器是16位的,所有最大值可以寫65535,也就是65536,就是對輸入的基準頻率提前進行一個分頻的操作
- 計數(shù)器可以對預分頻后的計數(shù)時鐘進行計數(shù)(比如計數(shù)時鐘每來一個上升沿,計數(shù)器的值+1),計數(shù)器運行時會自增運行,當自增運行到目標值,產生中斷,就完成了定時的任務
- 自動重裝載寄存器,就是寫入一個計數(shù)目標,當計數(shù)器自增到該目標,就會產生中斷信號,并且清零計數(shù)器,計數(shù)器自動開始下一次的計數(shù)計時。
- 基本定時器僅支持向上計數(shù)
3,通用定時器框圖
通用定時器和高級定時器支持向上計數(shù),向下計數(shù)和中央對齊這三種模式?
通用定時器可以使用外部時鐘(TIMx_ETR)
五,代碼展示
1,定時器中斷的基本結構
下面來看幾個時序圖,這對于代碼的編寫也十分重要
?
?
2,定時器定時中斷代碼
2.1 定時器初始化配置流程
- 1,打開RCC開啟時鐘,定時器的基準時鐘和整個外設的工作時鐘都會被同時打開
- 2,選擇時基單元的時鐘源,對于定時中斷,我們選擇內部時鐘源
- 3,配置時基單元,包括預分頻器,自動重裝器,計數(shù)模式等等,可以直接使用一個結構體來配置
- 4,配置輸出中斷控制,允許更新中斷輸出到NVIC
- 5,配置NVIC,在NVIC中打開定時器中斷的通道,并分配一個優(yōu)先級
- 6,運行控制,整個模塊配置完成后,需要驅動使能定時計數(shù)器
- 當定時器使能之后,計數(shù)器開始計數(shù),當計數(shù)器更新時,觸發(fā)中斷
- 7,最后,我們再寫一個定時器的中斷函數(shù),這樣這個中斷函數(shù)每隔一段時間就會自動執(zhí)行一次了
2.2 定時器的相關庫函數(shù)
2.2.1 定時器初始化相關函數(shù)
void TIM_DeInit(TIM_TypeDef* TIMx);//恢復缺省配置
void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);//時基單元初始化
void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);
void TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);
void TIM_BDTRConfig(TIM_TypeDef* TIMx, TIM_BDTRInitTypeDef *TIM_BDTRInitStruct);
void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_ICStructInit(TIM_ICInitTypeDef* TIM_ICInitStruct);
void TIM_BDTRStructInit(TIM_BDTRInitTypeDef* TIM_BDTRInitStruct);
void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);
void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState);
void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);
void TIM_GenerateEvent(TIM_TypeDef* TIMx, uint16_t TIM_EventSource);
void TIM_DMAConfig(TIM_TypeDef* TIMx, uint16_t TIM_DMABase, uint16_t TIM_DMABurstLength);
void TIM_DMACmd(TIM_TypeDef* TIMx, uint16_t TIM_DMASource, FunctionalState NewState);
void TIM_InternalClockConfig(TIM_TypeDef* TIMx);
void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);
void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource,uint16_t TIM_ICPolarity, uint16_t ICFilter);
?2.2.2 定時器其他重要的相關函數(shù)
void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode);//單獨寫預分頻值的,
void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);//自動重裝器預裝功能配置
void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter);//給計數(shù)值寫值
void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint16_t Autoreload);//給自動重裝器寫入一個值
uint16_t TIM_GetCounter(TIM_TypeDef* TIMx);//返回當時計數(shù)器的值
uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx);//返回當時預分頻器的值
FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);//檢查指定定時器(TIMx)的特定標志(TIM_FLAG)的狀態(tài)。
void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);//作用:清除指定定時器(TIMx)的特定標志(TIM_FLAG)。
ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);//檢查指定定時器(TIMx)的特定中斷(TIM_IT)的掛起狀態(tài)。
void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);//清除指定定時器(TIMx)的特定中斷(TIM_IT)的掛起位。
2.3 定時器代碼示例?
timer.c
#include "stm32f10x.h" // Device header/*** 函 數(shù):定時中斷初始化* 參 數(shù):無* 返 回 值:無*/
void Timer_Init(void)
{/*開啟時鐘*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //開啟TIM2的時鐘/*配置時鐘源*/TIM_InternalClockConfig(TIM2); //選擇TIM2為內部時鐘,若不調用此函數(shù),TIM默認也為內部時鐘/*時基單元初始化*/TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; //定義結構體變量TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; //時鐘分頻,選擇不分頻,此參數(shù)用于配置濾波器時鐘,不影響時基單元功能TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //計數(shù)器模式,選擇向上計數(shù)TIM_TimeBaseInitStructure.TIM_Period = 10000 - 1; //計數(shù)周期,即ARR的值TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1; //預分頻器,即PSC的值TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; //重復計數(shù)器,高級定時器才會用到TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure); //將結構體變量交給TIM_TimeBaseInit,配置TIM2的時基單元 /*中斷輸出配置*/TIM_ClearFlag(TIM2, TIM_FLAG_Update); //清除定時器更新標志位//TIM_TimeBaseInit函數(shù)末尾,手動產生了更新事件//若不清除此標志位,則開啟中斷后,會立刻進入一次中斷//如果不介意此問題,則不清除此標志位也可TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); //開啟TIM2的更新中斷/*NVIC中斷分組*/NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //配置NVIC為分組2//即搶占優(yōu)先級范圍:0~3,響應優(yōu)先級范圍:0~3//此分組配置在整個工程中僅需調用一次//若有多個中斷,可以把此代碼放在main函數(shù)內,while循環(huán)之前//若調用多次配置分組的代碼,則后執(zhí)行的配置會覆蓋先執(zhí)行的配置/*NVIC配置*/NVIC_InitTypeDef NVIC_InitStructure; //定義結構體變量NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; //選擇配置NVIC的TIM2線NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //指定NVIC線路使能NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //指定NVIC線路的搶占優(yōu)先級為2NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //指定NVIC線路的響應優(yōu)先級為1NVIC_Init(&NVIC_InitStructure); //將結構體變量交給NVIC_Init,配置NVIC外設/*TIM使能*/TIM_Cmd(TIM2, ENABLE); //使能TIM2,定時器開始運行
}/* 定時器中斷函數(shù),可以復制到使用它的地方
void TIM2_IRQHandler(void)
{if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET){TIM_ClearITPendingBit(TIM2, TIM_IT_Update);}
}
*/
?main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "Timer.h"uint16_t Num; //定義在定時器中斷里自增的變量int main(void)
{/*模塊初始化*/OLED_Init(); //OLED初始化Timer_Init(); //定時中斷初始化/*顯示靜態(tài)字符串*/OLED_ShowString(1, 1, "Num:"); //1行1列顯示字符串Num:while (1){OLED_ShowNum(1, 5, Num, 5); //不斷刷新顯示Num變量}
}/*** 函 數(shù):TIM2中斷函數(shù)* 參 數(shù):無* 返 回 值:無* 注意事項:此函數(shù)為中斷函數(shù),無需調用,中斷觸發(fā)后自動執(zhí)行* 函數(shù)名為預留的指定名稱,可以從啟動文件復制* 請確保函數(shù)名正確,不能有任何差異,否則中斷函數(shù)將不能進入*/
void TIM2_IRQHandler(void)
{if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET) //判斷是否是TIM2的更新事件觸發(fā)的中斷{Num ++; //Num變量自增,用于測試定時中斷TIM_ClearITPendingBit(TIM2, TIM_IT_Update); //清除TIM2更新事件的中斷標志位//中斷標志位必須清除//否則中斷將連續(xù)不斷地觸發(fā),導致主程序卡死}
}
?3,定時器外部時鐘
- timer.c
#include "stm32f10x.h" // Device header/*** 函 數(shù):定時中斷初始化* 參 數(shù):無* 返 回 值:無* 注意事項:此函數(shù)配置為外部時鐘,定時器相當于計數(shù)器*/
void Timer_Init(void)
{/*開啟時鐘*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //開啟TIM2的時鐘RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //開啟GPIOA的時鐘/*GPIO初始化*/GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure); //將PA0引腳初始化為上拉輸入/*外部時鐘配置*/TIM_ETRClockMode2Config(TIM2, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0x0F);//選擇外部時鐘模式2,時鐘從TIM_ETR引腳輸入//注意TIM2的ETR引腳固定為PA0,無法隨意更改//最后一個濾波器參數(shù)加到最大0x0F,可濾除時鐘信號抖動/*時基單元初始化*/TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; //定義結構體變量TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; //時鐘分頻,選擇不分頻,此參數(shù)用于配置濾波器時鐘,不影響時基單元功能TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //計數(shù)器模式,選擇向上計數(shù)TIM_TimeBaseInitStructure.TIM_Period = 10 - 1; //計數(shù)周期,即ARR的值TIM_TimeBaseInitStructure.TIM_Prescaler = 1 - 1; //預分頻器,即PSC的值TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; //重復計數(shù)器,高級定時器才會用到TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure); //將結構體變量交給TIM_TimeBaseInit,配置TIM2的時基單元 /*中斷輸出配置*/TIM_ClearFlag(TIM2, TIM_FLAG_Update); //清除定時器更新標志位//TIM_TimeBaseInit函數(shù)末尾,手動產生了更新事件//若不清除此標志位,則開啟中斷后,會立刻進入一次中斷//如果不介意此問題,則不清除此標志位也可TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); //開啟TIM2的更新中斷/*NVIC中斷分組*/NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //配置NVIC為分組2//即搶占優(yōu)先級范圍:0~3,響應優(yōu)先級范圍:0~3//此分組配置在整個工程中僅需調用一次//若有多個中斷,可以把此代碼放在main函數(shù)內,while循環(huán)之前//若調用多次配置分組的代碼,則后執(zhí)行的配置會覆蓋先執(zhí)行的配置/*NVIC配置*/NVIC_InitTypeDef NVIC_InitStructure; //定義結構體變量NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; //選擇配置NVIC的TIM2線NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //指定NVIC線路使能NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //指定NVIC線路的搶占優(yōu)先級為2NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //指定NVIC線路的響應優(yōu)先級為1NVIC_Init(&NVIC_InitStructure); //將結構體變量交給NVIC_Init,配置NVIC外設/*TIM使能*/TIM_Cmd(TIM2, ENABLE); //使能TIM2,定時器開始運行
}/*** 函 數(shù):返回定時器CNT的值* 參 數(shù):無* 返 回 值:定時器CNT的值,范圍:0~65535*/
uint16_t Timer_GetCounter(void)
{return TIM_GetCounter(TIM2); //返回定時器TIM2的CNT
}/* 定時器中斷函數(shù),可以復制到使用它的地方
void TIM2_IRQHandler(void)
{if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET){TIM_ClearITPendingBit(TIM2, TIM_IT_Update);}
}
*/
main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "Timer.h"uint16_t Num; //定義在定時器中斷里自增的變量int main(void)
{/*模塊初始化*/OLED_Init(); //OLED初始化Timer_Init(); //定時中斷初始化/*顯示靜態(tài)字符串*/OLED_ShowString(1, 1, "Num:"); //1行1列顯示字符串Num:OLED_ShowString(2, 1, "CNT:"); //2行1列顯示字符串CNT:while (1){OLED_ShowNum(1, 5, Num, 5); //不斷刷新顯示Num變量OLED_ShowNum(2, 5, Timer_GetCounter(), 5); //不斷刷新顯示CNT的值}
}/*** 函 數(shù):TIM2中斷函數(shù)* 參 數(shù):無* 返 回 值:無* 注意事項:此函數(shù)為中斷函數(shù),無需調用,中斷觸發(fā)后自動執(zhí)行* 函數(shù)名為預留的指定名稱,可以從啟動文件復制* 請確保函數(shù)名正確,不能有任何差異,否則中斷函數(shù)將不能進入*/
void TIM2_IRQHandler(void)
{if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET) //判斷是否是TIM2的更新事件觸發(fā)的中斷{Num ++; //Num變量自增,用于測試定時中斷TIM_ClearITPendingBit(TIM2, TIM_IT_Update); //清除TIM2更新事件的中斷標志位//中斷標志位必須清除//否則中斷將連續(xù)不斷地觸發(fā),導致主程序卡死}
}
四,總結
1,定時器定時中斷
-
觸發(fā)來源:定時器定時中斷是由STM32內部的定時器產生的。當定時器的計數(shù)值達到預設的重裝載值時,定時器溢出并觸發(fā)中斷。
-
應用場景:定時器定時中斷常用于需要周期性執(zhí)行的任務,如定時測量、延時控制、PWM輸出等。它允許微控制器在固定的時間間隔執(zhí)行特定的操作。
-
功能特點:
- 可編程性:定時器的計數(shù)值和重裝載值可以通過軟件編程進行靈活設置,從而實現(xiàn)不同的定時周期。
- 高精度:STM32的定時器通常具有較高的精度,能夠滿足對定時要求較高的應用場景。
- 自動重裝載:許多STM32定時器支持自動重裝載功能,即在觸發(fā)中斷后自動將計數(shù)值重置為預設的重裝載值,從而實現(xiàn)連續(xù)定時。
2,定時器外部中斷
-
觸發(fā)來源:定時器外部中斷通常指的是由外部事件(如外部輸入引腳狀態(tài)的變化)觸發(fā)的中斷,而不是由定時器本身產生的中斷。這里的“定時器外部中斷”可能是一個誤導性的表述,因為標準的STM32外部中斷是由外部中斷/事件控制器(EXTI)管理的,而不是由定時器直接管理的。然而,為了回答這個問題,我們可以將其理解為一種通過定時器與外部事件結合來觸發(fā)的中斷機制(盡管這不是標準的STM32術語)。
-
應用場景:定時器外部中斷(如果理解為通過定時器與外部事件結合觸發(fā)的中斷)可能用于在特定時間窗口內檢測外部事件,或者在外部事件發(fā)生時啟動定時器以測量事件持續(xù)時間等。
-
功能特點:
- 外部事件觸發(fā):與定時器定時中斷不同,定時器外部中斷的觸發(fā)依賴于外部事件。
- 時間窗口控制:通過結合定時器和外部中斷,可以實現(xiàn)僅在特定時間窗口內響應外部事件的功能。
- 靈活性:定時器和外部中斷的結合使用提供了更高的靈活性,可以滿足更復雜的定時和外部事件檢測需求。
3,總結
- 觸發(fā)來源:定時器定時中斷由定時器內部溢出觸發(fā),而定時器外部中斷(如果理解為一種結合機制)則由外部事件觸發(fā)。
- 應用場景:定時器定時中斷適用于周期性任務,而定時器外部中斷(結合機制)適用于需要在特定時間窗口內檢測外部事件的應用場景。
- 功能特點:兩者在可編程性、精度和靈活性方面各有優(yōu)勢,具體選擇取決于應用需求。