温州网站制作套餐网站不推广如何排名

张小明 2025/12/29 11:02:57
温州网站制作套餐,网站不推广如何排名,红安县城乡建设局网站,四会城乡建设局网站第四章 流程管理的利器——状态机#xff08;上#xff09; 前言 很多学生会C语言#xff0c;很好#xff0c;你获得了学习嵌入式的入场券#xff1b;大部分同学会使用CPU外设#xff0c;Good#xff0c;你进入了嵌入式的大门#xff1b;有相当一部分学员会通过外设移…第四章 流程管理的利器——状态机上前言很多学生会C语言很好你获得了学习嵌入式的入场券大部分同学会使用CPU外设Good你进入了嵌入式的大门有相当一部分学员会通过外设移植外围电路的驱动Great你可以尝试做项目了但大部分人都卡死在这个位置只能做一个可怜的码农系统稍微复杂一点程序就写的一团乱麻自己都看不懂。遇见流程极其复杂的项目如何管理代码才能让整个程序变得十分优雅又方便调试呢使用状态机4.1 项目引入我在工作的时候接到这么一个技术支持项目也不难可以当个引入例子简单的电子时钟支持时间显示、时间设置、闹铃设置、闹铃、支持显示温度。硬件上八个8段数码管、两个按键上下排布配合一个RTC芯片和温度传感器默认上电先读取RTC后直接显示时钟显示格式为“HHMMSS”其中一个冒号占用一个数码管时间显示5s之后切换成温度显示格式为“TT.TC”温度显示5s后切换成时间显示如此循环在时钟显示界面如果同时按下两个按键进入菜单页面菜单用数字编码在数码管上闪烁显示在菜单页面通过按上下按钮用于切换菜单选中菜单之后同时按下两个按键进入当前菜单配置界面在菜单配置界面配置完成后按下两个按键跳出到菜单页面在菜单界面或者菜单配置界面如果超过30s未按下按键则直接退回到时间显示界面时间配置菜单编码为1进入此菜单后按上键调节小时按下键调节分钟特别地如果长按下键属于快速调节分钟闹铃配置菜单编码为2进入此菜单后按上键调节小时按下键调节分钟特别地如果长按下键属于快速调节分钟还有其他菜单这里砍了简化一下功能已经开始有人头疼了很多51单片机基础教程中都把编写电子钟的项目放到最后起到总结的效果。但是对于很多学生来说单独驱动按键、数码管、时钟芯片、温度传感器都没问题就是和在一块问题非常严重包括但不限于逻辑混乱理不清一千个初学者和中学者就有1001个程序架构功能代码和跳转的变量不得不放在同一个函数里边但凡拆分称不同变量就要上全局变量按键按下数码管卡壳甚至直接歇菜数码管显示那么多不同内容不知道咋处理最好旧功能写好了添加新功能时发现程序架构不兼容需要推倒重做按键按下顺序不一样会出现各种不同的bug等。以至于很多学员跟着视频或者课本敲了一遍电子钟程序之后既没有分析也没有调试就直接结项然后自信满满的说“51已经轻松拿捏”。可真正去做项目的时候还是一个头两个大驱动都调通了咋揉和一块呢为何揉在一块老是出bug呢这个垃圾新功能为啥不能兼容老程序呢4.2 状态机的引入无论多复杂的项目都可以用“状态机”来统一管理在编写代码之前先把项目要求进行拆分简单的拆分方法是分成“状态State”和“状态转移条件Switch”两部分。4.2.1 状态区分举个例子这个项目有那么多条件真正能够区分的其实就是如下几个状态初始Init、正常显示NormalShow、菜单Menu、时间设置TimeSet、闹铃设置AlarmSet五个状态根据自己的习惯也可以进一步的粗分和细分状态数量4.2.2 状态功能在每个状态下代码功能都是简单的、独立的可以独立编写和调试。初始Init状态下初始化RTC、温度传感器这都能在demo中找到源码直接复制过来就能用正常显示NormalShow状态下定时读取RTC数码管显示时间定时读取温度传感器数码管显示温度实现时间显示5s温度显示5s如果嫌麻烦的话可以把此状态拆分为俩然后5s切换一下状态也是可以的菜单Menu模式下上下按键切换菜单内容需要按键和数码管配合也不难时间设置TimeSet、闹铃设置AlarmSet状态上下按键切换时间也是一个简单的功能4.2.3 状态切换在每个状态下如何切换到下一个状态也都是有条件的比如初始Init状态结束后直接进入正常显示NormalShow状态正常显示NormalShow下同时按下两个按键进入菜单Menu状态在时间设置TimeSet界面如果同时按下两个按键就回到菜单Menu状态如果超过30s未动作就回到正常显示NormalShow状态这些就是状态转移条件。4.2.4 状态机整理表格一般教材喜欢画状态转移图我不会这里就用列表来总结上边的操作。名字标签功能转出条件初始Init初始化硬件初始完成切换到正常显示NormalShow状态正常显示NormalShow读取RTC和温度传感器显示时间和温度5s切一次到闹铃时间提示闹铃同时按下Key_Up和Key_Down进入菜单Menu状态菜单Menu显示功能菜单两个按键切换菜单同时按下Key_Up和Key_Down根据菜单编号分别进入时间设置TimeSet、闹铃设置AlarmSet状态时间设置TimeSetKey_Up小时、Key_Down分钟Key_Down长按则分钟快调1、同时按下Key_Up和Key_Down进入菜单Menu状态2、30s无动作则进入正常显示NormalShow闹铃设置AlarmSetKey_Up小时、Key_Down分钟Key_Down长按则分钟快调1、同时按下Key_Up和Key_Down进入菜单Menu状态2、30s无动作则进入正常显示NormalShow4.3 简单状态机的代码编写根据4.2章节的分析各个状态功能基本都是独立的可以很容易编写和调试现在只要管理好各个状态的切换即可。这样代码编写就会被拆分成若干个子过程而不是把所有的状态分析混成一锅粥来统一编写4.3.1 状态枚举阅读其他大型代码无一例外状态的设置都是用的枚举没有一个用define的。用枚举有啥好处枚举的值默认从0开始依次1数据绝对不会重复强行重复也会提示错误而用define所有状态的编号需要用户自己管理枚举名字自定义不仅方便阅读也能当连续的数字索引用define当数字索引管理极其麻烦最重要的是枚举想要添加一个状态只需要在其中任意位置插入新状态就行其他状态的值会自动发生变化程序员完全不用参与旧代码完全兼容不做任何修改就可以兼容而define添加新状态后需要认真进行管理一个不小心可能就跑飞了鉴于此我们这里依然用枚举进行状态定义typedef enum { State_Init, //初始状态索引默认从0开始 State_NormalShow, State_Menu, State_TimeSet, State_AlarmSet, State_Max } State_Def;4.3.2 编写各个状态下的程序代码这里假如各种状态下运行代码运行的驱动都搞定了只着眼于状态机的编写。后续用到哪个函数就在程序中进行注释。这里每一个状态下的程序功能都可以单独编写和和调试。4.3.3 状态运行函数重点之一编写stateMachineRun()函数用于根据状态的不同运行不同的函数其实就是switch语句进行拆分//全局变量用于保存当前状态机状态 static State_Def g_CurState State_Init; //保存按键状态的变量通过调用getKey()函数来获取 //1表示按下0表示未按下 static char key_up, key_down; void stateMachineRun(void) { switch(g_CurState) { case State_Init: //初始化状态执行硬件初始化函数 BSPInit(); break; case State_NormalShow: //正常显示状态执行显示时间和温度的函数 //这里更新显示码 //具体数码管扫描推荐使用定时器下同 normalShow(); break; case State_Menu: //菜单状态显示菜单函数 //进入函数判断一次按键决定是否上下翻然后立马跳出不允许阻塞或者延时 showMenu(); break; case State_TimeSet: //根据上下按键决定数字是否发生变化 //然后立马退出不允许阻塞或延时 setTime(); break; case State_AlarmSet: //同上 setAlarm(); break; default: break; } }再次强调上边出现的函数除了BSPInit()之外其他函数都不允许阻塞或者延时每次调用就执行一个循环流程只要状态不改这些函数就会不停地刷新。这是状态机的优势所在4.3.4 状态切换函数重点之二状态切换函数非常重要根据条件进行状态的转移//记录超时时间的时间戳 //要求定时器中1s自加一次 static int timeTicket 0; //1s定时器中断让timeTicket自加 void timerEvent() { timeTicket; } void stateMachineSwitch(void) { if((key_up 1) || (key_down 1)) { //有按键按下则超时戳清零 timeTicket 0; } switch(g_CurState) { case State_Init: //初始化函数执行完成之后 //直接切换到正常显示模式 g_CurState State_NormalShow; break; case State_NormalShow: //双键按下切换到菜单状态 if((key_up 1) (key_down 1)) { g_CurState State_Menu; timeTicket 0; //超时戳清零 } break; case State_Menu: if(timeTicket 30) { //超时则退回正常显示模式 g_CurState State_NormalShow; } //双键按下切换到子菜单状态 if((key_up 1) (key_down 1)) { //获取当前选择的菜单码 int menu getMenu(); //根据菜单码来确定进入哪个子菜单 if(menu 1) g_CurState State_TimeSet; if(menu 2) g_CurState State_AlarmSet; } break; case State_TimeSet: if(timeTicket 30) { //超时则退回正常显示模式 g_CurState State_NormalShow; } //双键按下切换到菜单状态 if((key_up 1) (key_down 1)) { g_CurState State_Menu; } break; case State_AlarmSet: if(timeTicket 30) { //超时则退回正常显示模式 g_CurState State_NormalShow; } //双键按下切换到菜单状态 if((key_up 1) (key_down 1)) { g_CurState State_Menu; } break; default: break; } }4.3.5 状态机函数整合上边关于状态运行和状态切换的函数都已经编写完成后续在添加一些辅助函数就可以打包成一个程序void stateMachine(void) { getKey(key_up,key_down); //获取按键状态 stateMachineRun(); //按键状态运行 stateMachineSwitch(); //按键状态切换 }这样的函数在主程序的主循环里边就可以不停地调用这也就是为啥状态机里边的函数不允许阻塞的原因因为外边有个大循环框着呢。至此简单状态机代码架构已经编写完成4.4 总结个人认为这是性价比比较高的状态机编写方法大家一定要掌握编写使用技巧。上边咱们已经编写了最简单的状态机编码只是不同的状态机流程都需要大改上边提到的每一个函数特别是状态转移函数stateMachineSwitch()。如果这个架构是自己编写的还好维护如果让其他人接手依然是一个头两个大不利于程序的维护如果故意想写屎山代码当我没说。能不能编写一个通用的状态机代码用户只需像填充表格一样集中管理状态代码、状态转移条件就能适用各种流程的状态机甚至是状态机里边套子状态机关于通用的状态机代码编写咱们放大下一篇文章继续研究。
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

