STM32实战项目-状态机函数应用
创始人
2024-05-29 10:12:49
0

前言:

本章主要介绍一下,状态机在工程中的应用,下面我会通过这种方式点亮LED灯,来演示他的妙用。

目录

1、状态机应用

1.1流水灯函数

1.1.1led.h

1.1.2led.c

1.2状态机函数

1.2.1定义举常量

1.2.2结构体封装


1、状态机应用

有限状态机是一种概念思想,把复杂的控制逻辑分解成有限个稳定状态,组成闭环系统,通过事件触发,让状态机按设定的顺序处理事务;

单片机C语言的状态机编程,是利用条件选择语句(switch -- case)切换状态,通过函数内部指令改变状态机状态,让程序按设定的顺序执行。

如上图所示:五个状态分别对应五个流程分别对应五种状态,我们可以使用结构体封装,保存五个状态的函数的指针。 

1.1流水灯函数

为了方便程序移植,阅读,我们自己定义源文件 LED.C和头文件LED.H头文件中放,流水灯函数的声明和定义,源文件中放函数的实现。 

1.1.1led.h

/¶¨Òåö¾ÙÀàÐÍ
typedef enum
{LED1 = (uint8_t)0x01,LED2 = (uint8_t)0x02,LED3 = (uint8_t)0x03,
}LED_Num_t;//¶¨Òå½á¹¹ÌåÀàÐÍ
typedef struct
{void (*LED_ON)(uint8_t);     //´ò¿ªvoid (*LED_OFF)(uint8_t);    //¹Ø±Õvoid (*LED_Flip)(uint8_t);   //·­×ª
} LED_t;/* extern variables-----------------------------------------------------------*/
extern LED_t  LED;

1.1.2led.c

static void LED_ON(uint8_t); 
static void LED_OFF(uint8_t);
static void LED_Flip(uint8_t);/* Public variables-----------------------------------------------------------*/
LED_t LED = 
{LED_ON,LED_OFF,LED_Flip
};static void LED_ON(uint8_t LED_Num)
{//Ìõ¼þÑ¡ÔñÓï¾äswitch(LED_Num){case LED1: HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_SET); break;case LED2: HAL_GPIO_WritePin(LED2_GPIO_Port,LED2_Pin,GPIO_PIN_SET); break;case LED3: HAL_GPIO_WritePin(LED3_GPIO_Port,LED3_Pin,GPIO_PIN_SET); break;default: System.Assert_Failed();}
}
static void LED_OFF(uint8_t LED_Num)
{//Ìõ¼þÑ¡ÔñÓï¾äswitch(LED_Num){case LED1: HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_RESET); break;case LED2: HAL_GPIO_WritePin(LED2_GPIO_Port,LED2_Pin,GPIO_PIN_RESET); break;case LED3: HAL_GPIO_WritePin(LED3_GPIO_Port,LED3_Pin,GPIO_PIN_RESET); break;default: System.Assert_Failed();}
}static void LED_Flip(uint8_t LED_Num)
{//Ìõ¼þÑ¡ÔñÓï¾äswitch(LED_Num){case LED1: HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin); break;case LED2: HAL_GPIO_TogglePin(LED2_GPIO_Port,LED2_Pin); break;case LED3: HAL_GPIO_TogglePin(LED3_GPIO_Port,LED3_Pin); break;default: System.Assert_Failed();}
}

 我们可以看到在led.c函数中,我们封装的三个函数指针分别实现了,led的开、关、和翻转,至于ON,OFF,TogglePin 这些都是HAL库自己定义的我们可以看看他的函数实现,如下图所示:

 至于端口和引脚,这个在我们使用cubemax的时候,配置好参数的时候,已经自动初始化完成了。

1.2状态机函数

1.2.1定义举常量

 首先定义五个枚举常量,不同常量对应不同选择,也就会有不同的状态。

//¶¨Òåö¾ÙÀàÐÍ
typedef enum
{STA1   = (uint8_t)0x01, STA2   = (uint8_t)0x02, STA3   = (uint8_t)0x03, STA4   = (uint8_t)0x04, STA5   = (uint8_t)0x05,
} STA_Machine_Status_t;

1.2.2结构体封装

使用结构体封装五个函数指针,方便在运行函数中进行调用,具体代码如下:

//¶¨Òå½á¹¹ÌåÀàÐÍ
typedef struct
{STA_Machine_Status_t  ucSTA_Machine_Status;  //״̬»ú״̬void (*Fun_STA1)(void); void (*Fun_STA2)(void);void (*Fun_STA3)(void);void (*Fun_STA4)(void);void (*Fun_STA5)(void);
} STA_Machine_t;

 这五个函数指针指向五个函数,分别实现led的亮灭,所以函数内部又调用了led的函数,具体代码如下:

