野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 23212|回复: 12

有限状态机的使用

[复制链接]
发表于 2016-8-25 16:23:43 | 显示全部楼层 |阅读模式
本来是打算用火哥的F103板子,做实验的,结果jlink找不到了,所以就用了NUCLEO-F401的板子。使用有些状态机来实现,按键去抖动程序,用visio把UML图画出来。
效果是:按下按键,LED翻转一次。
然后根据这个图,编写按键检测程序:
  1. #define KEY_STATE_RELEASE    0        // 按键未按下
  2. #define KEY_STATE_WAITING    1        // 等待(消抖)
  3. #define KEY_STATE_PRESSED    2        // 按键按下(等待释放)

  4. #define readKey()                        HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_13)


  5. //等待时间,可以修改
  6. #define DURIATION_TIME         40

  7. /* 按键检测函数的返回值,按下为 1,未按下为 0 */
  8. #define PRESSED                 1
  9. #define NOT_PRESSED         0

  10. #define KEY_PRESSED                 0 //代表按下
  11. #define KEY_NOT_PRESSED         1 //代表未按下

  12. static int i = 0;

  13. uint8_t keyState = KEY_STATE_RELEASE;

  14. uint8_t keyDetect(void){
  15.         switch(keyState){
  16.                 case KEY_STATE_RELEASE:
  17.                         if(readKey() == KEY_PRESSED){ //=1代表按键按下
  18.                                 keyState = KEY_STATE_WAITING;
  19.                         }
  20.                         return NOT_PRESSED;
  21.                         break;

  22.                 case KEY_STATE_WAITING:
  23.                         if(readKey() == KEY_PRESSED){
  24.                                 i++;
  25.                                 if(i >= DURIATION_TIME){
  26.                                         i = 0;
  27.                                         keyState = KEY_STATE_PRESSED;
  28.                                         return PRESSED;
  29.                                 }else{
  30.                                         keyState = KEY_STATE_WAITING;
  31.                                         return NOT_PRESSED;
  32.                                 }
  33.                         } else{
  34.                                 i = 0;
  35.                                 keyState = KEY_STATE_RELEASE;
  36.                                 return NOT_PRESSED;
  37.                         }
  38.                         break;

  39.                 case KEY_STATE_PRESSED:
  40.                         if(readKey() == KEY_NOT_PRESSED){
  41.                                 keyState = KEY_STATE_RELEASE;
  42.                                 return NOT_PRESSED;
  43.                         }
  44.                         break;

  45.                 default:
  46.                         keyState = KEY_STATE_RELEASE;
  47.                         return NOT_PRESSED;
  48.                         break;
  49.         }
  50. }
复制代码
我是利用cube直接生成一个工程的,这个工程很久前(14年的)生成的(懒重新在去生成),用的是HAL库,主函数代码如下
  1. int main(void)
  2. {

  3.   HAL_Init();

  4.   SystemClock_Config();

  5.   HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0);
  6.   HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);


  7.   MX_GPIO_Init();
  8.         KEY_Init();

  9.         HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET);

  10.   while (1)
  11.   {        
  12.                 if( keyDetect() == PRESSED){
  13.                                 HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);        
  14.                 }
  15.                
  16.   }
  17.         
  18.         return 0;

  19. }
复制代码
LED配置和KEY配置
  1.   GPIO_InitTypeDef GPIO_InitStruct;

  2.   /* GPIO Ports Clock Enable */
  3.   __GPIOA_CLK_ENABLE();

  4.   /*Configure GPIO pin : PA5 */
  5.   GPIO_InitStruct.Pin = GPIO_PIN_5;
  6.   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  7.   GPIO_InitStruct.Pull = GPIO_NOPULL;
  8.   GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
  9.         
  10.   HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
复制代码
  1.   GPIO_InitTypeDef GPIO_InitStruct;

  2.   /* GPIO Ports Clock Enable */
  3.   __GPIOC_CLK_ENABLE();

  4.   /*Configure GPIO pin : PC13 */
  5.   GPIO_InitStruct.Pin = GPIO_PIN_13;
  6.   GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  7.   GPIO_InitStruct.Pull = GPIO_NOPULL;
  8.   GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
  9.         
  10.   HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
复制代码
装完逼了,跑了,不要打我0.0

***************************************补充****************************
有些资料超过10m了,传不上来。。
***************************************补充****************************
我也是初学者。。嘿嘿
链接: http://pan.baidu.com/s/1bXXuX4 密码: ecpa
slaa402a.pdf (139.37 KB, 下载次数: 123)

用状态机原理进行软件设计.pdf.pdf (267.81 KB, 下载次数: 242)

UML状态机C设计.pdf (4.49 MB, 下载次数: 155)



UMLkey.jpg
回复

使用道具 举报

发表于 2016-8-25 18:04:54 | 显示全部楼层
好厉害,求教学状态机编程可以看哪些资料
回复 支持 反对

使用道具 举报

发表于 2016-8-25 18:28:35 | 显示全部楼层
不错不错,我也想学学,求大神发资料
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-8-25 20:00:52 | 显示全部楼层
flyleaf 发表于 2016-8-25 18:28
不错不错,我也想学学,求大神发资料

发不上来 都说  太大了
回复 支持 反对

使用道具 举报

发表于 2016-8-25 22:35:54 来自手机 | 显示全部楼层
gq21 发表于 2016-8-25 20:00
发不上来 都说  太大了

传网盘后再发上来吧
回复 支持 反对

使用道具 举报

发表于 2016-8-26 08:59:07 | 显示全部楼层
谢谢分享
回复

使用道具 举报

 楼主| 发表于 2016-8-26 09:40:40 | 显示全部楼层

怎么可以发上来的 我电脑显示都是超过10m的
回复 支持 反对

使用道具 举报

发表于 2016-8-26 10:35:46 | 显示全部楼层
gq21 发表于 2016-8-26 09:40
怎么可以发上来的 我电脑显示都是超过10m的

那些小于10M的,大于10M的我有权限,但每次上传都会有错误,不知道什么问题
回复 支持 反对

使用道具 举报

发表于 2016-8-27 12:57:49 | 显示全部楼层
状态机,很好的应用
回复 支持 反对

使用道具 举报

发表于 2016-8-27 14:53:28 | 显示全部楼层
这么强大!!!!我知道三段式状态机!!!
回复 支持 反对

使用道具 举报

发表于 2016-8-27 15:17:48 | 显示全部楼层
谢谢楼主分享
回复 支持 反对

使用道具 举报

发表于 2016-8-27 15:18:07 | 显示全部楼层
谢谢楼主装逼的资料,谢谢管理员整理
回复 支持 反对

使用道具 举报

发表于 2016-8-30 11:37:46 | 显示全部楼层
我之前也写了一个状态机,独立按键的。最近搞了个矩阵按键的,也想加入状态机,搞了几天效果不明显,我是10ms中断扫描方式,楼主是多少时间去扫描的??
回复 支持 反对

使用道具 举报

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

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-11-22 08:48 , Processed in 0.062232 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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