在参考各个开发板的例程的基础上,经过自身编程实践重新构建和修改,编写了以下方便在状态机模块里使用的延时计数模块。延时计数的基础是SYSTICK,设置为1ms.具体代码如下:
softtimer.h:
- /*
- *********************************************************************************************************
- *
- * SOFTTIMER
- *
- * ST Microelectronics STM32
- * on the
- *
- * STM32Fx-DISCOVERY
- * Evaluation Board
- *
- * 文件名 : softtimer.h
- * 版 本 : V0.1
- * 作 者 : Lux
- * 时 间 : 2014/11/27
- * 编译环境 : D:\Program Files (x86)\IAR Systems\Embedded Workbench 7.0
- * 摘 要 : SOFTTIMER Drive,软件方式实现的非阻塞方式的超时计时模块
- *********************************************************************************************************/
- #ifndef __SOFT_TIMER_H
- #define __SOFT_TIMER_H
- #ifdef __cplusplus
- extern "C" {
- #endif
- //-----------------------Include files--------------------------------//
- #include <stdbool.h>
- #include <stdint.h>
- //------------------------Data struct---------------------------------//
- typedef enum
- {
- ONCE_MODE = 0x00,
- CIRC_MODE = 0x01
- }TIMER_MODE_t;
- typedef struct SOFT_TIMER
- {
- TIMER_MODE_t mode;
- bool isActivate;
- volatile uint32_t value;
- uint32_t totvalue;
- struct SOFT_TIMER* next;
- }SOFT_TIMER_t;
- //------------------------Extern function-----------------------------//
- void soft_timer_register(SOFT_TIMER_t *st);
- void set_and_star_soft_timer(SOFT_TIMER_t *st, TIMER_MODE_t mode, uint32_t totvalue);
- bool is_soft_timer_Out(SOFT_TIMER_t *st);
- void soft_timer_release(SOFT_TIMER_t *st);
- #ifdef __cplusplus
- }
- #endif
- #endif /*__SOFTTIMER_H*/
[color=rgb(51, 102, 153) !important]复制代码
softtimer.c:
- #include "softtimer.h"
- #include <stdlib.h>
- #include "stm32f10x.h"
- /* 使能中断 */
- #define ENABLE_SYSTICK_INT() __set_PRIMASK(0)
- #define DISABLE_SYSTICK_INT() __set_PRIMASK(1)
- /* 禁止中断 */
- static struct SOFT_TIMER *head = NULL;
- /* SoftTimer_ISR中断服务程序,每隔1ms进入1次 ****************************************/
- void SoftTimer_ISR(void)
- {
- struct SOFT_TIMER *t = head;
- if (t == NULL)
- return;
- while(t != NULL)
- {
- if (t->isActivate == true)
- t->value++;
- t = t->next;
- }
- }
- // 注册软件计时器
- void soft_timer_register(SOFT_TIMER_t *st)
- {
- struct SOFT_TIMER *t = head;
- st->isActivate = false;
- st->mode = ONCE_MODE;
- st->value = 0;
- st->totvalue = 0;
- st->next = NULL;
- if (head == NULL)
- {
- head = st;
- return;
- }
- while(t->next != NULL )
- {
- if (t == st) return; //此语句排除重复注册的现象
- t = t->next;
- }
- DISABLE_SYSTICK_INT();
- t->next = st;
- ENABLE_SYSTICK_INT();
- }
- // 设置并开始软件计时器,计时单位为ms
- void set_and_star_soft_timer(SOFT_TIMER_t *st, TIMER_MODE_t mode, uint32_t totvalue)
- {
- st->mode = mode;
- st->totvalue = totvalue;
- DISABLE_SYSTICK_INT();
- st->value = 0;
- st->isActivate = true;
- ENABLE_SYSTICK_INT();
- }
- // 查询软件计时器是否超时
- bool is_soft_timer_Out(SOFT_TIMER_t *st)
- {
- bool res = false;
- if (st->value >= st->totvalue)
- {
- res = true;
- DISABLE_SYSTICK_INT();
- if (st->mode == CIRC_MODE)
- {
- st->value = 0;
- st->isActivate = true;
- }else
- st->isActivate = false;
- ENABLE_SYSTICK_INT();
- }
- return res;
- }
- // 注销软件计时器
- void soft_timer_release(SOFT_TIMER_t *st)
- {
- struct SOFT_TIMER *p = head,*t = head;
- if (head == st)
- {
- head = st->next;
- return;
- }
- while(t->next != NULL )
- {
- if (t == st) //从节点删除st
- {
- DISABLE_SYSTICK_INT();
- p->next = st->next;
- ENABLE_SYSTICK_INT();
- st->next = NULL;
- return;
- }
- else
- {
- p = t;
- t = t->next;
- }
- }
- }
[color=rgb(51, 102, 153) !important]复制代码
使用方法如下:
- // LED模块的状态机
- void led_module()
- {
- static uint8_t state = 0;
- static SOFT_TIMER_t led_st;
- switch(state)
- {
- case 0:// 初始状态
- led1.init();
- led1.on();
- soft_timer_register(&led_st);
- set_and_star_soft_timer(&led_st, CIRC_MODE, 500);
- state = 1;
- //break;
- case 1:// led跳变状态
- led1.tigger();
- state = 2;
- break;
- case 2:// 延时等待状态
- if (is_soft_timer_Out(&led_st) == true)
- state = 1;
- break;
- }
- }
[color=rgb(51, 102, 153) !important]复制代码
[color=rgb(51, 102, 153) !important]
|