打印

讨教一个单片机的程序处理方法!

[复制链接]
2475|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
areshan|  楼主 | 2011-6-10 17:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
大家好,我想和大家讨论一个程序的处理方法,不知道大家有什么好的建议没有。我用的是AVR的单片机,是裸奔,没有等待消息之类的处理机制。
我现在遇到的问题是要控制一个设备,这个设备之前是断电的。我在控制这个设备前要给设备上电,等待设备的进入工作状态,然后再给设备输入指令。但是,这些都是在一个函数中的,函数又不能延时太久等待设备上电进入工作状态,我这边是这样处理的:
1.把这个函数放入主循环中,用一个全局变量来表示函数进入不同的状态,如下:
unsigned char state=POWEROFF;

switch(state)
{
case POWERON :
...........
state=READY;
break;
case WORK:
...........
state=POWERON;
break;
case READY:
...............
state=READY;
............
}
这样通过几次循环,和几次状态的变化,就可以完成需要的操作了!

不知道大家在遇到这种情况是怎么处理的呢?有什么好点的方法吗?
有没有制作一个小的系统,这样就可以自由的切换程序了!!!!!!

相关帖子

沙发
红金龙吸味| | 2011-6-10 18:42 | 只看该作者
这个思路已经可以了。

使用特权

评论回复
板凳
xixihaha0| | 2011-6-10 19:38 | 只看该作者
这是状态机思想,所有Delay的这种死等的操作理论上都可以改成这种的,这样可以了,

使用特权

评论回复
地板
areshan|  楼主 | 2011-6-11 08:57 | 只看该作者
哦,状态思想? 有点意思!

使用特权

评论回复
5
ayb_ice| | 2011-6-11 09:16 | 只看该作者
典型的状态机

使用特权

评论回复
6
areshan|  楼主 | 2011-6-11 11:14 | 只看该作者
谢谢aby_ice的留言,我还真没有状态机的概念,这种方法是我的同事教我的,说不要用延时把CPU给浪费了!谢谢aby_ice!指导过我不少的问题!

使用特权

评论回复
7
老鱼探戈| | 2011-6-11 11:25 | 只看该作者
状态机的最大好处是:当执行某一个状态下的程序的时候,其他状态的程序被挂起,使CPU处于相对“悠闲”的工作状态。

使用特权

评论回复
8
leang521| | 2011-6-11 11:27 | 只看该作者
去看下软件状态机设计思想,裸奔的系统都用这种方式处理

使用特权

评论回复
9
areshan|  楼主 | 2011-6-11 11:29 | 只看该作者
关于状态机的一个极度确切的描述是它是一个有向图形,由一组节点和一组相应的转移函数组成。状态机通过响应一系列事件而“运行”。每个事件都在属于“当前” 节点的转移函数的控制范围内,其中函数的范围是节点的一个子集。函数返回“下一个”(也许是同一个)节点。这些节点中至少有一个必须是终态。当到达终态, 状态机停止。
谢谢大家的回复,百度了一下,果然是状态机的思想!

使用特权

评论回复
10
盛夏·了| | 2011-6-12 13:23 | 只看该作者
状态机 学到了
这种求助方法赞  论坛应该多点讨论贴 少点纯求助贴

使用特权

评论回复
11
MasterLonely| | 2011-6-12 15:22 | 只看该作者
学习了。
请教:
1.
状态机的最大好处是:当执行某一个状态下的程序的时候,其他状态的程序被挂起,使CPU处于相对“悠闲”的工作状态。
老鱼探戈 发表于 2011-6-11 11:25

这个"悠闲"怎么理解?cpu不是一直都在运行(判断,改状态,调用。)吗?

2. 状态机使用时注意什么?要求被调用的函数时间很短吗?

谢谢

使用特权

评论回复
12
leang521| | 2011-6-13 14:36 | 只看该作者
状态机的目的在于控制每段代码的施行时间,方便函数中延时程序的脱出
使用状态机不需要特别注意什么,只要在需要延时的地方记状态脱出即可,如果真要注意的,就是要注意记录状态的变量安全。

使用特权

评论回复
13
PaperKite| | 2011-6-13 20:52 | 只看该作者
挺好的  谢谢

使用特权

评论回复
14
areshan|  楼主 | 2011-6-17 16:07 | 只看该作者
我把先前的程序该了,改成if的了,供各位参考!
char em3000_polling(void)
{
        if((scan_state==SCAN_POWEROFF)&&(scan_trig==1))                        //如果系统没有上电
        {
                em3000_poweron();                                        //扫描头上电
                scan_100ms=5;
                scan_state=SCAN_WAIT;
                return 1;
                }
        if(scan_state==SCAN_WAIT)
        {
                if(scan_100ms==0)
                scan_state=SCAN_TRIGON;       
                return 1;
                }
        if(scan_state==SCAN_TRIGON)
        {
                em3000_trigon();                                //开始扫描
                scan_100ms=40;
                scan_state=SCAN_IDLE;
                return 1;
                }
        if(scan_state==SCAN_IDLE)
        {
                if(scan_100ms==0)                                //如果4S没有读到条码       
                        {
                                em3000_trigoff();
                                scan_trig=0;                        //关闭触发开关
                                scan_100ms=200;
                                scan_state=SCAN_TRIGOFF;
                                scan_buf_flag=REC_ERR;        //接收错误               
                                return 1;
                                }
                if(scan_buf_flag==REC_FULL)                //如果读到条码
                        {
                                em3000_trigoff();
                                scan_trig=0;
                                scan_100ms=200;
                                scan_state=SCAN_TRIGOFF;
                                return 0;
                                }
                return 1;       
                }
        if(scan_state==SCAN_TRIGOFF)
        {
                if(scan_trig==1)                                //检测是否再次触发
                {
                        scan_state=SCAN_TRIGON;
                        scan_100ms=200;
                        return 1;
                        }
                if(scan_100ms==0)                                //如果3分钟没有再次触发就关闭em3000
                {
                        em3000_poweroff();
                        scan_state=SCAN_POWEROFF;
                        return 2;
                        }
                return 1;
                }
        scan_to_cpu();                                                //把收到scan的数据发送给CPU
        return 1;
        }
每次程序都是由上一个状态到下一个状态!

使用特权

评论回复
15
areshan|  楼主 | 2011-6-17 16:08 | 只看该作者
改成这种用if的可能会让大家更容易理解!!!!!!谢谢大家的回复!

使用特权

评论回复
16
areshan|  楼主 | 2011-6-17 16:10 | 只看该作者
说明下上面的scan_100ms是在一个定时器中不断减1的!!!!!!大家不要误解!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

127

主题

728

帖子

0

粉丝