或許你會直接想說那好辨,就是在 HAL_GPIO_EXTI_Callback 裡做HAL_Delay
但是這會讓你debug到死都會在HAL_Delay裡完成不了,為什麼?
因為預設的SysTick的優先序是排到15去,而後續定義的EXTI的優先層級都比它還高
因為預設的SysTick的優先序是排到15去,而後續定義的EXTI的優先層級都比它還高
當然是SysTick在EXTI call back裡會死在那裡 ,參考這裡說明
所以,要調整一下下兩者間的NVIC優先序,如下圖
-------------------------------------
-------------------------------------
這樣就可以在HAL_GPIO_EXTI_Callback 裡呼叫HAL_Delay了
為什麼SysTick會被安排到這麼後面的優先序裡去?可能是因為分時多工會用到
既然是分時多工之用,那一定是會有時間分割上的出入,自然不若GPIO那樣要即時處理電位起伏帶來的事件/中斷來得緊急(優先)之故,畢竟GPIO是在最前線作戰的單位,其所關注的事件一定是有很高的優先處理順序.這點很合理的
既然是分時多工之用,那一定是會有時間分割上的出入,自然不若GPIO那樣要即時處理電位起伏帶來的事件/中斷來得緊急(優先)之故,畢竟GPIO是在最前線作戰的單位,其所關注的事件一定是有很高的優先處理順序.這點很合理的
「可是,如果我要delay到小於1毫秒的delay,或是不想去修改它們的優先序,如何是好?」
如果不想用Standard Peripheral Library的用操作SysTick暫存器的寫法的話,可以用Timer對counter增減的方式來做delay的依據
參方這位老師的教學,(prescaler 72-1= 72MHz/72 -> 1MHz--> 1us ) 注意,是微秒級,不是奈秒.
-------------------
--------------------
並在main.c裡加入delay_us函數.(當然你也要有「MX_TIM1_Init();」跟「HAL_TIM_Base_Start(&htim1);」啟用TIM1)
-------------------
void delay_us (uint16_t us)
{
__HAL_TIM_SET_COUNTER(&htim1,0); // set the counter value a 0
while (__HAL_TIM_GET_COUNTER(&htim1) < us); // wait for the counter to reach the us input in the parameter
}
-------------------
之後,再回到我們之前要處理的「HAL_GPIO_EXTI_Callback 」使用它
------------假設我們設定的是下降緣觸發事件--------------
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
//delay一下,事緩則圓--消除突波之用
delay_us(1000*50);
delay_us(1000*50);
//如果此時按鈕線被拉回高電位的話,不處理
//密技:即便是用在中斷模式,stm32的GPIO 腳位還是可以讀取狀態的
if(HAL_GPIO_ReadPin(BUTTON_KEY1_GPIO_Port,BUTTON_KEY1_Pin)== GPIO_PIN_SET)
{
return;
}
}
//是的,已經確定是按下狀態
//處理中 ...
....
------------------------------------------------------------------
以上.
(科班出身的都那麼拚了,那非本科出身的,豈不是要更努力才行了?)
沒有留言:
張貼留言