STM32
直播中

张健

8年用户 1424经验值
私信 关注
[问答]

如何解决STM32的外部数据返回到emwin里面处理显示问题?

如何解决STM32的外部数据返回到emwin里面处理显示问题?

回帖(1)

戚歆敦

2021-12-22 15:51:16
问题如下:当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Ⅲ刚学几天,这个是个人见解,大佬勿喷!嘴下留情!
举报

更多回帖

发帖
×
20
完善资料,
赚取积分