问题如下:当STM32的外部数据返回到emwin里面处理显示的时候,需要花很久时间才刷新一次,emwin里的Progbar控件进度条,之前不跑系统的时候是可以1%-2%-3%…-100%,一个一个百分比的变化的,加了系统之后,返回的数据用串口和它显示对比,发现大概过了8%才变化一次,也就是第一次开机刷新时显示0%,等n久后才由0%-8%,8%-16%(0-100%变化分别由变量0-100变化,也就是变量的值对应着进度条的值)但是这个过程并没有实时显示出来,后来去查了一次,应该是任务调度的问题,我设置的emwin的优先级和外部运行的程序的优先级一样,
都是5级优先级
//EMWINDEMO任务
//设置任务优先级
#define EMWINDEMO_TASK_PRIO 5
//任务堆栈大小
#define EMWINDEMO_STK_SIZE 2048
//任务控制块
OS_TCB EmwindemoTaskTCB;
//任务堆栈
CPU_STK EMWINDEMO_TASK_STK[EMWINDEMO_STK_SIZE];
//emwindemo_task任务
void emwindemo_task(void *p_arg);
//L298n电机任务
//设置任务优先级
#define motor_TASK_PRIO 5
//任务堆栈大小
#define motor_STK_SIZE 160
//任务控制块
OS_TCB motorTaskTCB;
//任务堆栈
CPU_STK motor_TASK_STK[motor_STK_SIZE];
//led0任务
void motor_task(void *p_arg);
也就是说,这两个任务是一直完成然后切换的,(当然过程中还有更高优先级的触摸任务,优先级4)
这里已经使能了时间片轮调度功能
#if OS_CFG_SCHED_ROUND_ROBIN_EN //当使用时间片轮转的时候
//使能时间片轮转调度功能,时间片长度为1个系统时钟节拍,既1*5=5ms
OSSchedRoundRobinCfg(DEF_ENABLED,1,&err);
后来我就把两个两个任务的时间片轮都调大,L298n的改成120个时间片轮,也就是600ms,
//L298N控制水泵任务
OSTaskCreate((OS_TCB* )&motorTaskTCB,
(CPU_CHAR* )"motor task",
(OS_TASK_PTR )motor_task,
(void* )0,
(OS_PRIO )motor_TASK_PRIO,
(CPU_STK* )&motor_TASK_STK[0],
(CPU_STK_SIZE)motor_STK_SIZE/10,
(CPU_STK_SIZE)motor_STK_SIZE,
(OS_MSG_QTY )0,
(OS_TICK )120, //时间片为0时为默认长度,即5ms*1个系统时钟节拍 =5ms
(void* )0,
(OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,
(OS_ERR* )&err);
L298n的任务块
void motor_task(void *p_arg)
{
OS_ERR err;
while(1)
{
// if(HW==0) //如果检测到有瓶子 ,则红外灯亮,返回0,
// {
if (/*Bottle_Flag==1&&*/L
{ buhuo();
motor_start(); //水泵全速启动
}else if(L>=capacity1-1) //如果检测到流量大于等于299ml,则水泵停止工作,转盘启动
{ //OSTaskTimeQuantaSet();
Bottle=Bottle+1;
motor_stop(); //水泵停止
Locate_Rle(1600,1000,CW); //步进电机旋转90度
printf("标志位为%drn",Bottle_Flag); //打印输出
printf("瓶子:%d 瓶rn",Bottle); //打印瓶子
Freq=0; //上一次的工作已完成,把捕捉到的脉冲计数清零
L=0; //上一次的工作已完成,把流量计数清零
Bottle_Flag=0; //标志位清零,表示清除上一次瓶子的状态
delay_ms(500);
} OSTimeDlyHMSM(0,0,0,5,OS_OPT_TIME_PERIODIC,&err);//延时1ms
}
}
emwin的时间片轮改成2个系统时钟节拍,10ms
//STemWin Demo任务
OSTaskCreate((OS_TCB* )&EmwindemoTaskTCB,
(CPU_CHAR* )"Emwindemo task",
(OS_TASK_PTR )emwindemo_task,
(void* )0,
(OS_PRIO )EMWINDEMO_TASK_PRIO,
(CPU_STK* )&EMWINDEMO_TASK_STK[0],
(CPU_STK_SIZE)EMWINDEMO_STK_SIZE/10,
(CPU_STK_SIZE)EMWINDEMO_STK_SIZE,
(OS_MSG_QTY )0,
(OS_TICK )2, //时间片长度为1个系统时钟节拍,既2*5=10ms
(void* )0,
(OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,
(OS_ERR* )&err);
emwin的任务块
//EMWINDEMO任务
void emwindemo_task(void *p_arg)
{
OS_ERR err;
GUI_CURSOR_Show(); //显示鼠标
MainTask();
while(Run_Flag)
{
OSTimeDlyHMSM(0,0,0,1,OS_OPT_TIME_PERIODIC,&err);//延时5ms
}
}
然后现在Progbar的控件实时刷新的问题没有解决,还多了一个emwin切换界面反应很慢的问题,后来发现,我把L298n的时间片轮设置过大了,导致长时间停留在L298n,当你触摸界面的时候,要等l298n的任务完成了才能刷新,然后后面经过测试。
把L298n的时间片轮设置为默认,即5ms
然后经过测试得,emwin一个完整的任务刷新大概需要30ms,也就是6个时间片轮。
到这里,这个Progbar控件的问题就基本解决了。已经可以做到单片机外部返回数据,然后UI界面实时刷新,差不多1000ms刷新一次这样
我的UcosⅢ刚学几天,这个是个人见解,大佬勿喷!嘴下留情!