⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 柴油发动机的电控PID代码。平台freescale的MC9S12DZ60单片机。核心算法
💻 C
📖 第 1 页 / 共 5 页
字号:
  pka_exe = temp3;
  //PKI 
  temp = delta_exe;
  temp = comp(temp,255);//偏差限制
  ltemp = (long int)temp;
  sum_delta_exe += ltemp;  //累加
  if(sum_delta_exe > max_sum_pos)
    sum_delta_exe = max_sum_pos;
  else if(sum_delta_exe < min_sum_pos)
    sum_delta_exe = min_sum_pos;
  ltemp = sum_delta_exe / (int)nrm.rpki;
  ltemp /= 2;
  temp4 = (int)ltemp;
  //计算PWM占空比
  temp = temp1 + temp2 + temp3 + temp4; //P, I, D
  //temp = temp1 + temp4; //P,I
  temp = comp(temp,3330); //输出限制
  temp = (temp + 3333 + exe_outdata) / 2;
  exe_outdata = (uint)temp;
  PWMDTY23 = exe_outdata;//输出PWM占空比
}
/****************************************************************************
* 函数名称:pid_egr()																												
* 函数功能:位置环pid子程序																							
* 入口参数:无																														
* 出口参数:无																														
****************************************************************************/
void pid_egr(void) 
{
  //变量定义  
  //int x1,x2,y1,y2,x;
  /* 计算偏差 */
  //nrm.rliml = nrm.rpkp;
  //nrm.rlims = nrm.rpki;
  //nrm.rlimh = nrm.rpkd;
  
  pre_set_egr += set_egr;
  pre_set_egr /= 2;
  pre_fb_egr += fb_egr;
  pre_fb_egr /= 2;
  delta_egr = pre_set_egr - pre_fb_egr;

  //插值求stpkp
  x1 = PSEPA;
  y1 = LPKP;
  x2 = 1023;
  y2 = nrm.rliml;
  x = fb_egr;
  if(x > x1)
  {
    stpkp = insert(0);
  }
  else
  {
    stpkp = LPKP;
  } 
    
  //插值求stpkd
  y1 = LPKD;
  y2 = nrm.rlims;
  if(x > x1)
  {
    stpkd = insert(0);
  }
  else 
  {
    stpkd = LPKD;
  }
    
  //PKP 
  temp = delta_egr;
  temp = comp(temp,255);// 偏差限制 
  temp *= (int)nrm.egrkp;//计算, 没用到插值
  temp /= 2; 
  temp1 = temp; 
  
  //PKD
  temp = delta_egr - pre_delta_egr;  // 偏差计算 soft
  pre_delta_egr = delta_egr;
  temp = comp(temp,255);//偏差限制
  temp *= (int)nrm.egrkd;//没用插值
  temp /= 2; 
  temp = (temp + pkd_egr) / 2;
  temp2 = temp;
  pkd_egr = temp2;
    
  //PKA 
  temp = pkd_egr - pre_pkd_egr; //偏差计算,soft
  pre_pkd_egr = pkd_egr;
  temp = comp(temp,127);//偏差限制
  temp *= (int)nrm.rpdynaw;
  temp /= 2;
  temp = (temp + pka_egr) / 2;
  temp3 = temp;
  //pka_egr = temp3;
    
  //PKI 
  temp = delta_egr;
  temp = comp(temp,256);//偏差限制
  ltemp = (long int)temp;
  sum_delta_egr += ltemp;  //累加
  if(sum_delta_egr > max_sum_pos)
    sum_delta_egr = max_sum_pos;
  else if(sum_delta_egr < min_sum_pos)
    sum_delta_egr = min_sum_pos;
  ltemp = sum_delta_egr / (int)nrm.egrki;
  ltemp /= 8;
  //ltemp /= 10;
  temp4 = (int)ltemp;
  
  //计算PWM占空比
  temp = temp1 + temp2 + temp3 + temp4; //P, I, D
  //temp = temp1 + temp4; //P,I
  temp = comp(temp,1950); //输出限制
  temp = (temp + 1950 + egr_outdata) / 2;
  //if((water_temperature < 35) || (water_temperature > 100))
  {
    //egr_outdata = 0;
  }
 // else
  {
    egr_outdata = (uint)temp;
  }
  PWMDTY01 = egr_outdata;//输出PWM占空比
  
}/****************************************************************************
* 函数名称:																										
* 函数功能:串口通讯相关程序																							
* 入口参数:无																													
* 出口参数:无																													
*****************************************************************************/
void sdstrm(unsigned int coun4,unsigned char *rr5,
            unsigned char flag2,unsigned char flag6)
{                                                                                           
  //in:
  //    coun4: the number of the word_data. if coun4 == 0 
  //           then send 1 byte on dadrress rr5
  //    rr5: the dadrress of the first data
  //    flag2: is 1 then SYN do; is 0 not do
  //    flag6: is 1 then summ do; is 0 not do 
  //out:
  //    summ: the total dadr sum
  
  unsigned char al;
  unsigned int i;
  if(flag2!=0)
  {
    //sptemp = SCI0SR1;
    al = SYN;
    SCI0DRL = al;
    while((SCI0SR1 & SCI0SR1_TDRE_MASK) == 0);
    summ += al;
  }

  if(coun4 == 0) 
  {
    al = *rr5;
    SCI0DRL = al;
    while((SCI0SR1 & SCI0SR1_TDRE_MASK) == 0);
    summ += al;
  }
  
  else 
  {
    for (i=0;i<coun4;i++)
    {
      rr5++;
      al = *rr5;
      //sptemp = SCI0SR1;
      SCI0DRL = al;
      while((SCI0SR1 & SCI0SR1_TDRE_MASK) == 0);
      summ += al;
      //
      rr5--;
      al = *rr5;
      //sptemp = SCI0SR1;
      SCI0DRL = al;
      while((SCI0SR1 & SCI0SR1_TDRE_MASK) == 0);
      summ += al;
      //
      rr5 += 2;
    }
  }
  
  if(flag6!=0)
  {
    //sptemp = SCI0SR1;
    al=summ;
    SCI0DRL = al;
    while((SCI0SR1 & SCI0SR1_TDRE_MASK) == 0);
  }
}
  
