1、外部中斷初始化函數
// EXTI initialize void EXTIX_INIT(void) { EXTI_InitTypeDef EXTI_InitStructure; //定義外部中斷結構體 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //使能外部中斷時鍾 GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource1); //將GPIOA.1與中斷線1映射起來 EXTI_InitStructure.EXTI_Line = EXTI_Line1; //設置中斷線 EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //中斷觸發模式 EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿觸發 EXTI_InitStructure.EXTI_LineCmd = ENABLE; //使能外部中斷線 EXTI_Init(&EXTI_InitStructure); //外部中斷初始化 BSP_IntVectSet(BSP_INT_ID_EXTI1,EXTI1_IRQHandler); //設置中斷號跟對應的中斷服務函數 BSP_IntEn(BSP_INT_ID_EXTI1); //使能指定中斷 }
- 配置中斷初始化時,需要注意的是,在uCOS系統上的中斷機制跟裸機上不一樣
其中幾個關鍵的中斷函數(定義在Bsp_int.c)
void BSP_IntVectSet(CPU_DATA int_id, CPU_FNCT_VOID isr);//設置中斷向量及處理中斷服務函數,產生中斷時將跳至中斷服務函數的地址
void BSP_IntEn (CPU_DATA int_id) //使能指定中斷
void BSP_IntDis (CPU_DATA int_id) //禁用指定中斷(視程序需要)
void BSP_IntDisAll (void) //禁用所有中斷(視程序需要)
2、中斷優先級配置
void NVICSTR_INIT(void) { NVIC_InitTypeDef NVIC_InitStructure; //定義優先級結構體 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //設置NVIC中斷分組 NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQChannel; //使能只能外部中斷通道 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //搶占優先級1 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //子優先級0 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中斷通道 NVIC_Init(&NVIC_InitStructure); //中斷優先級分組初始化 }
- 寫優先級分配應該不難,基本都大同小異,不一樣的是中斷通道的定義名,裸機的定義跟uCOS的定義不一樣,這個查一下系統文件就能找到了。
在Bsp_int.c中,還有一個函數可用來設置中斷優先級,有興趣的讀者可以試試
void BSP_IntPrioSet (CPU_DATA int_id, CPU_INT08U prio) //設置中斷優先級
3、中斷服務函數
這里的中斷服務函數名可以自己定義,不過也不能太隨便,至少要能看出來是哪個中斷的對接函數
//EXTI1 interrupt handle void EXTI1_IRQHandler() { OSIntEnter(); ACounter1 = 30; //中斷操作 EXTI_ClearITPendingBit(EXTI_Line1); //清除中斷標志位 OSIntExit(); }
中斷服務函數名需與外部中斷初始化中的BSP_IntVectSet()第二個參數一致
這里還需講明一點,函數中用到了OSIntEnter() 與 OSIntExit(),這里大概講一下作用
在uC/OS-II中,通常在進入中斷時需要使用OSIntEnter() ;退出中斷前使用OSIntExit();
在中斷服務函數中使用這對函數,在中斷結束后可進行任務調度,使得系統更加“實時”
若中斷函數的運行不做信號量處理,對任務沒有觸發作用的,可以忽視不用
這樣就完成了外部中斷的配置,把EXTIX_INIT()放入系統初始化函數中,運行時待指定的IO有高低電平觸發時,將觸發對應的中斷操作