刚开始学习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****************************************/ 这东西不实用,当你的函数带的参数比较多时就知道了,比如给TFT LCD的操作函数,参数超过10个字节 作为一个入门的实验啊,怎么才能调试成功呢?指点一下啊! 回复【楼主位】tydyg
-----------------------------------------------------------------------
主要是你程序没有实施任务调度函数进行任务切换 还不如直接学ucos 你怎么在KEY1和KEY2 2个里面都调用OSTimeTick(); 况且你#define SHOW_TASK_ID 0 ;仔细看看书吧
页:
[1]