网站开发 书网站页面设计风格

学生信息管理 目录 基于ssm vue学生信息管理系统 一、前言 二、系统功能演示 三、技术选型 四、其他项目参考 五、代码参考 六、测试参考 七、最新计算机毕设选题推荐 八、源码获取: 基于ssm vue学生信息管理系统 一、前言 博主介绍:✌️大厂…

张小明 2025/12/25 22:26:14 网站建设

那些网站被k恢复是怎么做的国家企业信用信息公示系统官网河北

计算机中的熵与算法复杂度解析 在计算机科学领域,熵和算法复杂度是两个重要的概念。熵主要涉及随机数生成,而算法复杂度则用于衡量算法的性能和可扩展性。下面将详细介绍这两个方面的内容。 1. 熵与随机数生成 1.1 熵的概念起源 在信息领域,伟大的数学家约翰冯诺伊曼建议…

张小明 2025/12/25 22:25:39 网站建设

网站建设 验证码wordpress网站没有阅读量

别再说 “零基础学不了网安”!电脑小白也能入门的 4 阶段路线. 总有人问:“我连代码都不会写,能学网络安全吗?” 其实真不用怕,哪怕你是只会用电脑刷视频的纯小白,跟着清晰的路线一步步学,照样…

张小明 2025/12/25 22:25:05 网站建设

