UCOSIII 軟體定時器
阿新 • • 發佈:2018-12-31
一、相關理論
1、使用定時器需開啟巨集 OS_CFG_TMR_DEL_EN 1u
2、定時器解析度由定義的系統節拍頻率 OS_CFG_TICK_RATE_HZ 決定
如 OS_CFG_TMR_TASK_RATE_HZ = 100,系統時鐘週期為 10ms 1000/100=10ms
OS_CFG_TICK_RATE_HZ =200,系統時鐘週期為 5ms,定時器的最小解析度 5ms
二、相關API函式
1、建立定時器函式 OSTmrCreate()
OSTmrCreate ( (OS_TMR*) &tmr1, (CPU_CHAR*) "tmr1", (OS_TICK ) 20, //初始化延時20*10=200ms (OS_TICK) 100, // 100*10=1000ms (OS_OPT) OS_OPT_TMR_PERIODIC, (OS_TMR_CALLBACK_PTR) tmr1_callback, (void*) 0, (OS_ERR*) &err); void OSTmrCreate ( OS_TMR *p_tmr, //指向定時器 CPU_CHAR *p_name, //定時器名稱 OS_TICK dly, //初始延時 OS_TICK period, //定時時間 OS_OPT opt, //執行選項 OS_TMR_CALLBACK_PTR p_callback, //回撥函式名稱 void *p_callback_arg, //回撥函式的引數 OS_ERR *p_err) //錯誤碼 OS_OPT opt: OS_OPT_TMR_ONE_SHOT 單次定時器 OS_OPT_TMR_PERIODIC 週期定時器
2、開啟與關閉定時器 函式
1、開啟定時器 OSTmrStart(&tmr1,&err); CPU_BOOLEAN OSTmrStart (OS_TMR *p_tmr, //指向定時器 OS_ERR *p_err) //錯誤碼 2、關閉定時器 OSTmrStop(&tmr1,OS_OPT_TMR_NONE,0,&err); //關閉定時器 1 CPU_BOOLEAN OSTmrStop (OS_TMR *p_tmr, //指向定時器 OS_OPT opt, //選項 void *p_callback_arg, //傳入新的回撥引數 OS_ERR *p_err) OS_OPT opt: OS_OPT_TMR_NONE //除了停止計時什麼都不做 OS_OPT_TMR_CALLBACK //執行回撥引數 OS_OPT_TMR_CALLBACK_ARG //
三、模式圖解
四、程式原始碼
#include "led.h" #include "delay.h" #include "sys.h" #include "bsp_key.h" #include "usart.h" #include "includes.h" //任務優先順序 #define START_TASK_PRIO 3 //任務堆疊大小 #define START_STK_SIZE 512 //任務控制塊 OS_TCB StartTaskTCB; //任務堆疊 CPU_STK START_TASK_STK[START_STK_SIZE]; //任務函式 void start_task(void *p_arg); //任務優先順序 #define TASK1_TASK_PRIO 4 //任務堆疊大小 #define TASK1_STK_SIZE 128 //任務控制塊 OS_TCB Task1TaskTCB; //任務堆疊 CPU_STK TASK1_TASK_STK[TASK1_STK_SIZE]; //任務函式 void task1_task(void *p_arg); //任務優先順序 #define TASK2_TASK_PRIO 5 //任務堆疊大小 #define TASK2_STK_SIZE 128 //任務控制塊 OS_TCB Task2TaskTCB; //任務堆疊 CPU_STK TASK2_TASK_STK[TASK2_STK_SIZE]; //任務函式 void task2_task(void *p_arg); //任務優先順序 #define TASK3_TASK_PRIO 6 //任務堆疊大小 #define TASK3_STK_SIZE 128 //任務控制塊 OS_TCB Task3TaskTCB; //任務堆疊 CPU_STK TASK3_TASK_STK[TASK3_STK_SIZE]; //任務函式 void task3_task(void *p_arg); OS_MUTEX TEST_MUTEX; //定義一個互斥訊號量 int main(void) { OS_ERR err; CPU_SR_ALLOC(); delay_init (); NVIC_PriorityGroupConfig (NVIC_PriorityGroup_2); //設定中斷優先順序 uart_init (115200); //初始化串列埠 printf("串列埠初始化完成\r\n"); LED_Init(); Key_GPIO_Config(); OSInit(&err); OS_CRITICAL_ENTER(); //進入臨界區 OSTaskCreate( (OS_TCB*) &StartTaskTCB, //任務控制塊 (CPU_CHAR*) "start_task ", //任務名稱 (OS_TASK_PTR) start_task, //任務函式 (void*) 0, //引數 (OS_PRIO) START_TASK_PRIO, //任務優先順序 (CPU_STK*) &START_TASK_STK[0], //任務堆疊基地址 (CPU_STK_SIZE) START_STK_SIZE/10, //任務堆疊深度限位 (CPU_STK_SIZE) START_STK_SIZE, //任務堆疊大小 (OS_MSG_QTY) 0, //任務內部訊息佇列能夠接收的最大訊息數目,為0時禁止接收訊息 (OS_TICK) 0, //當使能時間片輪轉時的時間片長度,為0時為預設長度 (void*) 0, //使用者補充的儲存區 (OS_OPT) OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, //任務選項 (OS_ERR*) &err); //存放該函式錯誤時的返回值 OS_CRITICAL_EXIT(); //退出臨界區 OSStart(&err); } //開始任務函式 void start_task(void *p_arg) { OS_ERR err; CPU_SR_ALLOC(); p_arg = p_arg; CPU_Init(); #if OS_CFG_STAT_TASK_EN > 0u OSStatTaskCPUUsageInit(&err); //統計任務 #endif #ifdef CPU_CFG_INT_DIS_MEAS_EN //如果使能了測量中斷關閉時間 CPU_IntDisMeasMaxCurReset(); #endif #if OS_CFG_SCHED_ROUND_ROBIN_EN //當使用時間片輪轉的時候 //使能時間片輪轉排程功能,時間片長度為1個系統時鐘節拍,既1*5=5ms OSSchedRoundRobinCfg(DEF_ENABLED,1,&err); #endif OS_CRITICAL_ENTER(); //進入臨界區 OSMutexCreate( (OS_MUTEX*) &TEST_MUTEX, (CPU_CHAR*) "TEST_MUTEX", (OS_ERR*) &err); OSTaskCreate( (OS_TCB*) &Task1TaskTCB, //任務控制塊 (CPU_CHAR*) "task1_task ", //任務名稱 (OS_TASK_PTR) task1_task, //任務函式 (void*) 0, //引數 (OS_PRIO) TASK1_TASK_PRIO, //任務優先順序 (CPU_STK*) &TASK1_TASK_STK[0], (CPU_STK_SIZE) TASK1_STK_SIZE/10, (CPU_STK_SIZE) TASK1_STK_SIZE, (OS_MSG_QTY) 0, (OS_TICK) 0, (void*) 0, (OS_OPT) OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, (OS_ERR*) &err); OSTaskCreate( (OS_TCB*) &Task2TaskTCB, //任務控制塊 (CPU_CHAR*) "task2_task ", //任務名稱 (OS_TASK_PTR) task2_task, //任務函式 (void*) 0, //引數 (OS_PRIO) TASK2_TASK_PRIO, //任務優先順序 (CPU_STK*) &TASK2_TASK_STK[0], (CPU_STK_SIZE) TASK2_STK_SIZE/10, (CPU_STK_SIZE) TASK2_STK_SIZE, (OS_MSG_QTY) 0, (OS_TICK) 0, (void*) 0, (OS_OPT) OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, (OS_ERR*) &err); OSTaskCreate( (OS_TCB*) &Task3TaskTCB, //任務控制塊 (CPU_CHAR*) "task3_task ", //任務名稱 (OS_TASK_PTR) task3_task, //任務函式 (void*) 0, //引數 (OS_PRIO) TASK3_TASK_PRIO, //任務優先順序 (CPU_STK*) &TASK3_TASK_STK[0], (CPU_STK_SIZE) TASK3_STK_SIZE/10, (CPU_STK_SIZE) TASK3_STK_SIZE, (OS_MSG_QTY) 0, (OS_TICK) 0, (void*) 0, (OS_OPT) OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, (OS_ERR*) &err); OS_CRITICAL_EXIT(); //退出臨界區 OSTaskDel ((OS_TCB*)&StartTaskTCB,&err); //刪除任務自身 } void task1_task(void *p_arg) { u8 task1_num=0; OS_ERR err; CPU_SR_ALLOC(); p_arg = p_arg; while(1) { OSTimeDlyHMSM(0,0,0,500,OS_OPT_TIME_HMSM_STRICT,&err); //延時500MS printf("任務1請求訊號量\r\n"); OSMutexPend( &TEST_MUTEX, 0, OS_OPT_PEND_BLOCKING , 0, &err); printf("任務1執行\r\n"); OSMutexPost( &TEST_MUTEX,OS_ERR_NONE, &err ); OSTimeDlyHMSM(0,0,0,500,OS_OPT_TIME_HMSM_STRICT,&err); //延時500MS } } void task2_task(void *p_arg) { u8 task2_num=0; OS_ERR err; CPU_SR_ALLOC(); p_arg = p_arg; while(1) { printf("任務2執行\r\n"); LED1=~LED1; OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err); //延時1s } } void task3_task(void *p_arg) { static u32 i; OS_ERR err; CPU_SR_ALLOC(); p_arg = p_arg; while(1) { OSMutexPend( &TEST_MUTEX, 0, OS_OPT_PEND_BLOCKING , 0, &err); printf("任務3執行中\r\n"); for(i=0;i<5000000;i++) { OSSched(); } OSMutexPost( &TEST_MUTEX,OS_ERR_NONE, &err ); OSTimeDlyHMSM(0,0,1,0,OS_ERR_NONE,&err); //延時1s } }