STM32中斷程式設計過程中遇到的問題及解決方案

2021-10-14 03:08:31 字數 3352 閱讀 3997

實現功能:

1、自動流水燈:在led1~led4上實現自動流水燈,流水間隔時間為200ms/bit,然後通過按鍵key1改變流水燈的速度,每次按鍵間隔時間增加200ms:當間隔時間增加到1s後(蜂鳴器報警),再次按鍵間隔時間恢復為初始值200ms。//注:按鍵同通過中斷實現

2、手動流水燈功能:通過按鍵key1控制流水燈一位,每次按鍵流水燈移動一位,可迴圈實現。//(1)、在新的程式中實現,不涵蓋上題功能。(2)按鍵通過中斷實現

3、綜合流水燈:1)通過按鍵key2實現自動流水燈和手動流水燈兩種模式的切換。初始模式為自動流水燈模式。當處於自動流水燈模式時,key1用於改變流水燈速度,如1題所述。當處於手動流水燈模式時,key1用於控制流水燈移位,如2提所述。//注:所有按鍵用中斷實現,延時採用定時器中斷實現,操作穩定,可迴圈實現,對按鍵抖動和按鍵時間具有魯棒性。

對於功能1的實現,我書寫的中斷內容為:

/*	@函式名稱 :中斷服務子程式0

@函式功能 :響應中斷0的子程式

@輸入引數 :無

@返回值 :無

@注意 :中斷中不要放延時過長的程式,也不要寫死迴圈

*/void

exti0_irqhandler

(void

)else

if(time_flag<5)

time_flag=time_flag+1;

}exti_clearitpendingbit

(exti_line0)

;}

然後功能實現程式如下圖所示:

/*	@函式名稱:void led_base_200ms(u16 t)

@函式功能:以200ms為基準時間進行延時

@輸入引數:t延時基準

@返回值 :無

*/void

led_base_200ms

(void

) u8 i;

switch

(time_flag+1)

};break

;case2:

};break

;case3:

};break

;case4:

};break

;default:}

}}

解決問題來了,問題出在延時函式中,其實在中斷中最好不要用延時函式,用延時函式容易導致程式跑飛。在本次歷程中,進入中斷的delay_ms(20);延時還是滴答時鐘的延時,雖然精確,但是精確的實驗現象無法出來也不行啊,所以解決方案是去掉延時程式,或者換成普通的的迴圈,最好不用迴圈。通過本例也說明了在中斷可不能亂用延時啊,能不用延時就不用延時。乙個小小的破程式,調了我一天,可真是太難受。

對於題目一的實現**如下所示,每按一次,時間標誌位加一,當大於等於5時候清零,主要最好不要包含任何延時,簡單的修改標誌位就行:

/*	@函式名稱 :中斷服務子程式0

@函式功能 :響應中斷0的子程式

@輸入引數 :無

@返回值 :無

@注意 :中斷中不要放延時過長的程式,也不要寫死迴圈

*/void

exti0_irqhandler

(void

)else

time_flag++;}

exti_clearitpendingbit

(exti_line0)

;}

注意:time_flag是全域性變數,並且在**件中用「extern」修飾,便可在外部呼叫了

然後實現函式如下:

/*	@函式名稱:void led_base_200ms(u16 t)

@函式功能:以200ms為基準時間進行延時

@輸入引數:time延時基準

@返回值 :無

*/void

led_base_200ms

(u16 time)

}

然後在主函式中呼叫led_base_200ms即可

led_base_200ms

(time_flag)

;

對於功能二實現,還是上面的那個中斷程式,但是考慮到,由於用按鍵觸發中斷,因此還是會存在一定的抖動,我們就使用非滴答時鐘寫的延時程式消抖,就普通用迴圈來消抖,注意最好不用滴答時鐘寫的延時程式,具體原因由於學的不精,不能解釋,如果有大佬可以解釋一下,感激不盡。

/*	@函式名稱 :中斷服務子程式0

@函式功能 :響應中斷0的子程式

@輸入引數 :無

@返回值 :無

@注意 :中斷中不要放延時過長的程式,也不要寫死迴圈

*/void exti0_irqhandler(void)

else

time_flag++;

}exti_clearitpendingbit(exti_line0);

然後還是通過標誌位來呼叫燈的亮滅,具體函式如下所示

/*	@函式名稱:中斷標誌控制函式

@函式功能:根據中斷的標誌來執行響應的功能

@輸入引數:無

@返回值 :無

*/void

flag_control

(void

)break

;case2:

break

;case3:

break

;case4:

break

;default

:led_close_all()

;}}

然後在主函式中呼叫flag_cont();即可實現

對於功能3的實現,就更容易了,首先定義乙個模式選擇器,全域性外部變數哦;然後中斷函式是這樣寫的

/*	@函式名稱:中斷服務子程式2

@函式功能:響應中斷2的子程式

@輸入引數:無

@返回值 :無

@注意 :中斷中不要放延時過長的程式,也不要寫死迴圈

*/void

exti2_irqhandler

(void

)else

mode++;}

exti_clearitpendingbit

(exti_line2)

;}

然後模式選擇器函式是這樣寫的

/*	@函式名稱:void select_mode(void)

@函式功能:模式選擇器

@輸入引數:無

@返回值 :無

@注意 :

*/void

select_mode

(void

)}

後面就可在主程式中呼叫flag_control();

stm32中斷優先順序 STM32中斷系統

stm32 中斷非常強大,幾乎每個外設都可以產生中斷,因此這裡我們單獨使用一章來介紹它,為後面介紹外設中斷做鋪墊。學習本章可以參考 stm32f10x中文參考手冊 9 中斷和事件章節,cortex m3 權威指南 中文 chpt08 nvic與中斷控制章節。中斷概念 在學習 51 微控制器時,我們就...

STM32中斷巢狀

cortex m3核心支援256個中斷,其中包括16個核心中斷和240個外部中斷,且具有256級的可程式設計中斷設定,而stm32只用了其中一部分。stm32有84個中斷,包括16個核心中斷和68個可遮蔽中斷,具有16級可程式設計中斷優先順序。而我所使用的103系列只有60個可遮蔽中斷。優先順序的判...

STM32 中斷使用

stm32中斷有時候用多了容易亂,特此記錄一下,因為之前一直是m3 m0交叉用,韌體庫有些區別容易弄混,這裡說一下m3外部中斷的配置 步驟 1.將對應的io配置為輸入 2.將io對應的中斷的優先等級用nvic配置好 3.設定好對應io的中斷模式和觸發方式 4.將io所屬的中斷線設為中斷輸入源 1 以...