单片机里不想阻塞系统的延时
状态机
状态机有助于解决延时导致系统的阻塞问题
按键状态机
头文件
#ifndef STATE_MACHINE_H
#define STATE_MACHINE_H
#include "sys.h"uint32_t GetSystemSTART_TO_NOW_RunTimer(void);
uint32_t GetSystemLast_TO_NOW_RunTimer(uint32_t LastTime,uint32_t NowTime);
bool GetKeyState(void);
#endif
C文件
/**********************获取系统运行时间***********************************************/
/*DEFIN*/
#define U32_DataMax 4294967295
uint32_t SystemRuningTime_ms = 0;//将该值放入1ms定时器中断中进行累加
/*获取系统运行的时间
*/uint32_t GetSystemSTART_TO_NOW_RunTimer(void)
{
return SystemRuningTime_ms;
}/*
获取系统上一次到现在的时间
*/uint32_t GetSystemLast_TO_NOW_RunTimer(uint32_t LastTime,uint32_t NowTime)
{
if(LastTime < NowTime)
{
return NowTime - LastTime;
}
else//判断是否溢出
{
return (U32_DataMax - LastTime)+NowTime;
}
}/***********状态机例子******************************************************************************************/
/*
以按键检测为例
我们如果循环检测按键,消除抖动的时候如果使用delay延时,这对于系统其他在while执行的程序将会是致命的。
因此我们标记状态,根据当前的状态在执行下一步动作。
*//*
使用这个模块,有多少种状态?
按键:按键就绪,按键检测按下,按键消抖等待,按键消抖等待完成,按键按下和没有按下
过程:当检测到按下后我们将按键状态标记为按键检测按下,
*//***创建状态种类*****/
typedef enum KeyState
{
Ready = 0,//就绪
TestTakeDown,//检测到按下
TakeDown,
NotTakeDown,
}EnumKeyState;/*DEFINE*/
#define Key_1 1/*创建变量***************/
/*没有连续计数工能*/
bool GetKeyState1(void)
{
uint32_t NowTime = 0;
static uint32_t UseTimer = 0;
static uint32_t LastTimer = 0;
static EnumKeyState Key1_state = Ready;
switch(Key1_state)
{
case Ready:
if(gpio_input_bit_get(Key_EncoderC_Pro,Key_EncoderC_Pin) == RESET)
{
Key1_state = TestTakeDown;
LastTimer = GetSystemSTART_TO_NOW_RunTimer();//开始获取时间,便于GetSystemLast_TO_NOW_RunTimer函数调用
}
else
{
Key1_state = NotTakeDown;
}
break;
case TestTakeDown:
NowTime = GetSystemSTART_TO_NOW_RunTimer();
UseTimer = GetSystemLast_TO_NOW_RunTimer(LastTimer,NowTime) + UseTimer;
LastTimer = NowTime;
if(UseTimer >= 10)//等待了10ms
{
if(gpio_input_bit_get(Key_EncoderC_Pro,Key_EncoderC_Pin) == RESET)
{
Key1_state = TakeDown;
}
else
{
Key1_state = Ready;
}
UseTimer = 0;
}
break;
case TakeDown:
Key1_state = Ready;
return 1;
break;
case NotTakeDown:
Key1_state = Ready;
break;
return 0;
}
}
非阻塞延时
非阻塞延时,根据延时返回状态判断是否进行下一步动作。
缺陷:只能用一次,如果想用多个,就得写多个函数。
优点:简单方便,适用于延时较少的场合
/*
非阻塞延时
*/bool Task_Delay(uint32_t time_ms)
{
uint32_t NowTime = 0;
static uint32_t UseTimer = 0;
static EnumKeyState Key1_state = Ready;
static uint32_t LastTimer =0;
static uint8_t flag = 1;
if(flag == 1)
{
LastTimer = GetSystemSTART_TO_NOW_RunTimer();
flag = 0;
}
NowTime = GetSystemSTART_TO_NOW_RunTimer();
UseTimer = GetSystemLast_TO_NOW_RunTimer(LastTimer,NowTime) + UseTimer;
LastTimer = NowTime;
if(time_ms >= UseTimer)
{
flag = 1;
return 1;
}
else
{
return 0;
}}
软件定时器
以后再补充把,有兴趣的可以网上搜一下