renwocai 发表于 2012-10-15 14:15:32

这样写按键控制数码管动态显示,能不能称作“任务调度”

之前把数码管和按键都放在中断里面处理,是这样写的:http://www.amobbs.com/thread-5501382-1-1.html,因为PROTERU的原因,我一度怀疑程序在哪里出了错误呢{:sweat:} ,现在我把数码管刷新和按键处理都放在主程序里面,在中断里面设置标志位,主程序中判断以后选择性的执行这两个函数,想请教下达人,这是不是就是所谓的“任务调度”?如果是,那么这种方式比较好处理,因为程序执行的间隔时间都是固定的,但对于有些交互式外设,如AD,DA,LCD,必须从对方读取数据,时间间隔是离散的,应该怎样安排任务?{:tongue:} 以上请教!

附本次程序和仿真图(仿真是看不到效果的,但通过硬件测试)#include <reg51.h>
#define uchar unsigned char
uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
uchar shu=85,count;
bit flag;
sbit kb=P3^4;



void sumaguan()
{
        static uchar i=0;
        i++;
        P0=0XFF;
        P2=~(1<<(i-1));
        if(i<3)
                P0=0XC0;
        else if(i==3)
                P0=tab;
        else if(i==4)
                {
                        P0=tab;
                        i=0;
                }
}
void anjianchuli()
{
        static uchar zhuangtai=0;
        switch(zhuangtai)
                {
                        case 0:
                                {
                                        if(kb==0)
                                                zhuangtai++;
                                };break;
                        case 1:
                                {
                                        if(kb==0)
                                                zhuangtai++;
                                        else
                                                zhuangtai--;

                                };break;
                        case 2:
                                {
                                        if(kb==0)
                                                {
                                                        zhuangtai++;
                                                        shu++;
                                                        if(shu==100)
                                                                shu=0;
                                                }
                                        else
                                                        zhuangtai--;
                                };break;
                        case 3:
                                {
                                        if(kb==1)
                                                zhuangtai=0;
                                };break;
                }
        }



main()
{
        TMOD = 0x01;
    TH0 = 0x0E8;
    TL0 = 0x90;
    EA = 1;
    ET0 = 1;
    TR0 = 1;
        while(1)
        {
                if(flag==1)
                {
                        flag=0;
                        sumaguan();
                }
                if(count>=3)
                {
                        anjianchuli();
                        count=0;
                }
        }
       
}
void timer0() interrupt 1
{
        flag=1;
        count++;
    TH0 = 0x0E8;
    TL0 = 0x90;
}


renwocai 发表于 2012-10-15 15:29:41

顶下,今天星期一,都在上班忙吗,没人回复哦

channe 发表于 2012-10-15 16:00:47

这个不能算作是任务调度,只是把中断程序中的内容拿出来,放在主函数中执行了。
可以想象一种极端情况,比如刷LCD的程序出错堵死了,那么另外的程序也不能执行了。
而真正的任务调度,是由一个主时钟驱动,每隔一定周期切换一次任务,假如某个线程堵死了,其他的还能执行到。

renwocai 发表于 2012-10-15 16:18:02

channe 发表于 2012-10-15 16:00 static/image/common/back.gif
这个不能算作是任务调度,只是把中断程序中的内容拿出来,放在主函数中执行了。
可以想象一种极端情况,比 ...

的确如你所说,我在主楼就说过间隔时间离散的不能这么处理,但还想不到什么好的办法。如果举段代码示教,谢谢。

channe 发表于 2012-10-15 16:53:25

本帖最后由 channe 于 2012-10-15 16:55 编辑

代码不好写,思路是这样。
结构体
{
任务指针   //(就是程序的指针,例如你的sumaguan)
寄存器状态//( 保存运行状态 )
任务状态 //(可以放置 请求 睡眠 等等)
} Task;
然后你需要一个系统滴答时钟,比如1ms的中断,最高优先级。
然后每一毫秒到了,检查 任务状态 ,如果需要调用 ,那么调用这个函数   *(任务指针)();   //调用之前把上一个正在执行的任务的寄存器保存下载,把要执行的任务的寄存器恢复。

renwocai 发表于 2012-10-15 17:00:27

好的,谢谢,我领会一下。

renwocai 发表于 2012-10-15 17:22:23

channe 发表于 2012-10-15 16:53 static/image/common/back.gif
代码不好写,思路是这样。
结构体
{


这个思想我想应该能理解了,这是防止有些程序的执行时间大于定时器的时间间隔,那么只要到时间了,不管原有函数有没有执行完毕,都先放下,等到下一次时间周期到了后接着执行。是这样吧。


但我还是写不了,因为这个结构体里面的寄存器状态和任务状态不知道写什么。能否就我主楼的函数改写一下,万分感谢。

难点在于要强制改变中断的执行方式,因为一般是从哪里中断再回到哪里,而作为任务调度是中断后保护断点,再执行下一函数。

另外,想请教下这么安排程序的好处和不足一般在什么地方,操作系统的思想是不是就是这样的?

channe 发表于 2012-10-15 17:30:37

renwocai 发表于 2012-10-15 17:22 static/image/common/back.gif
这个思想我想应该能理解了,这是防止有些程序的执行时间大于定时器的时间间隔,那么只要到时间了,不管原 ...

是可以防止有些程序的执行时间大于定时器的时间间隔,但主要不是为了这个。
反而每个任务都应该做成一个死循环。
然后系统的滴答时钟取多少比较好我也不知道,但不是为了防止超时那种,而应该是第一个任务执行一步,第二个任务执行一步,第一个任务,第二个任务。这样子。

channe 发表于 2012-10-15 17:31:46

参见这个文章 http://www.amobbs.com/forum.php?mod=viewthread&tid=1398508&highlight=%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F

zhanan 发表于 2012-10-15 19:16:25

时间长的任务,用状态机分成几个子任务,使每个任务占用时间最短,消除了可恶的死等延时。
页: [1]
查看完整版本: 这样写按键控制数码管动态显示,能不能称作“任务调度”