void Fun_STA1()
{HAL_Delay(500);      //ÑÓʱ500msLED.LED_Flip(LED1);  //·­×ªLED1,ÃðµÆLED.LED_Flip(LED2);  //·­×ªLED2,ÃðµÆLED.LED_Flip(LED3);  //·­×ªLED3,ÃðµÆ//״̬»úÇл»ÖÁ״̬2STA_Machine.ucSTA_Machine_Status = STA2;
}void Fun_STA2()
{HAL_Delay(500);      //ÑÓʱ500msLED.LED_ON(LED1);    //LED1ÁÁµÆLED.LED_OFF(LED2);   //LED2ÃðµÆLED.LED_OFF(LED3);   //LED3ÃðµÆ//״̬»úÇл»ÖÁ״̬3STA_Machine.ucSTA_Machine_Status = STA3;
}void Fun_STA3()
{HAL_Delay(500);      //ÑÓʱ500msLED.LED_OFF(LED1);   //LED1ÃðµÆLED.LED_ON(LED2);    //LED2ÁÁµÆLED.LED_OFF(LED3);   //LED3ÃðµÆ//״̬»úÇл»ÖÁ״̬4STA_Machine.ucSTA_Machine_Status = STA4;
}void Fun_STA4()
{HAL_Delay(500);      //ÑÓʱ500msLED.LED_OFF(LED1);   //LED1ÃðµÆLED.LED_OFF(LED2);   //LED2ÃðµÆLED.LED_ON(LED3);    //LED3ÁÁµÆ//״̬»úÇл»ÖÁ״̬5STA_Machine.ucSTA_Machine_Status = STA5;
}void Fun_STA5()
{HAL_Delay(500);      //ÑÓʱ500msLED.LED_ON(LED1);    //LED1ÁÁµÆLED.LED_ON(LED2);    //LED2ÁÁµÆLED.LED_ON(LED3);    //LED3ÁÁµÆ//״̬»úÇл»ÖÁ³õʼ״̬1STA_Machine.ucSTA_Machine_Status = STA1;
}

这样的话一个完整的状态机就完成了,我们软件框架并没有改变,只是将调用的run函数内部进行了修改。整体的框架如下图所示:

 

相关内容

热门资讯

李光洁32天走7500公里吃8... 李光洁32天走7500公里吃8城,《拿一座城市下酒》这部纪录片怎么样?我觉得这部纪录片非常好,观看的...
每我世如你果只没界喜就欢的生一... 每我世如你果只没界喜就欢的生一爱有你过在想会。把这22个字组成一句话。我想过,如果在每一生只喜欢你,...
调查校园里的植物和动物说说有哪... 调查校园里的植物和动物说说有哪些动植物?可以分成几类?兰花,梅花可人丌··植物:乔木(杨树、柳树、银...
血脂高的原因? 血脂高的原因?血脂高的原因高血脂的诱因包括原发性和继发性两种:原发性高血脂症的病因:1、遗传因素。2...
为什么孩子总是重复看同一集动画... 为什么孩子总是重复看同一集动画片?是在传递这3个信号 小孩子爱看动画片是非常普遍的,动画片带给他们动...
终极三国里 49集刘备为什么这... 终极三国里 49集刘备为什么这么做?有没有官方回答?下集自己看吧 现在不会有官方回答的哟第一:可能真...
西式糕点制作大全的内容简介 西式糕点制作大全的内容简介《西式糕点制作大全》主要介绍了制作甜点的基本知识,例如各种制作工具,制作点...
逻辑思维又是什么?就是推理吗,... 逻辑思维又是什么?就是推理吗,怎么培养!?逻辑思维是一种严格分析思维。不一定是推理。推理是逻辑思维的...
囊萤夜读有一句俗语就是出自这个... 囊萤夜读有一句俗语就是出自这个故事你知道是什么吗?囊萤映雪 ( náng yíng yìng xuě...
什么是不伦恋情? 什么是不伦恋情?什么是不伦恋情.,?男跟女年龄相差很大?还是?男的比女的小?还是老夫少妻?是近亲谈恋...
有书名带晨星的嘛? 有书名带晨星的嘛?有书名带晨星的嘛?晨星传这本书。漫画书晨星物语
如果有些事情说不出口怎么办? 如果有些事情说不出口怎么办?烦恼皆是因为自己过分的执着 即使你在这样子下去 更不就不会有好的结果 为...
有哪些类似于《非自然死亡》题材... 有哪些类似于《非自然死亡》题材的日剧推荐?非自然死亡的题材电影确实不多,电视剧的话也不好找啊。不喜欢...
素书全集的内容简介 素书全集的内容简介 本书采用了《素书》的权威原著,参照《四库全书》并加上了宋代宰相张商英的注和清代王...
【世纪花园】小区对口的学校有重... 【世纪花园】小区对口的学校有重点小学和初中吗?世纪花园东区里有未来强者幼儿园,小区南边有个华兴小区,...
东南大学现有的专业中有哪些是属... 东南大学现有的专业中有哪些是属于老东南的1928年学校改名为国立中央大学,设理、工、医、农、文、法、...
一个男人一有钱就请朋友吃饭,没... 一个男人一有钱就请朋友吃饭,没钱就又说,买东西还赊账,商店里的老板都找上门来了?像陵念前这种男人的话...
坟上栽什么草好? 坟上栽什么草好?坟地种什么草好耐旱坟上栽野蕨草、扎根不深、浅根植物、可以固土、南方雨水多、不会造成坟...
关于国富潜力基金 关于国富潜力基金我9月24日上午买的国富基金,申购价格是9月24日开盘的价格吗?还是9月28日开盘的...
我是一个高中生。想学武术。在学... 我是一个高中生。想学武术。在学校没什么时间。是练散打还是跆拳道好。我是一个高中生。想学武术。在学校没...