当前位置: 首页 > article >正文

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

 状态机

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

按键状态机

头文件

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

}

 软件定时器

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


http://www.kler.cn/a/453763.html

相关文章:

  • 探秘仓颉编程语言:使用体验与功能剖析
  • MySQL基础-常见的增删改查操作语句总结
  • 在JavaScript中,let 和 const有什么不同
  • Docker 安装mysql ,redis,nacos
  • 如何在 Scrum 管理中化解团队冲突?
  • 排序算法之快速排序、归并排序
  • DBeaver 咋手动配置sqlite 驱动
  • QT--静态插件、动态插件
  • 【递归,搜索与回溯算法 综合练习】深入理解暴搜决策树:递归,搜索与回溯算法综合小专题(二)
  • 从0开始在linux服务器上部署SpringBoot和Vue
  • MongoDB部署高可用集群
  • Effective C++ 条款 22:将成员变量声明为 private
  • SpringBoot的MVC接口增加签名
  • workman服务端开发模式-应用开发-后端api推送修改二
  • UDP Ping程序实现
  • 学籍管理系统:实现教育管理现代化
  • 【国产NI替代】基于FPGA的32通道(24bits)高精度终端采集核心板卡
  • 敏捷开发05:Sprint Planning 冲刺计划会议详细介绍和用户故事拆分、开发任务细分
  • Kalilinux下MySQL的安装
  • 探索数据采集
  • 大数据学习之Redis 缓存数据库二,Scala分布式语言一
  • Keil-编译按钮Translate,Build,Rebuild
  • 【203】实验室管理系统
  • 实用工具推荐----Doxygen使用方法
  • 【信息系统项目管理师】第12章:项目质量管理-基础和过程 考点梳理
  • JS中的原型与原型链