我在做下册uc/os中间件数据队列的实验例程时,照班运行后EASYARM.EXE上LED显示的并不是预期的从0到9这样循环下去而是0 2 4 6 8这样的,我觉得是延时的事儿,就改了下延时的参数,好点儿了,奇数出来了,但显示变得很乱,我又想,一定还是延时的原因,我继续改,又好点,能0~9这样循环显示2趟左右接着就又不行了.我觉得是因为随着程序的运行,两个任务之间切换的时间间隔就慢慢改变了.然后我又觉得用信号量能很好的解决这个问题,用了信号量之后程序每重新循环0~9一次就会跟第一次运行时一样,那么0~9的循环显示也就能一直延续下去.但,我改了之后,LED上是这样显示的:等时间间隔的依次显示0~9,接着就是显示1 3 5 7 9或者123 5 7 9或者等等.比如显示1 3 5 7 9吧,虽然2 4 6 8 0没显示出来.但显示它们的时间间隔却给留出来了,感觉就好象其实显示了只是我没看见而已.这是怎么回事啊? 还有就是,我本来设的OSTimeDly()里的参数是1,后来改成的100.我本以为这个延时只是为了让TaskStart任务得以运行,而延时的长短没什么意义.参数变大只是循环完一轮跟第二轮循环之间的时间间隔变得大了而不是具体每一个数显示的间隔变大.然而事实不是这样,就是每一个数显示的时间隔变大了,以至我能很清楚的看清依次显示的是什么. 难道这就是队列的缓冲作用? 这个程序我是这样想的:Task任务先运行(我把原来两个任务的优先级改了),把0~9送到队列,延时,这时TaskStart运行,把队列中的数据取出并在上位机显示出来.Task再运行,如此循环.我这样想对吗? 小弟刚接触ARM及uc/os,请各位大哥多多指教,非常感谢! 程序如下(原书上的有的语句我用//注释掉了),请各位老大帮我看看哪里不对. /****************************************Copyright (c)************************************************** ** Guangzou ZLG-MCU Development Co.,LTD. ** graduate school ** http://www.zlgmcu.com ** **--------------File Info------------------------------------------------------------------------------- ** File name: main.c ** Last modified Date: 2004-09-16 ** Last Version: 1.0 ** Descriptions: The main() function example template ** **------------------------------------------------------------------------------------------------------ ** Created by: Chenmingji ** Created date: 2004-09-16 ** Version: 1.0 ** Descriptions: The original version ** **------------------------------------------------------------------------------------------------------ ** Modified by: ** Modified date: ** Version: ** Descriptions: ** ********************************************************************************************************/ /****************************************Copyright (c)************************************************** ** 广州周立功单片机发展有限公司 ** 研 究 所 ** 产品一部 ** ** http://www.zlgmcu.com ** **--------------文件信息-------------------------------------------------------------------------------- **文 件 名: test.c **创 建 人: 陈明计 **最后修改日期: 2003年7月2日 **描 述: 数据队列使用例子。先定义一个数据队列QueueBuf,然后使用一个任务循环向数据队列发送数据,另一任务则 ** 从队列中取得数据,转换后向串口发送。使用EasyARM软件的数码管显示输出结果。 **--------------历史版本信息---------------------------------------------------------------------------- ** 创建人: 陈明计 ** 版 本: v1.0 ** 日 期: 2003年7月2日 ** 描 述: 原始版本 ** **--------------当前版本修订------------------------------------------------------------------------------ ** 修改人: 陈锡炳 ** 日 期: 2005-03-07 ** 描 述: 修改,以适合EasyARM2131开发板 ** **------------------------------------------------------------------------------------------------------ ********************************************************************************************************/
//在Config.h中增加 /* 数据队列的配置 */ //#define QUEUE_DATA_TYPE uint8 //#include "queue.h" //#define EN_QUEUE_WRITE 1 /* 禁止(0)或允许(1)FIFO发送数据 */ //#define EN_QUEUE_WRITE_FRONT 0 /* 禁止(0)或允许(1)LIFO发送数据 */ //#define EN_QUEUE_NDATA 0 /* 禁止(0)或允许(1)取得队列数据数目 */ //#define EN_QUEUE_SIZE 0 /* 禁止(0)或允许(1)取得队列数据总容量 */ //#define EN_QUEUE_FLUSH 0 /* 禁止(0)或允许(1)清空队列 */ //因为需要在EasyARM.exe上显示,因而需要包含PC.c文件。
#include "config.h" #define TASK_STK_SIZE 64 OS_STK TaskStk[TASK_STK_SIZE]; OS_STK TaskStartStk[TASK_STK_SIZE]; int32 QueueBuf[15]; OS_EVENT *sem; void TaskStart(void *data); void Task (void *pdata); /********************************************************************************************************* ** 函数名称: main ** 功能描述: c语言的主函数,由它启动多任务环境 ** 输 入: 无 ** 输 出: 无 ** 全局变量: 无 ** 调用模块: PC_DispClrScr,OSInit,OSTaskCreate,OSStart ** ** 作 者: 陈明计 ** 日 期: 2003年7月1日 **------------------------------------------------------------------------------------------------------- ** 修改人: ** 日 期: **------------------------------------------------------------------------------------------------------ ********************************************************************************************************/ int main (void) { OSInit(); sem=OSSemCreate(1); OSTaskCreate(TaskStart, (void *)0, &TaskStartStk[TASK_STK_SIZE - 1], 1); OSStart(); return 0; } /********************************************************************************************************* ** 函数名称: TaskStart ** 功能描述: μCOS-II的第一个任务,通常由它初始化目标板和建立其它任务 ** 输 入: 无 ** 输 出: 无 ** 全局变量: 无 ** 调用模块: ** ** 作 者: 陈明计 ** 日 期: 2003年7月1日 **------------------------------------------------------------------------------------------------------- ** 修改人: ** 日 期: **------------------------------------------------------------------------------------------------------ ********************************************************************************************************/ uint8 const ShowTable[11] = { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f,0x00}; // 0 1 2 3 4 5 6 7 8 9 void TaskStart (void *pdata) { QUEUE_DATA_TYPE Ch; uint8 err; pdata = pdata; /* 避免编译警告 */ OSTaskCreate(Task, (void *)0, &TaskStk[TASK_STK_SIZE - 1], 0); /* 创建任务 */ TargetInit(); /* 目标板初始化 */ QueueCreate((void *)QueueBuf, sizeof(QueueBuf), NULL, NULL); /* 建立数据队列 */ for (;;) {OSSemPend(sem,0,&err); //OSTimeDly(40); /* 延时 */ if (QueueRead(&Ch, (void *)QueueBuf) == QUEUE_OK) /* 接收数据 */ { PC_DispChar(0x80, 0, ShowTable[Ch], 2); /* 显示接收到的数据 */ } if (QueueRead(&Ch, (void *)QueueBuf) == QUEUE_EMPTY) { err=OSSemPost(sem); } } } /********************************************************************************************************* ** 函数名称: Task ** 功能描述: μCOS-II的任务:发送数据 ** 输 入: 无 ** 输 出: 无 ** 全局变量: 无 ** 调用模块: ** ** 作 者: 陈明计 ** 日 期: 2003年7月1日 **------------------------------------------------------------------------------------------------------- ** 修改人: ** 日 期: **------------------------------------------------------------------------------------------------------ ********************************************************************************************************/ void Task (void *pdata) { uint8 i; uint8 err; pdata = pdata; /* 避免编译警告 */ for (;;) {OSSemPend(sem,0,&err); #if EN_QUEUE_WRITE > 0 for (i = 0; i < 10; i++) { QueueWrite((void *)QueueBuf, i); //if (QueueWrite((void *)QueueBuf, i) == OS_Q_FULL) /* FIFO方式发送数据*/ //{ err=OSSemPost(sem); OSTimeDly(100); //i--; /* 错误处理 */ // } // OSTimeDly(20); /* 延时 */ } #endif #if EN_QUEUE_WRITE_FRONT > 0 for (i = 0; i < 10; i++) { if (QueueWriteFront((void *)QueueBuf, i) == OS_Q_FULL) /* LIFO方式发送数据 */ { /* 错误处理 */ OSTimeDly(40); i--; } } OSTimeDly(600); #endif } } /********************************************************************************************************* ** End Of File ********************************************************************************************************/
|