中科因仑“3+1”工程特种兵精英论坛
标题:
分享:STM32下的非阻塞延时模块,可以在状态机下使用
[打印本页]
作者:
谭力源
时间:
2016-6-14 18:45
标题:
分享:STM32下的非阻塞延时模块,可以在状态机下使用
在参考各个开发板的例程的基础上,经过自身编程实践重新构建和修改,编写了以下方便在状态机模块里使用的延时计数模块。延时计数的基础是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]
欢迎光临 中科因仑“3+1”工程特种兵精英论坛 (http://bbs.enlern.com/)
Powered by Discuz! X3.4