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

[复制链接]
 楼主| renwocai 发表于 2012-10-15 15:20 | 显示全部楼层 |阅读模式
以下是电路,我要的功能很简单,按键第按一次,数码管后两位显示加1,到100后回头,看这样写能不能称作“任务调度”,如果是,那么这种方式比较好处理,因为程序执行的间隔时间都是固定的,但对于有些交互式外设,如AD,DA,LCD,必须从对方读取数据,时间间隔是离散的,应该怎样安排任务? 以上请教!




  1. #include <reg51.h>
  2. #define uchar unsigned char
  3. uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
  4. uchar shu=85,count;
  5. bit flag;
  6. sbit kb=P3^4;



  7. void sumaguan()
  8. {
  9.         static uchar i=0;
  10.         i++;
  11.         P0=0XFF;
  12.         P2=~(1<<(i-1));
  13.         if(i<3)
  14.                 P0=0XC0;
  15.         else if(i==3)
  16.                 P0=tab[shu/10];
  17.         else if(i==4)
  18.                 {
  19.                         P0=tab[shu%10];
  20.                         i=0;
  21.                 }
  22. }
  23. void anjianchuli()
  24. {
  25.         static uchar zhuangtai=0;
  26.         switch(zhuangtai)
  27.                 {
  28.                         case 0:
  29.                                 {
  30.                                         if(kb==0)
  31.                                                 zhuangtai++;
  32.                                 };break;
  33.                         case 1:
  34.                                 {
  35.                                         if(kb==0)
  36.                                                 zhuangtai++;
  37.                                         else
  38.                                                 zhuangtai--;

  39.                                 };break;
  40.                         case 2:
  41.                                 {
  42.                                         if(kb==0)
  43.                                                 {
  44.                                                         zhuangtai++;
  45.                                                         shu++;
  46.                                                         if(shu==100)
  47.                                                                 shu=0;
  48.                                                 }
  49.                                         else
  50.                                                         zhuangtai--;
  51.                                 };break;
  52.                         case 3:
  53.                                 {
  54.                                         if(kb==1)
  55.                                                 zhuangtai=0;
  56.                                 };break;
  57.                 }
  58.         }



  59. main()
  60. {
  61.         TMOD = 0x01;
  62.     TH0 = 0x0E8;
  63.     TL0 = 0x90;
  64.     EA = 1;
  65.     ET0 = 1;
  66.     TR0 = 1;
  67.         while(1)
  68.         {
  69.                 if(flag==1)
  70.                 {
  71.                         flag=0;
  72.                         sumaguan();
  73.                 }
  74.                 if(count>=3)
  75.                 {
  76.                         anjianchuli();
  77.                         count=0;
  78.                 }
  79.         }
  80.        
  81. }
  82. void timer0() interrupt 1
  83. {
  84.         flag=1;
  85.         count++;
  86.     TH0 = 0x0E8;
  87.     TL0 = 0x90;
  88. }

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
ayb_ice 发表于 2012-10-15 15:24 | 显示全部楼层
差不多吧
 楼主| renwocai 发表于 2012-10-15 15:28 | 显示全部楼层
差不多吧
ayb_ice 发表于 2012-10-15 15:24


谢谢回复,如果是,那么这种方式比较好处理,因为程序执行的间隔时间都是固定的,但对于有些交互式外设,如AD,DA,LCD,I2C必须从对方读取数据,时间间隔是离散的,应该怎样安排任务? 以上请教!
ayb_ice 发表于 2012-10-15 15:59 | 显示全部楼层
建议一个主循环10MS,如果程序没有执行到10MS,等待到10MS,开始下一循环,显示等任务在定时中断中完成,一个周期将所有任务检查处理一遍,当然有些任务可以几个循环才处理一次。。。
 楼主| renwocai 发表于 2012-10-15 16:18 | 显示全部楼层
建议一个主循环10MS,如果程序没有执行到10MS,等待到10MS,开始下一循环,显示等任务在定时中断中完成,一个周期将所有任务检查处理一遍,当然有些任务可以几个循环才处理一次。。。 ...
ayb_ice 发表于 2012-10-15 15:59


我很笨,能否来段简单代码,谢谢。
ayb_ice 发表于 2012-10-15 16:47 | 显示全部楼层
本帖最后由 ayb_ice 于 2012-10-15 16:53 编辑

void main(void)
{
    mcu_init();
    while(1)
    {
        task_a();
        if(++flag_x == 3){
            flag_x = 0;
            task_b();
        }
        if(++flag_y == 100){
            flag_y = 0;
            task_c();
        }
        ...

        while(!flag_10ms);
        flag_10ms = 0;
    }
}
void isr_t0(void) interrupt 1
{
    reload_t0(10MS);
    flag_10ms = 1;
}
void isr_other(void) interrupt x
{
    .....
}

评分

参与人数 1威望 +2 收起 理由
ocon + 2

查看全部评分

 楼主| renwocai 发表于 2012-10-15 17:01 | 显示全部楼层
谢谢,我领会下。
coody 发表于 2012-10-16 08:40 | 显示全部楼层
状态机
 楼主| renwocai 发表于 2012-10-16 11:30 | 显示全部楼层
void main(void)
{
    mcu_init();
    while(1)
    {
        task_a();
        if(++flag_x == 3){
            flag_x = 0;
            task_b();
        }
        if(++flag_y == 100){
            flag_ ...
ayb_ice 发表于 2012-10-15 16:47




这个方式的运行实质跟我的写法是一样的哦,主要针对有些任务运行时间超过定时器设定的时间间隔,这样可以保证每个任务都有机会运行到,但如果有的任务运行时间过长(比如我不用状态机处理按键,那就一定要等到按键抬起才能扫描数码管,结果又不好了。
hjs1618 发表于 2012-10-16 11:37 | 显示全部楼层
建议一个周期10MS或5MS用于按键扫描或其他定时处理,其余时间处理其他函数。不用一直等        while(!flag_10ms);
        flag_10ms = 0;
ayb_ice 发表于 2012-10-16 11:44 | 显示全部楼层
“比如我不用状态机处理按键,那就一定要等到按键抬起才能扫描数码管,结果又不好了。”

一定要禁止死等程序
ayb_ice 发表于 2012-10-16 11:45 | 显示全部楼层
“主要针对有些任务运行时间超过定时器设定的时间间隔”

这样的任务一定要分时间片运行
xuxikfg 发表于 2012-10-16 18:53 | 显示全部楼层
果断留名。。
gx_huang 发表于 2012-10-16 20:40 | 显示全部楼层
貌似很高级的方法。
其实是比较笨的方法,肯定是操作系统之类的书看多了。

最基本的教材里的例子其实最实用:
定时器定时中断,每来一次中断,显示一个数码管。
主程序里只要对需要显示 的内容赋值就可以了。
 楼主| renwocai 发表于 2012-10-19 10:47 | 显示全部楼层
貌似很高级的方法。
其实是比较笨的方法,肯定是操作系统之类的书看多了。

最基本的教材里的例子其实最实用:
定时器定时中断,每来一次中断,显示一个数码管。
主程序里只要对需要显示 的内容赋值就可以了。 ...
gx_huang 发表于 2012-10-16 20:40



可能对这个任务来说的确是这样,这里我只想请教一种方法,一种思想
您需要登录后才可以回帖 登录 | 注册

本版积分规则

8

主题

173

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部