找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2516|回复: 1
打印 上一主题 下一主题
收起左侧

状态机思想在单片机中的应用 附程序和大量资料

[复制链接]
跳转到指定楼层
#
FSM,有限状态机。在一个高效的程序中,一般都能看到状态机的身影。最近自己在试着将自己写的程序用状态机的思想重新整一遍,找了一些资料,分享下。如有侵权,望告知,马上删除。。

单片机状态机的全部资料下载:
状态机.rar (12.5 MB, 下载次数: 135)

我自己参考别人更改的状态机按键扫描程序:
  1. enum FSM_key_status
  2. {
  3.         _Idle = 0,
  4.         _Key1_Down,
  5.         _Key1_Press,
  6.         _Key1_Up,
  7.         _Key2_Down,
  8.         _Key2_Press,
  9.         _Key2_Up,               
  10. };


  11. uchar event_key_scan(void)
  12. {
  13.         static volatile uchar key_status = 0;                                //按键状态累计
  14.         static volatile uchar key_restate = 0;                                //按键状态累计
  15.         static volatile uint key_count = 0;                                        //按键保持时间累计
  16.         volatile uchar  key_return = 0;                                                //按键返回值
  17.         static uchar key_type=0;
  18.         uchar num = 0;
  19.         uchar new_key=0;
  20.        
  21.         new_key = _pa & 0x06;
  22. //        num = Judge_key(new_key);                                //存在多个按键连按时
  23.         if(num == 1)
  24.                 LED_G_ON;

  25.         switch(key_status)
  26.         {
  27.                 case _Idle:                                                                        //空闲状态时判断按键是否按下,判定为按下时按键状态累计加1
  28.                         {
  29.                                 switch(num)
  30.                                 {
  31.                                         case 1:
  32.                                                 {
  33.                                                         key_restate = new_key;
  34.                                                         key_status = _Key1_Down;               
  35.                                                 }        break;
  36.                                         case 2:
  37.                                                 {
  38.                                                         key_restate = new_key;
  39.                                                         key_status = _Key2_Down;       
  40.                                                 }        break;
  41.                                         default:        break;       
  42.                                 }
  43.                                 key_status = 0;
  44.                                 key_count = 0;
  45.                                 key_return = 0;                                                                                //未按下时清除相应的变量
  46.                                 key_type = 0;
  47.                         }        break;
  48.                 case _Key1_Down:
  49.                         {
  50.                                 switch(num)
  51.                                 {
  52.                                         case 1:
  53.                                                 {
  54.                                                         if(key_restate == new_key)
  55.                                                                 key_status++;
  56.                                                         else                                                       
  57.                                                                 key_status = _Idle;
  58.                                                                
  59.                                                 }        break;
  60.                                         case 2:
  61.                                                 {
  62.                                                         key_restate = new_key;
  63.                                                         key_status = _Key2_Down;
  64.                                                 }        break;
  65.                                         default:  key_status = _Idle;  break;       
  66.                                 }                               
  67.                         }        break;       
  68.                 case _Key1_Press:                                                                //按键为按下状态时,累计按下的时间
  69.                         {
  70.                                 switch(num)
  71.                                 {
  72.                                         case 1:
  73.                                                 {
  74.                                                         if(key_restate == new_key)
  75.                                                                 key_count++;
  76.                                                         else                                                       
  77.                                                                 key_status++;       
  78.                                                         if(key_restate == K_LED)
  79.                                                                 key_type = 1;
  80.                                                         else
  81.                                                                 key_type = 2;
  82.                                                 }        break;
  83.                                         case 2:
  84.                                                 {
  85.                                                         key_restate = new_key;
  86.                                                         key_status = _Key2_Down;
  87.                                                         key_type = 0;
  88.                                                         key_count = 0;
  89.                                                 }        break;
  90.                                         default:
  91.                                                 {
  92.                                                         key_status = _Idle;
  93.                                                         key_type = 0;
  94.                                                         key_count = 0;
  95.                                                 }  break;       
  96.                                 }       
  97.                         }        break;
  98.                 case _Key1_Up:                                                                        //按键放开后,根据保持时间来判断是长按还是短按
  99.                         {
  100.                                 if(key_count < 100)
  101.                                 {
  102.                                         if(key_type == 1)
  103.                                                 key_return = _LED_Short_Press;
  104.                                         else
  105.                                                 key_return = _MIST_Short_Press;       
  106.                                 }
  107.                                 else
  108.                                         if(key_type == 1)
  109.                                                 key_return = _LED_Long_Press;
  110.                                         else
  111.                                                 key_return = _MIST_Long_Press;       
  112.                                 key_count = 0;
  113.                                 key_type = 0;
  114.                                 key_status = _Idle;
  115.                                 key_restate = new_key;
  116.                         }        break;
  117.                  case _Key2_Down:
  118.                          {
  119.                                  if(key_restate == new_key)
  120.                                         key_status++;
  121.                                 else                                                       
  122.                                         key_status = _Idle;                       
  123.                          }        break;
  124.                  case _Key2_Press:
  125.                          {
  126.                                  if(key_restate == new_key)
  127.                                          key_count++;
  128.                                  else
  129.                                          key_status++;       
  130.                          }        break;
  131.                   case _Key2_Up:
  132.                           {
  133.                                   if(key_count > 100)
  134.                                         key_return = _Double_Press;
  135.                                 key_count = 0;
  136.                                 key_type = 0;
  137.                                 key_status = _Idle;
  138.                                 key_restate = new_key;
  139.                           }        break;
  140.                 default: break;       
  141.         }       
  142.         return key_return;               
  143. }
复制代码


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏7 分享淘帖 顶 踩
回复

使用道具 举报

楼主
ID:108573 发表于 2020-1-14 13:06 | 只看该作者
好帖子,学习一下
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表