打印

这个状态机咋写?多谢!

[复制链接]
2414|16
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
xlsbz|  楼主 | 2010-6-14 21:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 xlsbz 于 2010-6-14 21:58 编辑

发送7种内容不同、字节长度却相同的帧

其中第1种帧每1s发送一次;
其中第2种帧每2s发送一次;
其中第3种帧每7s发送一次;
其中第4种帧每13s发送一次;
其中第5种帧每14s发送一次;
其中第6种帧每17s发送一次;
其中第7种帧每29s发送一次;

用一个定时器

请问程序咋弄能比较简洁?

多谢!

祝各位端午节快乐:)

相关帖子

沙发
NE5532| | 2010-6-14 22:44 | 只看该作者
定时器设为1S的溢出周期,里面对29进行循环计数。发送程序建立一个任务队列,定时器里依次比较7种匹配条件,往队列里填充任务,只要任务队列非空,发送程序就按照队列里的顺序发数据就可以了。注意,前提条件是有最小公倍数的帧的总发送时间不能长于1秒,否则无解。

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
xlsbz + 1
板凳
流行音乐| | 2010-6-15 10:16 | 只看该作者
可以考虑以用户输入的不特定的时间定时,则所有种类的帧其实都是同一种定时方法。这样的方法很通用,不受具体的定时时间限制。

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
xlsbz + 1
地板
冷漠| | 2010-6-15 10:33 | 只看该作者
本帖最后由 冷漠 于 2010-6-15 10:38 编辑

用RTX51_TINY 完成真是太简单了:
建立7个任务,每个任务的写法都是相似的,copy 6次,10分钟就完成了。剩下的由操作系统管理调度去吧。

