搜索
bottom↓
回复: 64

关于将状态机应用于嵌入式软件设计的问题

[复制链接]

出0入0汤圆

发表于 2007-1-18 01:13:26 | 显示全部楼层 |阅读模式
最近在南方老树的网站里看到了一些关于将状态机应用于嵌入式软件设计的问题的转帖

也想谈些应用问题,自己也发表过I2C/TWI/USI实现状态机控制的实战例程:

I2C(TWI/SMBUS)LPC213X主机通讯例程

TWI一主多从实战程序片段



状态机在EDA中设计很普遍,有些甚至离不开它.

虽然在MCU设计中应用也很广,但有时即使可以也不得不放弃,这主要和MCU的众多因素有关.

不可否认,有时事例用状态机设计很简单,而且思路很清晰.

例如xf.zhu的状态机键盘扫描程序



但是在小容量程序空间的MCU中,可能菜农的"零耗时键盘"更能节省空间.

例如零耗时键盘各种事件及消抖处理模板裸奔程序详解



以菜农的倒塌思想去理解"状态机":

状态机就是我们预先编排的程序序列,我们设计的是如何诱导程序正常地进入此序列.

当程序不遵从序列(状态)时,将会引发错误的出现.

当程序遵从序列(状态)时,程序将根据此时的状态来安排下一步的状态(序列).



现在摘录菜农从未发表过的USI从机实战程序片段举例.



void UsiObj::Start(void)

{

  set_sleep_mode(SLEEP_MODE_IDLE);

  Status = 0;//状态初始化

  USICR = (1 << USISIE) | (1 << USIOIE) | (1 << USIWM1) |(1 << USIWM0) |(1 << USICS1);// |(1 << USICS0);

  USISR = 0xf0; //清除USISIF,USIOIF,USIPF,USIDC标志和设置计数器16次即接收1个字节8位(SCL上升及下降沿都计数)

  DDRB &= ~(1 << SCL); //SCL设置为输入方式,SCL信号由主机提供

  DDRB &= ~(1 << SDA); //SDA设置为输入方式

  Count = 0;//数组指针计数器归零

}

因为在从机收到Start硬件信号后会产生中断,从机运行Usi.Start()函数.

进行状态机的初始化,即Status = 0;程序被逼迫下次中断进行芯片读写地址分析.

下次中断时运行:

void UsiObj::Exec(void)

