基于状态机的单片机编程

前言

在设计锂离子电池充电器时,对于以前的根据系统状态进行判断,置标志位的方法,会显得程序臃肿,且架构混乱,变量交错复杂,移植困难。

所以结合实际项目,给出了一种基于状态机的编程方法。

有纰漏请指出,转载请说明。

学习交流请发邮件 1280253714@qq.com


方法论

对于电池包,一般会有几个端子与充电器进行通信识别,有BS(Battery Select)、NTC(负温度系数的电阻),正负极、通信口。

有些电池包内置NTC,通过通信将信息发给充电器,有些是直接接NTC给到充电器。

如果按照以往的编程方法,需要经常if else,而且各种标志位flag散乱于程序各处,代码臃肿,调试困难,bug不断,移植困难。

所以我提出了这种基于状态机的编程方法,对各个变量(电压、电流、温度、BS等),持续检测,同时各个状态可以随时转移。

最终任务级函数BatStateCheck判别参数状态,进行参数选择。

同时为了防止系统抖动,需要多次判断才能进行状态转移,demo如下。


变量状态转移流程框图


系统状态转移流程框图


系统状态转移函数示例

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
自动门课程设计(基于单片机c语言编程) 1 1绪论 1.1自动门的简介 自动门控制系统,在现当代社会是一个应用非常广泛的设备,自动门已经广泛应用于酒店、银行、超市、停车场或公共建筑等入口,其主要核心部分——自动门控制系统正是我们这篇论文的主要研究讨论的课题。 自动门是指:可以将人接近门的动作(或将某种入门授权)识别为开门信号的控制单元,通过驱动系统将门开启,在人离开后再将门自动关闭,并对开启和关闭的过程实现控制的系统。自动门的性能优劣主要取决于它的控制装置,早期的自动门控制系统采用继电器逻辑控制,造成安装繁琐、体积大、不稳定、不易维修等缺点已逐渐被淘汰。 1.2本设计研究的内容 1.2.1自动平移门机组的部件组成 在本设计中主要研究自动平移门,设计的自动平移门具有手动和自动开门功能以及分时段控制功能,同时配备防夹人光栅、后备电源等辅助装置来满足商场等人流众多场所的高效率、高安全性的要求。 主要部件 主控制器:它是自动门的指挥中心,通过内部编有指令程序的大规模集成块,发出相应指令,指挥马达或电锁类系统工作;同时人们通过主控器调节门扇开启速度、开启幅度等参数。 感应探测器:负责采集外部信号,如同人们的眼睛,当有移动的物体进入它的工作范围时,它就给主控制器一个脉冲信号。 动力马达:提供开门与关门的主动力,控制门扇加速与减速运行。 自动门课程设计(基于单片机c语言编程)全文共29页,当前为第1页。门扇行进轨道:就象火车的铁轨,约束门扇的吊具走轮系统,使其按特定方向行进。 自动门课程设计(基于单片机c语言编程)全文共29页,当前为第1页。 门扇吊具走轮系统:用于吊挂活动门扇,同时在动力牵引下带动门扇运行。 同步皮带:用于传输马达所产动力,牵引门扇吊具走轮系统。 辅助配置 行程开关:在自动门行进过程中,通过行程开关判断自动门所在位置,驱动信号输出达到控制自动门行进速度。 安全辅助装置:在高档酒店等地方需要杜绝自动门的夹人事件,可以选择安装防夹人光栅。 配备后备电源:为保证停电时自动门也能工作正常,可以配备后备电源。 1.2.2自动门控制系统要求 物体靠近门时 传感器获得信号给控制器,控制器根据门当前所在位置决定门的动作,有三种情况: 门处于关闭状态,控制器应驱动执行电机以最佳速度曲线打开门。 门处于某一位置,控制器应根据门当前所在位置,以适当的速度驱动执行电机开门。 门处于开启状态,控制器应使门保持开启状态。 无物体靠近门时。 如果门处于开启状态,延时适当的时间以最佳速度曲线关闭门。 如果门处于关闭状态,维持此状态。 2自动门的总体结构设计方案 2.1自动门的门体构造和参数 自动门课程设计(基于单片机c语言编程)全文共29页,当前为第2页。本设计面向商场和超市等人流量巨大,出入频繁的场所,需要有安全性和可靠性。公共场所的自动平移门因为使用非常频繁,而任何自动门的使用频率和使用寿命都有限,为使门体更加坚固耐用,本设计门体玻璃材质使用钢化玻璃。根据例如机场、大型超市、和医院外门等公共场所人员流量巨大的需求,必须对自动门进行综合的考虑,设定适合的具体参数,例如增加门的数量、加大门扇宽度、增加关门延时时间等。具体参数如表2-1所示: 自动门课程设计(基于单片机c语言编程)全文共29页,当前为第2页。 表2-1 自动门的具体参数 门体设计项目 参数设定值 单扇门开启宽度 1500mm 单扇门的最大承重 186kg 单扇门的厚度 10mm 门体高度 2500mm 最快开关门速度 8(cm/s) 常速开关门速度 4(cm/s) 减速开关门速度 2(cm/s) 开启保持时间 2s(可调) 2.2自动门的机械传动结构 自动门的机械传动机构设计主要包括安装板,行进轨道,三相交流电机,传送皮带,皮带滑轮,轨道滑轮,吊架等。 传动机构如图2-2所示。其中马达皮带直径为25mm,皮带外径为100mm,内径为50mm。 自动门课程设计(基于单片机c语言编程)全文共29页,当前为第3页。 自动门课程设计(基于单片机c语言编程)全文共29页,当前为第3页。 图2-2 机械传动结构 2.3自动门的导轨及滑轮结构 导轨、滑轮及传动皮带是推拉自动门的基本传动部件,与活动扇的运行直接有关,是易损件, 其结构设计、材质、加工、安装及调试精度、维修保养等决定了质量和使用寿命。 滚动直线导轨设计及优点 本设计采用了滚动直线导轨。这种结构不仅有效地缓解了动态"侧摆"的弊病,同时也在一定程度上解决了活动扇"掉扇"等安全问题。而且大大地减少了滑轮的动态磨损,在根据活动扇受力情况对导轨和滑轮截面曲线进行加强设计后,使门机的单扇承重量达到75公斤。 滚动直线导轨副是由导轨、滑块、钢球、返向器、保持架、密封端盖及挡板等组成(见下图)。当导轨与滑块作相对运动时,钢球就沿着导轨上的经过淬硬和精密磨
以下是一个基于51单片机的NEC协议状态机编程示例: ```c #include <reg51.h> #define IR_IN P3_2 // NEC协议定义的高低电平时间 #define T1 560 #define T2 1690 #define T3 45000 #define T4 22500 // 状态定义 #define STATE_IDLE 0 #define STATE_START 1 #define STATE_BIT 2 // 全局变量 unsigned char ir_state = STATE_IDLE; // 初始化为IDLE状态 unsigned char ir_code = 0; unsigned char ir_count = 0; void delay_us(unsigned int us) { while(us--) { _nop_(); } } // NEC协议解码函数 void ir_decode(unsigned char code) { // 解码操作 } void ir_timer_handler() { static unsigned int ir_timer_count = 0; static unsigned char ir_last_state = 0; // 读取当前状态 unsigned char ir_cur_state = IR_IN; // 状态转移 switch (ir_state) { case STATE_IDLE: if (ir_cur_state == 0 && ir_last_state == 1) { ir_timer_count = 0; ir_state = STATE_START; } break; case STATE_START: if (ir_cur_state == 1 && ir_last_state == 0) { if (ir_timer_count >= T1 && ir_timer_count <= T2) { ir_code = 0; ir_count = 0; ir_state = STATE_BIT; } else { ir_state = STATE_IDLE; } } break; case STATE_BIT: if (ir_cur_state == 1 && ir_last_state == 0) { if (ir_timer_count >= T1 && ir_timer_count <= T2) { ir_code >>= 1; if (ir_timer_count > T2 - T1) { ir_code |= 0x80; } ir_count++; if (ir_count >= 8) { ir_decode(ir_code); ir_state = STATE_IDLE; } } else { ir_state = STATE_IDLE; } } break; default: ir_state = STATE_IDLE; break; } // 更新last_state并清零计数器 ir_last_state = ir_cur_state; ir_timer_count = 0; } void main() { TMOD = 0x01; // 定时器0工作在模式1 TH0 = 0xFC; // 定时器初值 TL0 = 0x67; ET0 = 1; // 打开定时器0中断 EA = 1; // 打开总中断 while(1) { // 等待中断处理 } } // 定时器0中断 void timer0_isr() interrupt 1 { TH0 = 0xFC; // 定时器初值 TL0 = 0x67; ir_timer_handler(); // 处理红外信号 } ``` 以上代码通过定时器0中断处理来实现NEC协议的红外信号解码。整个解码过程是通过状态机实现的,分为三个状态:IDLE、START和BIT。在IDLE状态下,等待红外信号开始;在START状态下,检测红外信号开始;在BIT状态下,解码红外信号。在定时器中断处理函数中,会根据当前状态和红外信号的高低电平时间来进行状态转移和解码操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值