适用于MCU的简易状态机框架

关注、星标公众,不错过精彩内容

整理:黄工

素材来源:网络

地址:

https://www.cnblogs.com/CodeWorkerLiMing/p/12501934.html

很多初学者学习MCU,基本都是跑裸机,还有就是一些资源比较小的MCU也基本跑裸机。

不是说所有MCU都必须要跑操作系统,也可以使用状态机来“代替”操作系统。本文就是简单的方式给大家分享状态机的内容。

在单片机裸机的编程方法中,状态机的方法是比较好的,经典的比如按键的检测判断等

其实有很多地方可以使用这种思想。比如传感器的数据采集,因为单片机不可能一直等待着运行,那样的效率是很低的,通常都是结合fsm + timer的方式来提高CPU的使用率。

一、传感器中使用fsm的方法

大家都知道,ds18b20的采集是比较慢的,发送转换指令后,最慢需要等待720ms,这个时间有点太长了。简直不能忍受。

如下所示:我采用了11bit分辨率,0.125的分辨率足够了,作为温度参考而已。

9 - bit resolution    93.75 ms  0.5
10 - bit resolution   187.5     0.25
11 - bit resolution   375       0.125
12 - bit resolution   750       0.0625

那么我肯定不是死等的,死等,多浪费cpu,效率太低了,实际工作中根本无法接受。

因此,做了一个状态机:

int main(int argc, char const *argv[])
{
  while(1)
  {
      ds18b20_discope();
  }
  return0;
}


void ds18b20_discope(void)
{
  switch (ds18b20的状态机的全局变量)
  {
  case 发送命令:
      发送转换命令
      赋值到等待装态
      break;
  case 等待装态:
      判断是否有超时,
      如果有超时,则:读取,计数器清零,并回到发送命令状态
      否则,do nothing
          break;
  default:
      break;
  }
}

定时器的基准中断可以自己细化,我是50ms一个中断:

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    如果ds18b20已经处于等待状态,
    则计数++
}

这样就是一个简单的传感器定时采样的状态机思路,不会死等,效率较高,而且稳定。

注意ds18b20的时序性比较严格,网上说不能被打断的,但是后来移植到freertos中,也是可以的,温度采样还算稳定,但是考虑到后续程序比较大,因此还是裸机了,状态机的思路基本能解决。

最后说明,状态机的应用很广泛,有的RTOS应用里面同样也使用状态机的处理,具体需结合实际情况而定。

免责声明:本文素材来源网络,版权归原作者所有。如涉及作品版权问题,请与我联系删除。

‧  END  

推荐阅读:

精选汇总 | 目录 | 搜索

详解消灭EMC的三大利器:电容器/电感/磁珠

Cortex-M微控制器软件接口标准CMSIS详细内容

关注微信公众号『strongerHuang』,后台回复“1024”,查看更多精彩内容。

长按前往图中包含的公众号关注

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MCU按键管理框架是一种软件设计模式,用于管理单片机上的按键输入。该框架可以实现按键的稳定性、可靠性和灵活性,使单片机在按键输入时能够快速响应,从而提高系统的可靠性和稳定性。 MCU按键管理框架的设计思路如下: 1. 定义按键输入的方式:按键输入可以是短按、长按和连续按等方式,需要根据不同的输入方式进行相应的处理。 2. 设计按键扫描算法:按键扫描算法可以采用轮询或者中断方式,通过检测按键状态来判断按键是否被按下或者释放。 3. 实现按键去抖动:按键的物理结构会导致按键输入产生抖动,需要采用去抖动算法来消除抖动,保证按键输入的稳定性。 4. 定义按键事件处理函数:当按键被按下或者释放时,需要执行相应的事件处理函数,根据不同的事件类型,执行相应的操作。 5. 添加按键检测时间:为了避免CPU过度占用,可以采用定时器来检测按键状态,定时器的时间间隔可以根据实际情况进行调整。 6. 设计按键管理接口:按键管理接口可以提供按键输入和事件处理的接口函数,以便其他模块可以调用和使用MCU按键管理框架的实现步骤如下: 1. 定义按键输入方式,包括短按、长按和连续按等方式。 #define KEY_SHORT_PRESS 0 #define KEY_LONG_PRESS 1 #define KEY_CONTINUOUS_PRESS 2 2. 设计按键扫描算法,可以采用轮询方式,检测按键状态。 void KeyScan(void) { static uint8_t key_press_cnt = 0; static uint8_t key_release_cnt = 0; static uint8_t key_status = 0; if (GPIO_ReadInputDataBit(KEY_GPIO_PORT, KEY_GPIO_PIN) == KEY_PRESSED) { if (key_press_cnt < KEY_DEBOUNCE_TIME) { key_press_cnt++; } if (key_press_cnt == KEY_DEBOUNCE_TIME) { key_status = KEY_PRESSED; } } else { if (key_release_cnt < KEY_DEBOUNCE_TIME) { key_release_cnt++; } if (key_release_cnt == KEY_DEBOUNCE_TIME && key_status == KEY_PRESSED) { key_status = KEY_RELEASED; key_press_cnt = 0; key_release_cnt = 0; } } } 3. 实现按键去抖动,可以采用延时方式来消除按键抖动。 #define KEY_DEBOUNCE_TIME 20 4. 定义按键事件处理函数,根据不同的事件类型,执行相应的操作。 void KeyEventHandler(uint8_t event_type) { switch (event_type) { case KEY_SHORT_PRESS: //执行短按操作 break; case KEY_LONG_PRESS: //执行长按操作 break; case KEY_CONTINUOUS_PRESS: //执行连续按操作 break; default: break; } } 5. 添加按键检测时间,可以采用定时器方式,定时检测按键状态。 #define KEY_SCAN_TIME 10 void KeyScanTimerHandler(void) { static uint8_t key_press_time = 0; static uint8_t key_long_press_time = 0; static uint8_t key_continuous_press_time = 0; static uint8_t key_event_type = 0; KeyScan(); if (key_status == KEY_PRESSED) { key_press_time++; if (key_press_time == KEY_SHORT_PRESS_TIME) { key_event_type = KEY_SHORT_PRESS; KeyEventHandler(key_event_type); } else if (key_press_time == KEY_LONG_PRESS_TIME) { key_event_type = KEY_LONG_PRESS; KeyEventHandler(key_event_type); } else if (key_press_time > KEY_LONG_PRESS_TIME && key_press_time % KEY_CONTINUOUS_PRESS_TIME == 0) { key_event_type = KEY_CONTINUOUS_PRESS; KeyEventHandler(key_event_type); } } else { key_press_time = 0; key_long_press_time = 0; key_continuous_press_time = 0; key_event_type = 0; } } 6. 设计按键管理接口,提供按键输入和事件处理的接口函数。 void KeyInit(void) { //初始化按键引脚 //初始化定时器 } void KeyTask(void) { //调用按键扫描函数 } MCU按键管理框架可以实现按键输入和事件处理的功能,可以应用于各种嵌入式系统中。可以根据实际需求进行定制化设计,提高系统的可靠性和稳定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值