设计与开发

单片机状态字 如何写一个状态指示灯?

小编 2024-10-06 设计与开发 23 0

如何写一个状态指示灯?

工作时,我们常常会有这样的需求:

用一个 LED 灯指示机器的工作状态:正常或故障。

这样一个需求,对于我们入门就写点灯程序的点灯小能手来说,根本就是小意思。

因为这只需要控制IO输出高电平或者低电平就可以达到要求。尽管如此简单,如果用的不好,那也是存在风险的:《引脚输出的隐藏BUG | 深入思考》。

本篇笔记记录的当然不是简单的指示正常和故障这两种状态,而是多种状态。

比如,快闪、慢闪、1秒闪1次,1秒闪3次等。

不过,因精力有限,鱼鹰介绍一个简单的实现1.5秒闪烁1~5次的方法,并且通过对该方法的详细介绍,你也可以实现更复杂的指示功能(当然也可用于蜂鸣器等)。

该方法有几点优势:

1、代码实现简单;

2、可用于多线程;

3、移植方便;

4、裸机、操作系统均可使用,可不需要定时器。

当然也有缺点,就是只能指示最新的当前状态(也就是说,如果有多个线程同时调用,将指示最后一个调用时的状态),不过对于状态指示来说,这样足够了。

为了实现1.5秒内闪烁5次,并且让代码尽可能的简单,我们可以将 1.5 s划分成 10 个等份,每个等份为 150 ms。

假定,高电平为

,低电平为亮。

那么,如果我们要实现1.5 s 闪烁一次的效果,只需要在0 时刻设置为低电平,1时刻设置为高电平即可,其他时刻不需要操作电平,此时电平效果如下:

这样,通过在指定时刻设置IO电平,即可达到闪烁的效果。

现在的问题是,如何获得稳定的周期时间,这已经是老生常谈的问题,如果不明白,可以参考以下笔记:《延时功能进化论(合集)》。

这里我们需要实现两个周期,一个是 1.5 s,一个是 150 ms,所以需要两个变量保存时间戳,同时为了实现单次延时,再增加一个变量,即关于时间的变量共有三个。

下面贴代码,看看代码实现:

代码注释比较详尽,如果看不懂,说明还没有理解鱼鹰以前写的笔记,建议翻翻以前的鱼鹰笔记。

简单说明几点:

1、为了移植方便,使用了一个函数指针设置LED电平,因此可以很方便的修改。

2、可以方便配置多个LED,如果一个LED不够,那就俩。

3、为了减少空间的使用,原本 4 字节的时间戳通过强制转化,使用 2 字节即可实现。

4、单次超时时间实现。

5、时间戳单位为 1 毫秒,同时 led_set_handle 函数为了保证时间精度,调用周期为 10 ms,该函数需要周期性调用 ,并且只可以在一个地方调用 (一个LED情况下)。

6、led_show 函数用于更新闪烁次数,可在闪烁次数变化的时候调用;同时可多线程使用,当然因为没有缓存,始终保存最后一次调用时的显示次数。

7、led 作为共享资源,使用变量 curr_number 控制资源访问,保证指示不会出现混乱。

8、指示更新周期1.5秒,即上层即使更新了 next_number ,最迟 需要 1.5 后才会更新,最早 更新时间为立刻。

9、使用 C99 的特性,简化初始化过程。

单片机状态机编程详解(状态转换图)

不知道大家有没有这样的感觉,就是玩MCU还可以,所有的功能模块都可以驱动,但是如果写一套完整的代码。却无逻辑与框架可言,上来就是开始写!东抄抄西抄抄。

说明编程还处于比较低的水平,那么如何才能提高自己的编程水平呢?学会一种好的编程框架或者一种编程思想,可能会受用终生!比如模块化编程,框架式编程,状态机编程等等,都是一种好的框架。

今天说的就是状态机编程,由于篇幅较长,大家慢慢欣赏。那么状态机是一个这样的东东?状态机(state machine)有5个要素,分别是状态(state)、迁移(transition)、事件(event)、动作(action)、条件(guard)。

什么是状态机?

状态机是一个这样的东东:状态机(state machine)有 5 个要素,分别是状态(state)、迁移(transition)、事件(event)、动作(action)、条件(guard)。

状态 :一个系统在某一时刻所存在的稳定的工作情况,系统在整个工作周期中可能有多个状态。例如一部电动机共有正转、反转、停转这 3 种状态。

一个状态机需要在状态集合中选取一个状态作为初始状态。