{

unsigned char tmp;

  Count &= 0x03;//防止数组溢出

/*-------------------------------------------------------------------

优化示例:

  DDRB &= ~((1 << SCL) | (1 << SDA)); //SCL设置为输入方式,SCL信号由主机提供

上句将比下两句代码多编译2个字节

  DDRB &= ~(1 << SCL); //SCL设置为输入方式,SCL信号由主机提供

  DDRB &= ~(1 << SDA); //SDA设置为输入方式

--------------------------------------------------------------------*/

  DDRB &= ~(1 << SCL); //SCL设置为输入方式,SCL信号由主机提供

  DDRB &= ~(1 << SDA); //SDA设置为输入方式

/*-------------------------------------------------------------------

优化示例:

  while (PINB & (1 << SCL));//等待SCL=0主机处理结束

上句将比下句代码多编译16个字节

  while ((unsigned char)tmp = (PINB & (1 << SCL)));//等待SCL=0主机处理结束

--------------------------------------------------------------------*/

  while ((tmp = (PINB & (1 << SCL))) != 0);//等待SCL=0主机处理结束

  PORTB &= ~(1 << SCL);//保持低电平

  DDRB |= (1 << SCL);//占用SCL总线,以便长期处理

  switch(Status) {

    case 0: //状态TW_START,从机地址判别

            Address = USIDR;//取本机滚动地址0b0000000R/W~0b1111111R/W

                Status = ((Address & 0x01) + 1);//Status下次主发为1W,主收为2R

        Count = 0;//数组指针计数器归零

        SendAck();

                break;

        case 1: //状态TW_MT_SLA_ACK,主发从收模式

                Status = 3;//下次进入接收命令状态

                USISR = 0x00; //准备接收8位命令

                break;

        case 2: //状态TW_MR_SLA_ACK或TW_MR_DATA_ACK,主收从发模式

                Status = 4;

                  USIDR = TxBuffer[Count++] ^ Address;//发送并加密8位数据1个字节

                USISR = 0x00; //继续发送8位数据

                DDRB |= (1 << SDA);//从机SDA需要输出数据,故设置为输出方式

                break;

        case 3: //状态主发从收模式(接收数据状态)

//....

因为I2C中断是有序的,即模块的状态是"有序"的,也可认为这是硬件状态机.

那么在软件状态机Status=0时,就必定要对应硬件状态TW_START.否则出错处理进入休眠;

在从机收到从机地址后,若地址的最低为D0=0(W)时,在发送ACK后下次进入主发从收模式Status=0+1=1

在从机收到从机地址后,若地址的最低为D0=1(R)时,在发送ACK后下次进入主收从发模式Status=1+1=2



依此类推,从机的接收程序被诱导入了我们实现安排好的圈套~~~

从状态图来看,它很像二叉树,故"搜索"即诱导程序序列很快,而且条理很清.



当然菜农恶搞的关于USI接口密文传送增加I2C模块拦截难度的问题就只能点到为止了~~~

否则菜农的菜碗就保不住了~~~

出0入0汤圆

发表于 2007-12-23 16:52:18 | 显示全部楼层
这个帖子竟然没人顶。

出0入0汤圆

发表于 2007-12-23 17:33:54 | 显示全部楼层
倒塌了!
这么好的帖子竞没人顶?
帮顶!!

出0入0汤圆

发表于 2007-12-23 22:15:53 | 显示全部楼层
.

出0入0汤圆

发表于 2007-12-23 22:40:37 | 显示全部楼层
学习学习 谢谢

出0入0汤圆

发表于 2007-12-24 01:38:35 | 显示全部楼层
哈哈,我就是这么裸奔的。

出0入0汤圆

发表于 2008-1-31 12:27:02 | 显示全部楼层
谢谢,才发现,顶啊

出0入0汤圆

发表于 2008-1-31 13:12:16 | 显示全部楼层
顶,纯路过

出0入0汤圆

发表于 2008-2-1 09:33:44 | 显示全部楼层
学习了

出0入0汤圆

发表于 2008-2-1 12:02:45 | 显示全部楼层
这段时间21ic上状态机是个热门

出0入0汤圆

发表于 2008-2-1 12:43:59 | 显示全部楼层
最近在搞IAR的visualSTATE,感觉开发挺方便的,就是不知道这个东西编出的程序效率怎么样。

出0入0汤圆

发表于 2008-2-1 17:08:06 | 显示全部楼层
这个做法不错,支持!!

出0入0汤圆

发表于 2008-2-1 17:14:49 | 显示全部楼层
谢谢
正在学习

出0入0汤圆

发表于 2008-2-1 20:18:58 | 显示全部楼层
在无操作系统的情况下,是偶喜欢的编程方式,呵呵!俺住西安碑林区,呵呵!菜农在西安哪块?

出0入0汤圆

发表于 2009-4-18 11:18:40 | 显示全部楼层
谢谢
正在学习

出0入0汤圆

发表于 2009-4-19 22:13:39 | 显示全部楼层
不顶不行

出0入0汤圆

发表于 2009-8-14 18:07:41 | 显示全部楼层
要顶呀

出0入0汤圆

发表于 2009-8-14 19:50:51 | 显示全部楼层

出0入0汤圆

发表于 2009-8-14 20:19:45 | 显示全部楼层
嗯 个人风格不同

出0入0汤圆

发表于 2009-8-15 21:14:35 | 显示全部楼层
顶一个!!

出0入4汤圆

发表于 2009-8-15 21:45:04 | 显示全部楼层
顶!好东西!
按键处理,都是用状态机做的!

出0入0汤圆

发表于 2009-8-16 02:03:20 | 显示全部楼层
MARK 状态机

出0入0汤圆

发表于 2009-8-28 22:37:41 | 显示全部楼层
学习IAR的visualSTATE

出0入0汤圆

发表于 2009-8-29 01:23:41 | 显示全部楼层
学习!

出0入0汤圆

发表于 2009-8-29 01:47:27 | 显示全部楼层
人工智能之父-----图灵想出来的 ,当然经典

出0入0汤圆

发表于 2009-8-29 08:54:08 | 显示全部楼层
mark

出0入46汤圆

发表于 2009-8-29 11:32:30 | 显示全部楼层
学习学习@!

出0入0汤圆

发表于 2009-9-3 13:14:56 | 显示全部楼层
这里让我了结 状态机。

出0入0汤圆

发表于 2009-9-3 21:16:26 | 显示全部楼层
支持,帮顶

出0入0汤圆

发表于 2009-9-9 19:46:42 | 显示全部楼层
状态机是好东西.

强贴留名,呵呵

出0入0汤圆

发表于 2009-11-19 22:43:31 | 显示全部楼层
ding

出0入0汤圆

发表于 2009-11-19 22:51:18 | 显示全部楼层
学习。

出0入0汤圆

发表于 2010-1-14 23:59:25 | 显示全部楼层
mark

出0入4汤圆

发表于 2010-1-15 21:52:11 | 显示全部楼层
学习,

出0入0汤圆

发表于 2010-1-15 22:27:44 | 显示全部楼层
I2C从机只能采用状态机

出0入0汤圆

发表于 2010-1-22 09:14:03 | 显示全部楼层
看看!

出0入0汤圆

发表于 2010-1-22 11:44:51 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-1-22 17:28:34 | 显示全部楼层
留下脚印。。

出0入0汤圆

发表于 2010-1-23 17:03:28 | 显示全部楼层
mark!

出0入0汤圆

发表于 2010-2-7 23:33:13 | 显示全部楼层
MARK

出0入0汤圆

发表于 2010-2-8 08:31:21 | 显示全部楼层
ding!

出0入0汤圆

发表于 2010-3-2 18:47:50 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-3-12 06:11:32 | 显示全部楼层
mark

出65入0汤圆

发表于 2011-3-12 08:01:53 | 显示全部楼层
mark状态机

出0入0汤圆

发表于 2011-3-12 08:25:26 | 显示全部楼层
学习

出0入0汤圆

发表于 2011-3-14 14:38:59 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-3-14 20:38:03 | 显示全部楼层
ding!ding!

出115入0汤圆

发表于 2011-8-25 15:04:39 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-8-26 11:12:55 | 显示全部楼层
俺也用

出0入0汤圆

发表于 2011-10-31 14:11:11 | 显示全部楼层
学习一下!

出0入0汤圆

发表于 2011-10-31 23:13:06 | 显示全部楼层
mark 零耗时键盘 状态机

出0入0汤圆

发表于 2011-11-1 16:21:47 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-11-2 12:43:18 | 显示全部楼层
雁塔菜农 M0

出0入0汤圆

发表于 2011-12-16 15:06:39 | 显示全部楼层
顶顶~~~

出0入0汤圆

发表于 2012-2-27 16:36:58 | 显示全部楼层
mark

出0入0汤圆

发表于 2012-2-28 11:46:13 | 显示全部楼层
mark

出0入0汤圆

发表于 2012-2-28 12:26:57 | 显示全部楼层
mark

出0入0汤圆

发表于 2012-2-28 12:50:28 | 显示全部楼层
这个一定要mark

出0入0汤圆

发表于 2012-2-28 13:11:23 | 显示全部楼层
回复【10楼】igoal
最近在搞iar的visualstate,感觉开发挺方便的,就是不知道这个东西编出的程序效率怎么样。
-----------------------------------------------------------------------

我在学习过程中遇到很多问题,但不知道怎样解决。

出0入0汤圆

发表于 2014-9-2 11:26:45 | 显示全部楼层
下面是在网上搜到的一个针对状态机的简要总结:
“有限状态机系统优点:简单易用,状态间关系直观看到,便于编程;可以快速执行;只是通过改变输出功能来改变机器的响应。缺点:任何时刻系统只能有一个状态,无法表示并发性,不能描述异步并发系统;在系统部件多时,状态数随之增加,导致复杂性显著增长;对于大的应用系统,难于调试。 ”

感觉说的不够清楚,楼主能不能总结一下嵌入式中应用状态机的优缺点啊?

出0入0汤圆

发表于 2014-9-3 15:04:50 | 显示全部楼层
学习学习

出0入0汤圆

发表于 2014-9-9 10:14:05 | 显示全部楼层
深入浅出啊,讲的太好了--MARK!!!硬件状态机

出0入0汤圆

发表于 2014-9-9 10:29:23 | 显示全部楼层
状态机为什么这么火。。

出0入0汤圆

发表于 2014-9-9 13:42:50 | 显示全部楼层
学习一下

出0入0汤圆

发表于 2016-7-13 18:55:41 | 显示全部楼层
学习学习
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-9 05:21

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表