单片机里不想阻塞系统的延时

状态机

状态机有助于解决延时导致系统的阻塞问题

按键状态机

头文件

#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;

}

}

软件定时器

以后再补充把,有兴趣的可以网上搜一下

相关推荐
_Ningye8 小时前
STM32 — 11.5 硬件SPI读写W25Q64
stm32·单片机·嵌入式硬件
inrichtt8 小时前
第九课时:STM32 SPI实战:按键消抖与FLASH断电保护
stm32·单片机·嵌入式硬件
优信电子9 小时前
STM32 驱动 SHT35 温湿度传感器:从 I²C 通信到 CRC 校验的完整实战
单片机·嵌入式
尼喃10 小时前
两节两串锂电池保护板原理图+充电电路二合一电路图
嵌入式硬件
深圳市恒锐丰科技杨生10 小时前
SS6208L 12V 集成 MOS 半桥功率芯片|LeadPower 率能半导体
嵌入式硬件·硬件工程
女神下凡11 小时前
芯参谋(61):PMSM永磁同步电机驱动电路设计指南
arm开发·单片机·嵌入式硬件·硬件工程·设计规范
HRTOS11 小时前
HRTOS 4.0 中断嵌套注意事项:为什么不建议在嵌套中断中调用唤醒任务 API?
单片机·嵌入式硬件·51单片机
新晨单片机设计12 小时前
S023E-基于STM32单片机WIFI智能插座(温度、定时)【Proteus仿真+Keil程序+原理图】
stm32·单片机·proteus·wifi智能电表
硅基手札12 小时前
SPI技术系列 08 · SPI 控制器寄存器与 IP 架构
驱动开发·stm32·单片机·嵌入式硬件·mcu·架构·计算机外设
夏虫不可与之言冰12 小时前
第三课 点亮 LED 与定时器非阻塞闪烁
c语言·c++·vscode·单片机·嵌入式硬件·物联网