1. 程式人生 > >UCOS_III(原子戰艦STM32)學習筆記一

UCOS_III(原子戰艦STM32)學習筆記一

1、UCOS_III主要使用系統的滴答定時器(倒計時計數器)來做高精度延遲;滴答定時器的中斷優先順序最低(優先順序為15);
2、`void delay_init()
{

if SYSTEM_SUPPORT_OS //如果使用了OS

u32 reload;

endif

①SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);//選擇外部晶振  HCLK/8
②fac_us=SystemCoreClock/8000000;    為系統時鐘的1/8

if SYSTEM_SUPPORT_OS //如果使用了OS

③reload=SystemCoreClock/8000000;    //每us計數的次數,單位為K,如果為72M,則計數為9K          
④reload*=1000000/delay_ostickspersec; //根據delay_ostickspersec設定溢位時間

⑤fac_ms=1000/delay_ostickspersec; //代表OS最小延遲單位        

SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;    
SysTick->LOAD=reload; //重灌載計數器,裝入初值                 
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;   

else

fac_ms=(u16)fac_us*1000;                

endif

} `
上面的程式碼是原子縮寫的delay.c裡面的函式,用來對延遲進行初始化的。
①設定滴答定時器時鐘源,F103為72M,72M/8=9M;
②用當前時鐘源9M,9M/S=9/us;故1us計數器跳動9次;
③同②;
④根據delay_ostickspersec設定溢位時間,在預設值下,delay_ostickspersec=200;
reload在後邊將會當做計數初值,放入重灌載計數器,故它為溢位所需的計數次數;
reload=1/200*1000000*9;
溢位時間為1/200s,在乘以1000000,變為us級別,再乘以1us跳動次數;
(一秒鐘跳200次(設定計時);每次0.005s,即5ms;0.005s有多少個us,即0.005*1000000=5000個;1us跳9次,故在乘以9,等於45000次,裝入SysTick->LOAD這個暫存器;
說白了就是:滴答定時器1us跳9次,你將45000次放入SysTick->LOAD這個暫存器,它就開始倒計時,滴答定時器進入它的中斷的時間是1/200s=5ms,也是45000/9us=5000us=5ms,也就是5ms進一次中斷。


⑤最小延遲單位,T=1/delay_ostickspersec;

3、void delay_ms(u16 nms) //OS毫秒級延遲
{
if(delay_osrunning&&delay_osintnesting==0)
{
if(nms>=fac_ms) //如果延遲時間大於最小延遲單位
{
delay_ostimedly(nms/fac_ms); //OS延遲
}
nms%=fac_ms; // 這裡用的是%,就是說小於最小延遲單位的毫秒數,用下面的普通延遲 ;比如現在延遲7ms,若當前最小延遲單位為5ms,nms/fac_ms =7/5=1,故用OS延遲一個5ms,nms%fac_ms=7%5=2,用普通的OS的delay_us延遲,延遲2ms;
}
delay_us((u32)(nms*1000)); //普通延遲(OS的delay_us延遲)
}

呼叫OS的delay_ms的時候,為啥延遲的ms數小於最小延遲單位,T=1/delay_ostickspersec,無法引起任務排程?
原因很簡單,系統定時器T=1/delay_ostickspersec長時間才會進一次中斷,即void SysTick_Handler(void)函式,任務排程發生在這個函式裡面,因為你定時的時間小於進入中斷的時間,所以當延遲完成的時候,中斷還沒有到來。

OS的delay_us函式無法引起任務排程;

4、UCOS_III的五個系統任務

優先順序0:中斷服務管理任務 OS_IntQTask()
優先順序1:時鐘節拍任務 OS_TickTask()
優先順序2:定時任務 OS_TmrTask()
優先順序OS_CFG_PRIO_MAX-2:統計任務OS_StatTask()
優先順序OS_CFG_PRIO_MAX-1:空閒任務OS_IdleTask()

時鐘節拍任務和空閒任務系統預設開啟,其他手動開啟,系統任務所佔的優先順序,使用者任務不能佔用。