void pinc(unsigned char flag3,unsigned char flag4)
{    
  //in:
  //     flag3: 0:decrease  1:increase
  //     flag4: 0:slow      1:fast
  unsigned int bx,cx,stepp;
  unsigned int *ax,*dx;
  //do
  //{
    //sptemp = SCI0SR1;
  //}
  //while((sptemp & SCI0SR1_RDRF_MASK) == 0);  //等待接受操作数地址
   
  //bx = (unsigned int)SCI0DRL;
  bx = cmdstr[1];
  //
  if(flag4 == 1) stepp = FFACTOR;
  else stepp = FACTOR; 
  //
  //
  if(flag3 == 1)             ////increase
  {
    if(bx < MODE3NI)
    {
      dx = &nrm.rksp;
      dx += bx;
      cx = *dx;
      ax = &max.rksp;
      ax += bx;
      bx = *ax;              //bx is the top_limit value
    }
    else if(bx < (MODE3N)) 
    {
      if(bx < 2*MODE3NI) 
      {
        dx = &max.rksp;
        bx -= MODE3NI;
      }
      else 
      {
        dx = &min.rksp;
        bx -= (2*MODE3NI);
      }
      dx += bx;
      cx = *dx;
      bx = 0xffff;           //
    }
    else if(bx < (MODE3N+MODE7NI))
    {
      dx = &oil.lmt1;
      bx -= MODE3N;
      dx += bx;
      cx = *dx;
      bx = 0x3ff;
    }
    else if(bx == (MODE3N+MODE7N-1))  //the last rotation's limit value is different!!!!
    {
      dx = &rot.lmt1;
      bx -= (MODE3N+MODE7NI);
      dx += bx;
      cx = *dx;
      bx = 0x1fff;
    }
    else if((bx != (MODE3N+MODE7N-1)) && (bx < (MODE3N+MODE7N))) 
    {
      dx = &rot.lmt1;
      bx -= (MODE3N+MODE7NI);
      dx += bx;
      cx = *dx;
      dx++;
      bx = *dx;
      dx--;
    }
    else if(bx < (MODE3N+MODE7N+MODE8NI))  //operate object is rotation[10]
    {
      dx = rotation;
      bx -= (MODE3N+MODE7N);
      dx += bx;
      cx = *dx;
      //bx = 0x3ff;
      if(dx == rotation+9)
      {
        bx = 3500; 
      }
      else
      {
        dx++;
        bx = *dx;
        dx--;
      }
    }
    else if(bx < (MODE3N+MODE7N+2*MODE8NI))  //operate object is position[10]
    {
      dx = position;
      bx -= (MODE3N+MODE7N+MODE8NI);
      dx += bx;
      cx = *dx;
      if(dx == position+9)
      {
        bx = 1023; 
      }
      else
      {
        dx++;
        bx = *dx;
        dx--;
      }
      
      //bx = 0x3ff;
      //dx++;
      //if(*dx < 0x3ff)
      //{
        //bx = *dx;
      //}
      //else
      //{
        //bx = 0x3ff;
      //}
      //dx--;
    }
    else
    {
      dx = egr[0];
      bx -= (MODE3N+MODE7N+2*MODE8NI);
      dx += bx;
      cx = *dx;
      bx = 0x3ff;
    }
    
    // then dx:the variable_daddress
    //      cx:the variable
    //      bx:the top_limit_value
    bx -= stepp;
    if(cx <= bx) cx += stepp;
    *dx = cx;
  }
  //
  //
  else                       ////decrease
  {
    if(bx < MODE3NI)
    {
      dx = &nrm.rksp;
      dx += bx;
      cx = *dx;
      ax = &min.rksp;
      ax += bx;
      bx = *ax;              //bx is the bottom_limit value
    }
    else if(bx < (MODE3N)) 
    {
      if(bx < 2*MODE3NI) 
      {
        dx = &max.rksp;
        bx -= MODE3NI;
      }
      else 
      {
        dx = &min.rksp;
        bx -= (2*MODE3NI);
      }
      dx += bx;
      cx = *dx;
      bx = 0;                //
    }
    else if(bx < (MODE3N+MODE7NI))
    {
      dx = &oil.lmt1;
      bx -= MODE3N;
      dx += bx;
      cx = *dx;
      bx = 0;
    }
    else if(bx == (MODE3N+MODE7N-1))
    {
      dx = &rot.lmt1;
      bx -= (MODE3N+MODE7NI);
      dx += bx;
      cx = *dx;
      bx = 0;
    }
    else if((bx != (MODE3N+MODE7N-1)) && (bx < (MODE3N+MODE7N))) 
    {
      dx = &rot.lmt1;
      bx -= (MODE3N+MODE7NI);
      dx += bx;
      cx = *dx;
      dx--;
      bx = *dx;
      dx++;
    }
    else if(bx < (MODE3N+MODE7N+MODE8NI))  //operate object is rotation[10]
    {
      dx = rotation;
      bx -= (MODE3N+MODE7N);
      dx += bx;
      cx = *dx;
      //bx = 0;
      dx--;
      bx = *dx;
      dx++;
    }
    else if(bx < (MODE3N+MODE7N+2*MODE8NI))  //operate object is position[10]
    {
      dx = position;
      bx -= (MODE3N+MODE7N+MODE8NI);
      dx += bx;
      cx = *dx;
      //bx = 0;
      dx--;
      if(*dx < 0x3ff)
      {
        bx = *dx;
      }
      else
      {
        bx = 0x3ff;
      }
      dx++;
    }
    else
    {
      dx = egr[0];
      bx -= (MODE3N+MODE7N+2*MODE8NI);
      dx += bx;
      cx = *dx;
      bx = 0;
    }
    // then dx:the variable_daddress
    //      cx:the variable
    //      bx:the bottom_limit_value
    bx += stepp;
    if(cx >= bx) cx -= stepp;
    *dx = cx;
  }
  //
  summ = 0;
  sdstrm(1,(unsigned char *)dx,0,0);
}

