fengjing81 2020-03-02
都说程序设计 = 算法 + 数据结构。数据结构是挨踢必修课,不过好像学了数据结构之后也没用来做过啥。不知道做啥,就写个软件定时器。
typedef struct __software_timer{ u32 timeout; //初始化时间计数器 u32 repeat; //运行间隔:repeat > 0 :周期定时时间 repeat == 0 :只定时一次 void (*timeout_callback_handler)(void *para); //超时回调函数 struct __software_timer *next; }software_timer_t;
/** * @brief: Determine if the software timer list is empty * @param[in]: None * @retval[out]: None * @note: * @author: AresXu * @github: * @version: v1.0.0 */ static u8 is_softtimer_list_empty(void) { if(software_timer_list_head.next == NULL) return TRUE; else return FALSE; }
链表使用单向链表。
/** * @brief: Insert the software timer node into the linked list * @param[in]: None * @retval[out]: None * @note: * @author: AresXu * @github: * @version: v1.0.0 */ static void insert_software_timer(software_timer_t *timer_handle) { software_timer_t *tmp; software_timer_t *list_head = &software_timer_list_head; if(is_softtimer_list_empty()) { list_head->next = timer_handle; } else { tmp = list_head->next; while(tmp->next) { if(timer_handle == tmp) //定时器已经存在 { printf("The timer already exists\r\n"); return; } tmp = tmp->next; } tmp->next = timer_handle; } }
/** * @brief: Removes the software timer node from the list * @param[in]: None * @retval[out]: None * @note: * @author: AresXu * @github: * @version: v1.0.0 */ static void remove_software_timer(software_timer_t *timer_handle) { software_timer_t *list_head = &software_timer_list_head; software_timer_t *tmp = list_head; if(is_softtimer_list_empty()) return; while(tmp && tmp->next != timer_handle) { tmp = tmp->next; } if(tmp == NULL) return; tmp->next = timer_handle->next; timer_handle->next = NULL; }
回调函数不能过长,执行时间不能超过定时时间。
/** * @brief: Initializes the software timer * @param[in]: None * @retval[out]: None * @note: * @author: AresXu * @github: * @version: v1.0.0 */ void software_timer_init(software_timer_t *timer_handle,u32 timeout,u32 repeat,void (*timerout_cb)(void *)) { timer_handle->timeout = timeout; timer_handle->repeat = repeat; timer_handle->timeout_callback_handler = timerout_cb; timer_handle->next = (void *)0; }
/** * @brief: Start timer * @param[in]: None * @retval[out]: None * @note: * @author: AresXu * @github: * @version: v1.0.0 */ void software_timer_start(software_timer_t *timer_handle) { insert_software_timer(timer_handle); }
/** * @brief: stop timer * @param[in]: None * @retval[out]: None * @note: * @author: AresXu * @github: * @version: v1.0.0 */ void software_timer_stop(software_timer_t *timer_handle) { remove_software_timer(timer_handle); }
/** * @brief: Timer processing function * @param[in]: None * @retval[out]: None * @note: Must be called by the main function * @author: AresXu * @github: https://github.com/EmbeddedXGJ * @version: v1.0.0 */ void software_timer_main_loop(void) { software_timer_t *tmp = &software_timer_list_head; tmp = tmp->next; while(tmp) { if(tmp->timeout <= 0) { tmp->timeout_callback_handler((void *)0); if(tmp->repeat > 0) { tmp->timeout = tmp->repeat; } else { software_timer_stop(tmp); } } tmp = tmp->next; } }
1 ms硬件定时器调用函数。
/** * @brief: Provide a heartbeat to the software timer * @param[in]: void * @retval[out]: void * @note: Must be called by 1ms hardware timer * @author: AresXu * @github: https://github.com/EmbeddedXGJ * @version: v1.0.0 */ void software_timer_ticks(void) { software_timer_t *tmp = &software_timer_list_head; tmp = tmp->next; while(tmp) { if(tmp->timeout > 0) { tmp->timeout--; } tmp = tmp->next; } }
software_timer_t timer1_t; software_timer_t timer2_t; software_timer_t timer3_t; void timer1_cb(void *parm) { printf("1000ms >>> dyy\r\n"); } void timer2_cb(void *parm) { printf("2000ms >>> dyy\r\n"); } void timer3_cb(void *parm) { printf("500ms >>> dyy\r\n"); } void SoftWareTimer_Init(void) { software_timer_init(&timer1_t,1000,1000,timer1_cb); software_timer_init(&timer2_t,2000,2000,timer2_cb); software_timer_init(&timer3_t,500,500,timer3_cb); software_timer_start(&timer1_t); software_timer_start(&timer2_t); software_timer_start(&timer3_t);
串口助手打印信息