void  Send_1(void)  _task_ 1          //任务1
{
while(1)
{  
os_wait2(K_IVL, 4);                 //250ms节拍。

send( );    // 每1秒发送帧
}

void  Send_2(void)  _task_ 2          //任务2
{
while(1)
{
os_wait2(K_IVL, 8);                    //250ms节拍。

send( );    // 每2秒发送帧
}
}
void  Send_3(void)  _task_ 3          //任务3
{
while(1)
{  
os_wait2(K_IVL, 28);                         //250ms节拍。

send( );    // 每7秒发送帧
}
}

void  Send_4(void)  _task_ 4          //任务4
{
while(1)
{  
os_wait2(K_IVL, 13*4 );                  //250ms节拍。

send( );    // 每13秒发送帧
}
}
……
……

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
xlsbz + 1
5
xlsbz|  楼主 | 2010-6-15 21:12 | 只看该作者
用RTX51_TINY 完成真是太简单了:
建立7个任务,每个任务的写法都是相似的,copy 6次,10分钟就完成了。剩下的由操作系统管理调度去吧。

void  Send_1(void)  _task_ 1          //任务1
{
while(1)
{  
os_wait2(K ...
冷漠 发表于 2010-6-15 10:33


可是 OS不不懂啊!
我是裸奔  !

使用特权

评论回复
6
xlsbz|  楼主 | 2010-6-15 21:25 | 只看该作者
本帖最后由 xlsbz 于 2010-6-15 21:34 编辑
定时器设为1S的溢出周期,里面对29进行循环计数。发送程序建立一个任务队列,定时器里依次比较7种匹配条件,往队列里填充任务,只要任务队列非空,发送程序就按照队列里的顺序发数据就可以了。注意,前提条件是有最 ...
NE5532 发表于 2010-6-14 22:44


是不是这样?(比如说下面这个例子可以实现任务2.3.4.5每6秒执行一次,任务1每3秒执行一次)

static i;
i ++;

switch (i){
case 1  任务1 break;

case 2  任务2  b reak

case 3  任务3   break

case 4  任务1   break

case5  任务4  break

case6 任务5  i = 0   break

default   i = 0
}


}

使用特权

评论回复
7
aresc| | 2010-6-15 22:31 | 只看该作者
首先设置定时器为1s,然后有两种方法:
1.使用最小公倍数  2 * 7 * 13 * 17 * 29 = 89726,然后在定时器中断里设置一个计数器,计数器在中断里每次加1,加到89726时复位为0,程序类似如下:

#define MAX_TIMER_CNT  89726
static int 1s_timer_cnt = 0;
void ISR (void)
{
        1s_timer_cnt++;
         任务1;               // 定时器中断为1S,所以每次都要执行任务1.
         if ((1s_timer_cnt % 2) == 0)
                任务2;
         if ((1s_timer_cnt % 7) == 0)
                任务3;
         if ((1s_timer_cnt % 13) == 0)
                任务4;
         if ((1s_timer_cnt % 14) == 0)
                任务5;
         if ((1s_timer_cnt % 17) == 0)
                任务6;
         if ((1s_timer_cnt % 29) == 0)
                任务7;
         if (1s_timer_cnt == MAX_TIMER_CNT)
                1s_timer_cnt = 0;
}

也可以使用部分的最小公倍数比如2*7*13,用这个去控制2S,7S,13S,14S的任务,再加一个17*29的计数器去控制17S,29S的任务。

2. 设置6个独立的计数器 1s_timer_cnt1, 1s_timer_cnt2, 1s_timer_cnt3, 1s_timer_cnt4, 1s_timer_cnt5, 1s_timer_cnt6,程序类似如下:

static int 1s_timer_cnt1 = 0;
static int 1s_timer_cnt2 = 0;
static int 1s_timer_cnt3 = 0;
static int 1s_timer_cnt4 = 0;
static int 1s_timer_cnt5 = 0;
static int 1s_timer_cnt6 = 0;

void ISR (void)
{
       1s_timer_cnt1 ++;
       1s_timer_cnt2 ++;
       1s_timer_cnt3 ++;
       1s_timer_cnt4 ++;
       1s_timer_cnt5 ++;
       1s_timer_cnt6 ++;
        任务1;                // 定时器中断为1S,每次进入中断都要执行任务1.
        if (1s_timer_cnt1 == 2)
        {
                1s_timer_cnt1 = 0;
                任务2;
        }
        if (1s_timer_cnt2 == 7)
        {
                1s_timer_cnt2 = 0;
                任务3;
     }
        if (1s_timer_cnt3 == 13)
        {
                1s_timer_cnt3 = 0;
                任务4;
     }
        if (1s_timer_cnt4 == 14)
        {
                1s_timer_cnt4 = 0;
                任务5;
     }
        if (1s_timer_cnt5 == 17)
        {
                1s_timer_cnt5 = 0;
                任务6;
     }
        if (1s_timer_cnt6 == 29)
        {
                1s_timer_cnt6 = 0;
                任务7;
     }
}

使用特权

评论回复
评分
参与人数 2威望 +2 收起 理由
john_light + 1 我很赞同
xlsbz + 1
8
xlsbz|  楼主 | 2010-6-16 08:16 | 只看该作者
首先设置定时器为1s,然后有两种方法:
1.使用最小公倍数  2 * 7 * 13 * 17 * 29 = 89726,然后在定时器中断里设置一个计数器,计数器在中断里每次加1,加到89726时复位为0,程序类似如下:

#define MAX_TIMER_CNT ...
aresc 发表于 2010-6-15 22:31


回帖的语句都这么规范  佩服!!!!!

使用特权

评论回复
9
xwj| | 2010-6-16 08:19 | 只看该作者
唉~~~

89726...
为什么非要只用一个计数器呢???

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
xlsbz + 1
10
xwj| | 2010-6-16 08:25 | 只看该作者
再就是:
由于存在多个任务在同一秒内同时满足的情况,所以这样的方法只能保证整体上“有”这些帧,而不能保证这些帧之间的间隔准确性。
——当然,一般情况下都不需要考虑这个间隔的一致性、准确性。

使用特权

评论回复
11
xlsbz|  楼主 | 2010-6-16 08:38 | 只看该作者
在6楼是这个意思


void ISR_TIMERx  INTERRUPT  y
{      STATIC timerx_counter;
         timerx_counter++;
         if  (timerx_counter >= 一定次数) {
                       timerx_counter = 0;
                       StartSend_OK = TRUE;  //发送数据的标志位
         }

}

在主循环

while (1)
{

if  (StartSend_OK) {
      StartSend_OK = FALSE;

      static i;
       i ++;

     s witch (i){
    case 1  任务1 break;

    c ase 2  任务2  b reak

    case 3  任务3   break

     case 4  任务1   break

    c   ase5  任务4  break

     case6 任务5  i = 0   break

    default   i = 0
}


其实还有一点没有说  还有个需求  就是 两个任务执行必须间隔一定的时间


}

使用特权

评论回复
12
mohanwei| | 2010-6-16 09:11 | 只看该作者

想要较精确的定时,用下面这种方法

本帖最后由 mohanwei 于 2010-6-16 09:19 编辑

#define _time_tick 10 //定时器节拍为10ms
#define _Tasks 7//7个任务
const int TaskTime[_Tasks]= //任务周期(对于定时器节拍的计数值)
{
    1*1000/_time_tick,
    2*1000/_time_tick,
    7*1000/_time_tick,
    13*1000/_time_tick,
    14*1000/_time_tick,
    17*1000/_time_tick,
    29*1000/_time_tick,
};
void timer_0_isr(void)
{
    static unsigned int counter[_Tasks]=0;
    int i;
    for(i=0;i<_Tasks【i】;i++)
    {
        counter【i】++;//计数器加1
        if(counter【i】>=TaskTime【i】)//定时到
        {
            counter【i】=0;//计数器清零
            sendframe(i);//发送相应数据帧
        }
    }
}

使用特权

评论回复
13
mohanwei| | 2010-6-16 09:17 | 只看该作者
这个网站代码有点烂,“counter【i】++;//计数器加1”里的方括号和i总会被掉……

使用特权

评论回复
14
mohanwei| | 2010-6-16 09:20 | 只看该作者
这个网站代码有点烂,“counter【i】++;//计数器加1”里的方括号和i总会被_*_河_*_蟹_*_掉……

使用特权

评论回复
15
mohanwei| | 2010-6-16 09:25 | 只看该作者
菊花文登场,看你还能不能河_蟹:
这҉个҉网҉站҉代҉码҉有҉点҉烂 ҉,҉“҉c҉o҉u҉n҉t҉e҉r҉[҉i҉]҉+҉+҉;҉/҉/҉计҉数҉器҉加҉1҉”҉里҉的҉方҉括҉号҉和҉i҉总҉会҉被҉河҉蟹҉掉 ҉…҉…҉

使用特权

评论回复
16
gaohq| | 2010-6-16 10:22 | 只看该作者
哈哈,菊花文。

使用特权

评论回复
17
mcu_lover| | 2010-6-16 18:31 | 只看该作者
菊花文,呵呵

使用特权

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

本版积分规则

190

主题

1614

帖子

4

粉丝