迁移 :系统从一个状态转移到另一个状态的过程称作迁移,迁移不是自动发生的 ,需要外界对系统施加影响。停转的电动机自己不会转起来,让它转起来必须上电。

事件 :某一时刻发生的对系统有意义的事情,状态机之所以发生状态迁移,就是因为出现了事件。对电动机来讲,加正电压、加负电压、断电就是事件

动作 :在状态机的迁移过程中,状态机会做出一些其它的行为,这些行为就是动作 ,动作是状态机对事件的响应。给停转的电动机加正电压,电动机由停转状态迁移到正转状态,同时会启动电机,这个启动过程可以看做是动作,也就是对上电事件的响应。

条件 :状态机对事件并不是有求必应的,有了事件,状态机还要满足一定的条件才能发生状态迁移 。还是以停转状态的电动机为例,虽然合闸上电了,但是如果供电线路有问题的话,电动机还是不能转起来。

只谈概念太空洞了,上一个小例子:一单片机、一按键、俩 LED 灯(记为L1和L2)、一人, 足矣!

规则描述:

1、L1L2状态转换顺序OFF/OFF--->ON/OFF--->ON/ON--->OFF/ON--->OFF/OFF

2、通过按键控制L1L2的状态,每次状态转换需连续按键5次

3、L1L2的初始状态OFF/OFF

实际上在状态机编程中,正确的顺序应该是先有状态转换图,后有程序,程序应该是根据设计好的状态图写出来的 。不过考虑到有些童鞋会觉得代码要比转换图来得亲切,我就先把程序放在前头了。

这张状态转换图是用UML(统一建模语言)的语法元素画出来的,语法不是很标准,但拿来解释问题足够了。

图2按键控制流水灯状态转换图

程序清单代码需移步 ---戳进-->单片机状态机编程详解

相关问答

51 单片机 之程序 状态字 寄存器主要功能?

51单片机的PSW(程序状态字)寄存器包括了C,AC,RS1,RS0,OV,P等几个状态位,这些状态位反映的是51单片机在执行完某个指令后的状态,比如有没有进位,有没有溢出,A...

单片机 中如何使用 状态 寄存器STATUS?

STATUS状态寄存器进位(C)、半进位(DC)和零(Z)标志位的值。在减法中,C和DC位分别用作借位(borrow)和半借位(digitborrow)STATUS状态寄存器进位(C)、半...

单片机 、简述程序 状态字 寄存器PSW各位的符合及意义?

pc:程序计数器,记录下一条指令地址;ir:指令寄存器当前执行中的指令;gr:通用寄存器,比如系统堆栈指针寄存器(sppsw:程序状态字,记录指令结果的状态...ir:指...

单片机 写命令与写数据的区别?

1计算机、单片机与I/O接口芯片的信息传递分为四种情况:(1)向I/O接口芯片送控制字(2)读I/O接口芯片的状态(3)向I/O接口芯片写数据(4)读I/O接口芯...1计...

如何判断 单片机 是否处在运行工作 状态 ?

你是要让人能判断,还是程序能判断.人的话,控制一个LED闪烁就好了程序的话,a=2;b=3;c=a+b;if(c==5){单片机在运行}不过这没有意义.你是要让人能判断,还是...

单片机 中指令周期、机器周期、 状态 周期、振荡时钟周期(时...

[最佳回答]时钟周期:时钟周期也称为振荡周期,定义为时钟脉冲的倒数(可以这样来理解,时钟周期就是单片机外接晶振的倒数,例如12M的晶振,它的时间周期就是1/12u...

单片机 使用频率为6MHz的晶振,那么 状态 周期,机器周期和指令...

[最佳回答]正确!100分

单片机 p0口怎么定义变量?

在单片机中,可以使用C语言通过定义变量来使用P0口。首先,需要包含相应的头文件来使用单片机的GPIO功能,并且需要声明变量的数据类型(如int,char等)。然后...

单片机 中定义flag有啥作用flag=1和flag=0都是什么意思?

...首先按键控制LED这样的代码例程比比皆是,无序赘述,在这边外加一个松手检测的代码应该也不难。定义一个标志位flag,如果flag=0为按下检测,flag=1为松手检测...

请问 单片机 休眠后,为降低静态电流要将IO口设置为输入还是输...

之所以要让单片机进入休眠状态,目的是要把整个电路都带入低功耗状态。这就具体到每根口线与周边电路的连接关系,不能凭空给出I/O口状态的配置。另外,单片机是...

猜你喜欢