/****************************************************************************
* 函数名称:sci_rev()																												
* 函数功能:串口中断程序,接收数据放入缓冲区																							
* 入口参数:无																														
* 出口参数:无																														
****************************************************************************/
interrupt 20 void sci_rev(void)
{
  //uchar c;
  sptemp = SCI0SR1;
  if((sptemp & SCI0SR1_RDRF_MASK) !=0) //有数据输入
  {
    PORTB_BIT1 = ~PORTB_BIT1;
    //c = SCI0DRL; 
    //if(inbufful != 1)//接收缓冲区没满
    {
      //*inlast = c;
      *inlast = SCI0DRL;
      inlast++;
      inbufsign = 1;//接收缓冲区非空
      if(inlast == (inbuf+ILEN))
      {
        inlast = inbuf;//地址到顶部回到底部
      }
      //if(inlast == getlast)
      //{
      //  inbufful = 1;  //置接收缓冲区满标志
      //}
    }
  }
}

/****************************************************************************
* 函数名称:compcread(uchar modenum)																												
* 函数功能:串口pc读取命令处理程序																							
* 入口参数:void																														
* 出口参数:无																														
****************************************************************************/
void compcread(void)
{
  switch(cmdstr[1])
  {
    case MODE1:
    {
      summ = 0;
      sdstrm(MODE1N,(unsigned char *)&mnt.arg1,1,1);
      break;
    }
    case MODE2:
    {
      summ = 0;
      sdstrm(MODE2N,(unsigned char *)&nrm.rksp,1,1);
      break;
    }
    case MODE3:
    {
      summ = 0;
      sdstrm(MODE3NI,(unsigned char *)&nrm.rksp,1,0);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -