单片机程序构架-状态机1(转载)
- 格式:doc
- 大小:81.00 KB
- 文档页数:7
单⽚机的状态机框架编写_续之前⼤致写过⼀篇状态机⽐较粗糙的博⽂,写了:状态机的⽅式⽐较适合裸机编程,但是不够深⼊,这⾥在深⼊⼀点,起因是美敦⼒medtronic公开了PB560呼吸机完整设计资料,⾥⾯⽤到了ST10F276的芯⽚,就是⽤的状态机的思想,所以状态机的思想肯定是⽐较好的,不然⼤公司不会使⽤这个框架来做呼吸机啊,这可是医疗产品,质量必须过关的。
整个产品都要经过医疗认证的,⽆论是电⽓、软件、结构等等。
因此中⼩型裸机项⽬,使⽤状态机来编程应该是毫⽆压⼒的。
但是要⽤好,还是要好好规划⼀下。
状态机的使⽤离不开定时器,通常是使⽤定时中断来触发⼀个时间来切换状态机的状态的,⽐如按键,10ms就去处理⼀下按键处理⼦程序,理想情况下,10ms基本上能够轮询到这个按键⼦程序,但是主程序通常不⽌⼀个处理⼦函数啊,还有其他的程序如下⾯所⽰,那请问,10ms到了,主程序能否执⾏完其他的函数呢,即能否在10ms左右再次进⼊按键⼦程序?不⼀定,要看1、单⽚机的主频,2、看外部设备的处理速度,3、单⽚机和外部芯⽚的通信速度,4、单⽚机其他函数的数学、逻辑计算量。
1、单⽚机主频越⾼,那么相应的数学计算,逻辑运算都会提升不少。
2、与外部芯⽚的通信速度,这个稍稍复杂,涉及到硬件的布线,是否允许⾼速通信,涉及到抗⼲扰,⾼频电路等;还有涉及到通信协议,SPI(MHZ)的速度⽐IIC(KHZ)快上⼀个数量级,⽽且spi还有qspi,dspi等⾼速通信的⽅式,这个速度就更加快了,当然单⽚机的总线速度也要⽐较⾼才⾏,不⽀持⾼速,那么只能低速了。
3、外部芯⽚的处理速度,有的芯⽚如果处理的很慢,⽐如ds18b20,开启转换到转换结束,最慢700多ms,那么就⼲脆把两个状态使⽤状态机来处理,不⽤死等,基本上耗费的时间就是单⽚机对于单总线的数据访问的时间了。
看datesheet,⼀般都是us级别的,⼏ms的时间肯定是通信完成的。
但是尽量在2ms以内处理完毕。
单片机程序架构设计
在嵌入式系统开发中,单片机程序架构设计是非常重要的一环。
单片机程序架构设计涉及到软件和硬件的协同工作,以及系统功能
的实现和性能优化。
一个好的单片机程序架构设计可以提高系统的
稳定性、可靠性和可维护性,同时也能提高系统的性能和功耗效率。
首先,在单片机程序架构设计中,需要考虑的是系统的整体架构。
这包括系统的功能模块划分、模块之间的通信方式、数据传输
和处理流程等。
一个清晰的系统架构可以帮助开发人员更好地理解
系统的工作原理,提高开发效率和系统的可维护性。
其次,单片机程序架构设计还需要考虑系统的硬件和软件的协
同工作。
在硬件方面,需要考虑单片机的选择、外围器件的选型以
及硬件接口的设计。
在软件方面,需要考虑系统的任务调度、中断
处理、驱动程序的设计以及应用程序的开发。
硬件和软件的协同工
作可以提高系统的性能和稳定性。
此外,单片机程序架构设计还需要考虑系统的功耗优化。
在嵌
入式系统中,功耗是一个非常重要的指标。
通过合理的程序架构设
计和硬件设计,可以降低系统的功耗,延长系统的使用时间,提高
系统的可靠性。
总之,单片机程序架构设计是一个复杂而又重要的工作。
一个好的单片机程序架构设计可以提高系统的性能和稳定性,降低系统的功耗,提高系统的可维护性。
因此,在单片机程序开发过程中,需要重视程序架构设计这一环节,从而打造出更加优秀的嵌入式系统。
单片机主循环程序架构的标准可以根据具体的单片机型号和开发平台而有所差异,但通常遵循以下基本结构:
1.初始化:在程序开始时进行初始化设置,包括设置IO口、定时器、中断等。
这些设置
将在主循环中使用。
2.主循环:主循环是程序的核心部分,它通过一个无限循环来执行主要任务。
主循环中的
代码根据需求周期性地执行各种功能模块,例如数据采集、数据处理、控制操作等。
3.中断服务程序(Optional):如果需要处理外部事件或定时中断,可以编写相应的中断
服务程序。
这些中断服务程序会在中断触发时被调用,执行特定的操作,并在完成后返回到主循环。
4.低功耗模式(Optional):对于需要低功耗要求的应用,可以在主循环中添加进入和退
出低功耗模式的指令,以降低系统能耗。
5.系统状态检测和错误处理:在主循环中可以添加状态检测和错误处理的代码,以确保系
统正常运行并及时处理异常情况。
6.调试和日志记录(Optional):为了方便调试和故障排除,可以在程序中添加调试信息
输出和日志记录功能。
需要根据具体应用的要求和单片机的特性进行调整和扩展。
同时,良好的代码结构、模块化设计和注释能够使程序更易读、维护和扩展。
在编写代码时,还应考虑代码的效率和实时性,以提高系统的性能和响应能力。
单片机裸奔之状态机浅谈说到编程,不得不说到状态机,状态机做为软件编程的主要架构已经在各种语言中应用,固然包括,在一个思路清楚而且高效的程序中,必定有状态机的身影出现。
灵便的应用状态机不仅是程序更高效,而且可读性和扩展性也很好。
状态无处不在,状态中有状态,只要把握了这种思维,让它成为您编程中的一种习惯,信任您会受益匪浅。
状态机可归纳为4个要素,即现态、条件、动作、次态。
这样的归纳,主要是出于对状态机的内在因果联系的考虑。
“现态”和“条件”是因,“动作”和“次态”是果。
详解如下:①现态:是指当前所处的状态。
②条件:又称为“大事”。
当一个条件被满足,将会触发一个动作,或者执行一次状态的迁移。
③动作:条件满足后执行的动作。
动作执行完毕后,可以迁移到新的状态,也可以照旧保持原状态。
动作不是必须的,当条件满足后,也可以不执行任何动作,挺直迁移到新状态。
④次态:条件满足后要迁往的新状态。
“次态”是相对于“现态”而言的,“次态”一旦被激活,就改变成新的“现态”了。
假如我们进一步归纳,把“现态”和“次态”统一起来,而把“动作”忽视(降格处理),则只剩下两个最关键的要素,即:状态、迁移条件。
状态机的表示要领有许多种,我们可以用文字、图形或表格的形式来表示一个状态机。
举个容易的例子:就按键处理来说,击键动作本身也可以看做一个状态机。
一个细小的击键动作包含了:释放、颤动、闭合、颤动和重新释放等状态。
当我们打开思路,把状态机作为一种思想导入到程序中去时,就会找处处理疑问的一条有效的捷径。
有时候用状态机的思维去思量程序该干什么,比用控制流程的思维去思量,可能会更有效。
这样一来状态机便有了更实际的功用。
废话不多说,实践才是检验真理的唯一标准。
第1页共4页。
单片机状态机编程逻辑单片机是一种集成电路,可以实现各种功能,其中之一就是状态机编程。
状态机是一种描述系统行为的模型,通过定义不同的状态和状态转移条件,可以精确地控制系统的运行。
在单片机中,状态机编程可以用来实现各种任务的调度和控制,提高系统的效率和可靠性。
一、状态机的基本概念状态机由状态和状态转移构成。
状态是指系统在某一时刻所处的状态,可以是开启、关闭、等待等。
状态转移是指系统由一个状态转移到另一个状态的过程,可以通过某些条件触发。
状态机可以用有限状态机(Finite State Machine, FSM)表示,由有限个状态和状态转移构成。
二、状态机的实现方法在单片机中,状态机可以通过编程实现。
以下是一种常见的实现方法:1. 定义状态和状态转移条件:首先,根据系统的需求,定义系统可能的状态和状态之间的转移条件。
例如,一个灯的状态机可以定义为两个状态:开启和关闭,状态之间可以通过按下开关触发转移。
2. 初始化状态:在程序开始时,将系统的状态初始化为初始状态。
例如,将灯的状态初始化为关闭状态。
3. 状态切换:根据系统的需求,在程序中定义状态之间的转移条件和相应的操作。
例如,当按下开关时,如果灯的状态为关闭,则将灯的状态切换为开启;如果灯的状态为开启,则将灯的状态切换为关闭。
4. 状态处理:根据系统的需求,在程序中定义每个状态下的操作。
例如,当灯的状态为开启时,执行开启灯的操作;当灯的状态为关闭时,执行关闭灯的操作。
5. 状态迁移:在程序中通过判断状态转移条件是否满足来触发状态的切换。
例如,在每次循环中检测开关是否按下,如果按下则进行状态切换。
三、状态机编程的应用状态机编程在单片机中有广泛的应用,可以用来实现各种任务的调度和控制。
1. 系统任务调度:状态机可以用来实现系统中不同任务的调度。
例如,一个自动控制系统中可能有多个任务,如温度监测、风扇控制、报警等,可以通过状态机编程实现这些任务的调度,根据不同的状态执行相应的任务。
项目4简易数字钟的设计(2)计算机专业有门必修课程叫“软件工程”,这门课程告诉软件学习者们如何系统性的、规范化的、可定量的过程化方法去开发和维护软件。
我们在学习单片机编程的过程当中,也应该借鉴“软件工程”课程当中的讲述的方法和手段,去维护和规范我们的单片机程序。
在本单元当中,我们安排了4个任务。
任务1介绍了一种基于状态机的程序框架,通过状态机的学习,初学者可以写出思路清晰、多任务运行流畅的程序。
任务2介绍了程序的风格和可移植性,规范了变量和函数等的命名,并简单介绍了C51中提高程序可移植性的方法。
任务3介绍了程序模块化的实现方法,让初学者学会合理的管理程序。
任务4中运用本单元所讲的知识,结合前一单元,完成简易数字钟的设计。
【内容安排】4.1 基于状态机的程序框架4.2 程序的风格和可移植性4.3 程序的模块化4.4 简易数字钟的设计任务4.1 基于状态机的程序框架4.1.1 任务介绍上一单元中已经多次提到多任务运行时,延时函数(DelayMs())对程序的危害性,堵塞CPU,系统任务的实时性得不到有效的保证。
在3.4节中,提到中断可以提高任务的实时性,但是单片机的中断数量是有限的,不可能每一个任务都有中断。
在 3.5节中,通过定时器中断服务函数提供的时标信号,定时扫描LED和数码管,可以消除延时函数,时标信号给我们提供了一种新的思路来消除延时函数(本质上还是借助于中断)。
但是LED闪烁和动态数码管扫描都是属于状态时间分配均匀的(LED闪烁有两个状态,亮和灭分配时间相等;数码管每个位扫描的时间也相等),程序易于实现。
对于像按键检测这样的(时间分配不均匀的)任务,怎样来消除程序中的延时呢?本节任务是:利用本节所讲“状态机”,改写独立按键程序,并增加“长按”、“连击”等功能。
4.1.2 知识准备1、状态机的思想网络上经常报道特级象棋大师车和多人一起下象棋,采用的方式是“车轮战”。
车轮战有两种方式:(1)象棋大师先和甲开始下象棋,直到有了结果,然后才轮到乙和象棋大师对阵,下完了之后,然后是丙......,一直到和最后一个人下完。
单片机程序技术架构概述及解释说明1. 引言1.1 概述单片机程序是指在单片机芯片上运行的、由汇编语言或高级编程语言编写的一系列指令,以实现特定功能的程序。
随着科技的发展,单片机程序在各个领域得到了广泛应用,如家电控制、智能交通、医疗设备等。
这些应用对于单片机程序的可靠性和高效性提出了更高的要求。
1.2 文章结构本文主要围绕单片机程序的技术架构展开讨论,并重点介绍了其概念和相关组件模块划分。
接着,文章将详细解释通信协议与接口设计在单片机程序中的重要性,并介绍了相关内容。
最后,文章将对单片机程序的设计流程、软件编程语言选择与优化技巧、内存管理与资源利用策略等方面进行概述和解释说明。
1.3 目的本文旨在全面介绍单片机程序及其技术架构,并通过对其设计流程、编程语言选择和优化技巧、内存管理与资源利用策略等方面的阐述,帮助读者深入理解并掌握单片机程序开发中需要考虑的关键问题和技术要点。
同时,通过对未来发展趋势的展望,为读者提供对单片机程序领域的进一步研究和实践提供指导。
2. 单片机程序2.1 简介单片机程序是指在单片机芯片上运行的一系列指令集合。
它是通过编程语言将所需功能转化为二进制代码实现的。
单片机程序具有高度可定制性和灵活性,可以适应各种应用领域的需求。
2.2 功能与应用单片机程序可以实现各种功能,如控制、监测、通信等等。
它可以被广泛应用于电子设备、自动化系统、嵌入式系统以及其他需要进行控制和处理任务的场景。
举例来说,单片机程序可以用于家庭智能化系统,通过编程实现对家居设备的控制和管理;也可以应用在工业自动化中,通过编写程序来控制生产线的运行;还可以用于汽车电子领域,实现对车辆部件的监测和故障诊断。
2.3 开发环境和工具开发一款单片机程序通常需要使用相应的开发环境和工具。
常见的开发环境包括Keil uVision、IAR Embedded Workbench、MPLAB X等等。
这些开发环境提供了图形界面和调试器等功能,方便开发人员进行程序编写、调试和测试。
状态机的概念
状态机是软件编程中的一个重要概念。比这个概念更重要的是对它的灵活
应用。在一个思路清晰而且高效的程序中,必然有状态机的身影浮现。
比如说一个按键命令解析程序,就可以被看做状态机:本来在A状态下,
触发一个按键后切换到了B状态;再触发另一个键后切换到C状态,或者返回到
A状态。这就是最简单的按键状态机例子。实际的按键解析程序会比这更复杂些,
但这不影响我们对状态机的认识。
进一步看,击键动作本身也可以看做一个状态机。一个细小的击键动作包
含了:释放、抖动、闭合、抖动和重新释放等状态。
同样,一个串行通信的时序(不管它是遵循何种协议,标准串口也好、I2C
也好;也不管它是有线的、还是红外的、无线的)也都可以看做由一系列有限的
状态构成。
显示扫描程序也是状态机;通信命令解析程序也是状态机;甚至连继电器
的吸合/释放控制、发光管(LED)的亮/灭控制又何尝不是个状态机。
当我们打开思路,把状态机作为一种思想导入到程序中去时,就会找到解
决问题的一条有效的捷径。有时候用状态机的思维去思考程序该干什么,比用控
制流程的思维去思考,可能会更有效。这样一来状态机便有了更实际的功用。
程序其实就是状态机。
也许你还不理解上面这句话。请想想看,计算机的大厦不就是建立在“0”
和“1”两个基本状态的地基之上么?
状态机的要素
状态机可归纳为4个要素,即现态、条件、动作、次态。这样的归纳,主
要是出于对状态机的内在因果关系的考虑。“现态”和“条件”是因,“动作”
和“次态”是果。详解如下:
①现态:是指当前所处的状态。
②条件:又称为“事件”。当一个条件被满足,将会触发一个动作,或者
执行一次状态的迁移。
③动作:条件满足后执行的动作。动作执行完毕后,可以迁移到新的状态,
也可以仍旧保持原状态。动作不是必需的,当条件满足后,也可以不执行任何动
作,直接迁移到新状态。
④次态:条件满足后要迁往的新状态。“次态”是相对于“现态”而言的,
“次态”一旦被激活,就转变成新的“现态”了。
如果我们进一步归纳,把“现态”和“次态”统一起来,而把“动作”忽
略(降格处理),则只剩下两个最关键的要素,即:状态、迁移条件。
状态机的表示方法有许多种,我们可以用文字、图形或表格的形式来表示
一个状态机。
纯粹用文字描述是很低效的,所以就不介绍了。接下来先介绍图形的方式。
状态迁移图(STD)
状态迁移图(STD),是一种描述系统的状态、以及相互转化关系的图形
方式。状态迁移图的画法有许多种,不过一般都大同小异。我们结合一个例子来
说明一下它的画法,如图1所示。
图1 状态迁移图
①状态框:用方框表示状态,包括所谓的“现态”和“次态”。
②条件及迁移箭头:用箭头表示状态迁移的方向,并在该箭头上标注触发
条件。
③节点圆圈:当多个箭头指向一个状态时,可以用节点符号(小圆圈)连
接汇总。
④动作框:用椭圆框表示。
⑤附加条件判断框:用六角菱形框表示。
状态迁移图和我们常见的流程图相比有着本质的区别,具体体现为:在流
程图中,箭头代表了程序PC指针的跳转;而在状态迁移图中,箭头代表的是状
态的改变。
我们会发现,这种状态迁移图比普通程序流程图更简练、直观、易懂。这
正是我们需要达到的目的。
状态迁移表
除了状态迁移图,我们还可以用表格的形式来表示状态之间的关系。这种
表一般称为状态迁移表。
表1就是前面介绍的那张状态迁移图的另一种描述形式。
表1 状态迁移表
①采用表格方式来描述状态机,优点是可容纳更多的文字信息。例如,我
们不但可以在状态迁移表中描述状态的迁移关系,还可以把每个状态的特征描述
也包含在内。
②如果表格内容较多,过于臃肿不利于阅读,我们也可以将状态迁移表进
行拆分。经过拆分后的表格根据其具体内容,表格名称也有所变化。
③比如,我们可以把状态特征和迁移关系分开列表。被单独拆分出来的描
述状态特征的表格,也可以称为“状态真值表”。这其中比较常见的就是把每个
状态的显示 内容单独列表。这种描述每个状态显示内容的表称之为“显示真值
表”。同样,我们把单独表述基于按键的状态迁移表称为“按键功能真值表”。
另外,如果每一个 状态包含的信息量过多,我们也可以把每个状态单独列表。
④由此可见,状态迁移表作为状态迁移图的有益补充,它的表现形式是灵
活的。
⑤状态迁移表优点是信息涵盖面大,缺点是视觉上不够直观,因此它并不
能取代状态迁移图。比较理想的是将图形和表格结合应用。用图形展现宏观,用
表格说明细节。二者互为参照,相得益彰。
用状态机思路实现一个时钟程序
接下来,我将就状态机的应用,结合流程图、状态迁移图和状态迁移,举一个实
际例子。下面这张图是一个时钟程序的状态迁移图,如图2所示。
图2 时钟程序状态迁移图
把这张图稍做归纳,就可以得到它的另一种表现形式——状态迁移表,如
表2所示。
表2 时钟程序状态迁移表
状态机应用的注意事项
基于状态机的程序调度机制,其应用的难点并不在于对状态机概念的理
解,而在于对系统工作状态的合理划分。
初学者往往会把某个“程序动作”当作是一种“状态”来处理。我称之为
“伪态”。那么如何区分“动作”和“状态”。本匠人的心得是看二者的本质:
“动作”是 不稳定的,即使没有条件的触发,“动作”一旦执行完毕就结束了;
而“状态”是相对稳定的,如果没有外部条件的触发,一个状态会一直持续下去。
初学者的另一种比较致命的错误,就是在状态划分时漏掉一些状态。我称
之为“漏态”。
“伪态”和“漏态”这两种错误的存在,将会导致程序结构的涣散。因此
要特别小心避免。
更复杂的状态机
前面介绍的是一种简单的状态结构。它只有一级,并且只有一维,如图3
所示。
图3 线性状态机结构
如果有必要,我们可以建立更复杂的状态机模型。
1 多级状态结构
状态机可以是多级的。在分层的多级状态机系统里面,一个“父状态”下
可以划分多个“子状态”,这些子状态共同拥有上级父状态的某些共性,同时又
各自拥有自己的一些个性。
在某些状态下,还可以进一步划分子状态。比如,我们可以把前面的时钟
例子修改如下:
把所有和时钟功能有关的状态,合并成1个一级状态。在这个状态下,又可以划
分出3个二级子状态,分别为显示时间、设置小时、设置分钟;
同样,我们也可以把所有和闹钟功能有关的状态,合并成1个一级状态。
在这个状态下,再划分出4个二级子状态,分别为显示闹钟、设置“时”、设置
“分”、设置鸣叫时间。
我们需要用另一个状态变量(寄存器)来表示这些子状态。
子状态下面当然还可以有更低一级的孙状态(子子孙孙无穷尽也),从而
将整个状态体系变成了树状多级状态结构,如图4所示。
图4 树状多级状态结构
2 多维状态结构
状态结构也可以是多维的。从不同的角度对系统进行状态的划分,这些状
态的某些特性是交叉的。比如,在按照按键和显示划分状态的同时,又按照系统
的工作进程做出另一种状态划分。这两种状态划分同时存在,相互交叉,从而构
成了二维的状态结构空间。
举一个这方面的例子,如:空调遥控器,如图5所示。
图5 多维状态机结构
同样,我们也可以构建三维、四维甚至更多维的状态结构。每一维的状态
都需要用一个状态变量(寄存器)来表示。
无论多级状态结构和多维状态结构看上去多么迷人,匠人的忠告是:我们
依然要尽可能地简化状态结构,能用单级、单维的结构,就不要给自己找事,去
玩那噩梦般的复杂结构。
简单的才是最有效的。
结束语
对状态机的理解需要一个由浅入深的过程。这个过程应该是与实践应用和
具体案例思考相结合的。当一种良好的思路成为设计的习惯,它就能给设计者带
来回报。愿这篇手记里介绍的基于状态机的编程思路能给新手们带来一些启迪,
帮助大家找到“程序设计”的感觉。