tydyg 发表于 2009-10-17 17:02:10

刚开始学习small RTOS51 写了一个小程序调试一下怎么通不过啊?

最近想学UCOS,网上有人说先学习 small RTOS51后在学会快些,就看了陈明计的书,感觉上明白了一点点,试着写了一个按键闪灯程序,很简单的,共建了4个任务,在KEIL上调试,结果在PROTEUS 上仿真,竟有问题不能4个任务都执行,不知怎么回事?哪位大哥指点一下啊?我有陈明计的 《嵌入式实时操作系统SMALL RTOS51 原理及应用》电子书。 我的QQ:513845925

/********************************/
/*   "操作系统定义"            */
/********************************/
#include "OS_CFG.H"
#include "OS_CPU.H"
#include "..\os\OS.H"
#include "..\os\OS_Q.h"
#include "..\os\OS_SEM.h"

/********************************/
/*   "以下为程序配置"         */
/********************************/

//任务定义
#ifdef IN_OS_CPU_C
extern void Show1(void);
extern void Show2(void);
extern void KEY1(void);
extern void KEY2(void);
void(* const TaskFuction)(void)={Show1,Show2,KEY2,KEY1};
//函数数组TaskFuction[]保存了各个任务初始PC指针,其按任务ID(既优先级次序)顺序保存

#endif

#define SHOW_TASK_ID    0                     /* 调用系统节拍处理函数的任务ID */

                                                /*定义串并转换使用的IO口线   */
sbit key1= P1 ^ 0;
sbit LED1 = P1 ^ 1;
sbit LED2 = P1 ^ 2;
sbit LED3 = P1 ^ 3;
sbit key2= P1 ^ 7;
/**********************end****************************************/




#define OS_MAX_TASKS            4          /* 最大任务数1~16                                           */
#define OS_TICKS_PER_SEC      100         /* 声明1秒系统系统节拍数                                    */
#define EN_USER_TICK_TIMER      1         /* 禁止(0)或允许(1)系统定时中断调用用户函数UserTickTimer()*/
#define EN_OS_INT_ENTER         0         /* 禁止(0)或允许(1)中断嵌套管理                           */
#define EN_TIMER_SHARING      0         /* 禁止(0)或允许(1)定时器中断调用OSTimeTick()               */
#define TICK_TIMER_SHARING      1         /* 定义进入多少次硬件中断为一次系统定时器软中断             */


#define EN_OS_Q               0         /* 禁止(0)或允许(1)消息队列                                 */
#define EN_OS_Q_CHK             0         /* 禁止(0)或允许(1)校验消息队列指针                         */
#define OS_Q_MEM_SEL            xdata       /* 消息队列存储空间选择,keil c51有用,必须为idata、xdata   */
                                          /* 不是keil c51时它必须为空格                               */
#define EN_OS_Q_PENT            1         /* 禁止(0)或允许(1)等待队列中的消息                         */
#define EN_OS_Q_ACCEPT          0         /* 禁止(0)或允许(1)无等待的从队列中取得消息               */
#define EN_OS_Q_POST            0         /* 禁止(0)或允许(1)FIFO方式向对列发送消息                   */
#define EN_OS_Q_POST_FRONT      1         /* 禁止(0)或允许(1)LIFO方式向对列发送消息                   */
#define EN_OS_Q_INT_POST      0         /* 禁止(0)或允许(1)中断中FIFO方式相对列发送消息             */
#define EN_OS_Q_INT_POST_FRONT1         /* 禁止(0)或允许(1)中断中LIFO方式相对列发送消息             */
#define EN_OS_Q_NMsgs         1         /* 禁止(0)或允许(1)取得队列中消息数                         */
#define EN_OS_Q_SIZE            0         /* 禁止(0)或允许(1)取得队列总容量                           */
#define EN_OS_Q_FLUSH         0         /* 禁止(0)或允许(1)清空队列                                 */

#define EN_OS_SEM               0         /* 禁止(0)或允许(1)信号量                                 */
#define EN_OS_SEM_CHK         0         /* 禁止(0)或允许(1)校验信号量索引                           */
#define OS_SEM_MEM_SEL          idata       /* 信号量储空间选择,keil c51有用,必须为idata、xdata       */

                                          /* 不是keil c51时它必须为空格                               */
#define OS_MAX_SEMS             2         /* 最大信号量数目                                           */


#define EN_OS_SEM_PENT          1         /* 禁止(0)或允许(1)等待信号量                               */
#define EN_OS_SEM_ACCEPT      0         /* 禁止(0)或允许(1)无等待请求信号量                         */
#define EN_OS_SEM_INT_POST      0         /* 禁止(0)或允许(1)中断中发送信号量                         */
#define EN_OS_SEM_POST          1         /* 禁止(0)或允许(1)中发送信号量                           */
#define EN_OS_SEM_QUERY         0         /* 禁止(0)或允许(1)查询信号量                               */

//#define data                               /* 非keil c51时必须加止这一句                               */


#if EN_TIMER_SHARING == 0
#define TIME_ISR_TASK_ID   SHOW_TASK_ID   /* 定义系统定时器软中断触发的任务ID                         */
#endif


#ifdef IN_OS_CPU_C
#if EN_USER_TICK_TIMER > 0
//extern void UserTickTimer(void);            /* 系统定时中断中调用的用户函数                              */
#define UserTickTimer() TF2=0;            /* 系统定时中断中调用的用户函数                              */
#endif
#endif



