单片机工控应用

描述

先看一个没有做任务调度的XY轴复位的程序A:

//XY轴复位
unsigned int XYReset(unsigned char reset)
{
  static unsigned char operation = STEP1;
  static unsigned int baseTime;


  if(reset == TRUE)  
  {
    operation = STEP1;
   }

  switch(operation){
    case STEP1:
        sm_run(SM101,3200);  //步进电机SM101运动3200步
        operation = STEP2;
      break;
    case STEP2:
    if(sm_state[SM101]==SM_STOP)
    {  //3200步运动完成
        baseTime = systemTime;  //开始延时
        operation = STEP3;
      }
      break;
    case STEP3:
     if(Timer(baseTime,500)==TRUE)
     { //延时500ms完成
        sm_run(SM102,3200);  //步进电机SM102运动3200步
        operation = STEP4;
      }
      break;
    case STEP4:
      if(IsSensorOn(X101))
      {
        sm_stop(SM102);
        return TRUE;
      }
      else if(sm_state[SM102] == SM_STOP)
      {
        return -2;  //动作报错
      }
      break;
    default:break;
  }  
  return 0; //动作正在运行
}

下面增加任务调度的XY轴复位的程序B:

//XY轴复位
void XYReset()
{
  switch(GetStep())
  {
    case STEP1:
    sm_run(SM101,3200);
    wait_sm_stop(SM101,STEP2);//任务切换,让出当前的运行权限,直到SM101电机停止后切换回来
    break;
    case STEP2:
    wait_time(500,STEP3);//任务切换 500ms后切换回来
    break;
    STEP3:
    find_sensor(SM102,3200,X101,STEP4,STEP_ERROR);//任务切换,传感器感应 电机停止后回来
    break;
    STEP4:
    set_ation_ok();  //正确结束当前的动作任务,退出就绪队列
    break;
    STEP_ERROR:
    set_error("SM102电机丢步");//错误结束当前动作任务,退出就绪队列
    break;
  }
}

程序A和程序B的共同点:

  1. 都有耗时操作:电机运动,等待传感器状态变化,延时等。
  2. 使用switch case做状态转换
  3. 都是非阻塞,没有死等卡在当前的函数,系统其它函数也可以运行.

程序A程序B的不同点:

  1. 程序A的局部变量多,程序B要简短,代码行数只有程序A的56%
  2. 程序B的电机状态 传感器状态 时间状态都是系统管理查询的,极大的提高了代码的复用,因为一个项目一般都有几十个动作动作函数.
  3. 程序B没有if else都是函数调用,逻辑清晰,更接近自然表达.
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分