能帮忙做网站建设wordpress 推流

利用法线和位移映射添加表面细节 1. 引言 位移映射是基于从高度图纹理采样的信息来移动顶点(通常通过细分过程创建)的过程。它在传统法线映射的基础上进行扩展,为表面提供更多细节。位移映射并非替代法线映射,二者协同工作可产生更逼真的效果。法线映射通过操纵光照来呈现…

张小明 2025/12/25 22:23:59 网站建设

主营商城网站建设国外模板网站

第一章:Dify 与 Spring AI 的 API 适配在构建现代AI驱动的应用时,Dify 作为低代码AI应用开发平台,提供了直观的流程编排和模型管理能力。而 Spring AI 作为基于 Spring 生态的 AI 开发框架,为 Java 开发者提供了统一的 API 接口来…

张小明 2025/12/25 22:23:24 网站建设

网站平台开发报价表怎么做做网站背景图片怎么放

C2000系列DSP的堆栈评估方法 一、C2000堆栈评估的核心原理 C2000(如F28x/F28004x/F2837xD等)的堆栈(Stack)是RAM中一块向下生长的连续内存区域,用于存储: 函数调用的返回地址; 局部变量(自动变量); 函数参数; 中断上下文(中断发生时CPU自动压栈的寄存器); 手动…

张小明 2025/12/25 22:22:50 网站建设