#include "config.h"

uint8 ShowCase;                        //显示缓存,用来保存各个显示位的段码
uint8 TimeAdd;                           //时间计数,用于纪录从复位以来的时间



void init(void)
{
        //"系统初始化"
        //IE = 0x00;      //"清除中断"
        //ES = 1;         //4"串行中断允许"
        //EX0 = 1;      //0"外部中断0允许"
        //ET0 = 1;      //1"定时器0中断允许"
        //EX1 = 1;      //2"外部中断1允许"
        //ET1 = 1;      //3"定时器1中断允许"
        //ET2 = 1;
        //IP = 0;         //"清除中断优先级"
        //PS = 1;         //"串行中断优先"
        //PX0 = 1;      //"外部中断0"
        //PT0 = 1;      //"定时器中断0"
        //PX1 = 1;      //"外部中断1"
        //PT1 = 0;      //"定时器中断1"
        //TCON            "定时器控制寄存器"
        TCON = 0;
        //TF1             "T1溢出标志"
        //TR1 = 1;      //"T1运行控制"
        //TF0             "T0溢出标志"
        //TR0 = 1;      //"T0运行控制"
        //IE1             "外部中断1申请标志"
        //IT1 = 1;      //"外部中断1触发方式 0=电平 1=边沿"
        //IE0             "外部中断0申请标志"
        //IT0 = 1;      //"外部中断0触发方式 0=电平 1=边沿"
        //TMOD            "定时器模式控制寄存器"
        //|GATE    |C//T   |M0      |M1      |GATE   |C//T   |M0       |M1      |
        //"高4位用于T1低4位用于T0"
        //SCON"串行控制"
        //| SM0 | SM1 | SM2 | REN | TB8 | RB8 | TI| RI|
        //"| SM0SM1 | 工作方式|   说    明   |   波 特 率    |"
        //"|   0    0 | 方 式 0   |? 同步移位   |   fosc/12   |"
        //"|   0    1 | 方 式 1   | 10位异步收发 |定时器控制   |"
        //"|   1    0 | 方 式 2   | 11位异步收发 |fosc/32|fosc/64|"
        //"|   1    1 | 方 式 3   | 11位异步收发 |定时器控制   |"
        //"SM2 多机通讯允许"
        //"REN 接收允许控制"
        //"TB8 发送数据第9位"
        //"RB8 接收数据第9位"
        //"TI发送中断标志"
        //"RI接受中断标志"
        //PCON "电源控制寄存器"
        //SMOD"波特率选择位 =1 方式1,2,3 波特率加倍"
        //"波特率=2^(sod)*fosc/(32*12*(256-初值))"
    T2CON = 0x0;
    TR2 = 1;
    ET2 = 1;
                                          //系统节拍中断使用定时器2,中断频率为600Hz
    RCAP2H = (65536 - (11059200 / 12) / 600) / 256;
    RCAP2L = (65536 - (11059200 / 12) / 600) % 256;
    TH2 = (65536 - (11059200 / 12) / 600) / 256;
    TL2 = (65536 - (11059200 / 12) / 600) % 256;

}



void main(void)
{
    init();
    OSStart();
}


void Show1(void)
{
      
    while (1)
    {
                                             /* 让发光二极管闪动 */
      LED1=~LED1;
      OSWait(K_TMO,OS_TICKS_PER_SEC);

       // OSTimeTick();                     /* 调用系统节拍处理程序             */
    }
}


void Show2(void)
{
      
    while (1)
    {
                                             /* 让发光二极管闪动 */
      LED3=~LED3;
      OSWait(K_TMO,OS_TICKS_PER_SEC/2);

      //OSTimeTick();                     /* 调用系统节拍处理程序             */
    }
}



void KEY1(void)
{
    while (1)
    {
                                                      /* 让发光二极管闪 */
   if(key1==0)LED2=0;
       else
           LED2=1;

//       OSWait(K_TMO,OS_TICKS_PER_SEC);
           OSTimeTick();                     /* 调用系统节拍处理程序 */
    }
}


void KEY2(void)
{
    while (1)
    {
                                                      /* 让发光二极管闪 */
   if(key2==0)
       {

          LED1=0;
          LED3=0;
           }
           else
          {

          LED1=1;
          LED3=1;
           }

       //   OSWait(K_TMO,OS_TICKS_PER_SEC);

          OSTimeTick();                     /* 调用系统节拍处理程序             */
    }
}


/**********************end****************************************/

coody 发表于 2009-10-17 19:05:33

这东西不实用,当你的函数带的参数比较多时就知道了,比如给TFT LCD的操作函数,参数超过10个字节

tydyg 发表于 2009-10-19 08:31:13

作为一个入门的实验啊,怎么才能调试成功呢?指点一下啊!

zuixin369 发表于 2012-2-3 16:02:01

回复【楼主位】tydyg
-----------------------------------------------------------------------

主要是你程序没有实施任务调度函数进行任务切换

cyr_hongfeng 发表于 2012-2-3 22:05:31

还不如直接学ucos

gagaguojia 发表于 2012-7-6 11:55:33

你怎么在KEY1和KEY2 2个里面都调用OSTimeTick();   况且你#define SHOW_TASK_ID    0   ;仔细看看书吧            
页: [1]
查看完整版本: 刚开始学习small RTOS51 写了一个小程序调试一下怎么通不过啊?