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

📄 main.c

📁 柴油发动机的电控PID代码。平台freescale的MC9S12DZ60单片机。核心算法
💻 C
📖 第 1 页 / 共 5 页
字号:
    *p = *q++;
    p++;
  }
  
 /* p = (uint *)temperature_value;
  q = (uint *)etemperature_value;
  for (i=0; i<13; i++) 
  {
    *p = *q++;
    p++;
  }
  
  p = oil_temperature_data;
  q = eoil_temperature_data;
  for (i=0; i<26; i++) 
  {
    *p = *q++;
    p++;
  }

  p = gas_temperature_data;
  q = egas_temperature_data;
  for (i=0; i<26; i++) 
  {
    *p = *q++;
    p++;
  }   */
  
  p = rotation;
  q = erotation;
  for (i=0; i<10; i++) 
  {
    *p = *q++;
    p++;
  }

  p = position;
  q = eposition;
  for (i=0; i<10; i++) 
  {
    *p = *q++;
    p++;
  }

  p = &egr[0][0];
  q = &eegr[0][0];
  for (i=0; i<200; i++) 
  {
    *p = *q++;
    p++;
  }

  stksp = nrm.rksp1;
  stksi = nrm.rksi1;
  stksd = nrm.rksd1;
  
  inbufsign = 0;
  inbufful = 0;
  inlast = inbuf;
  getlast = inbuf;
  
  if(power_on != 0xab)
  {
    power_on = 0xab;
    limt1 = oil.lmt1;
  }
}

/****************************************************************************
* 函数名称:write_eeprom()																												
* 函数功能:写EEPROM																													
* 入口参数:*data 待写数据地址指针,count 数据个数																																
* 出口参数:DONE:successful ERROR:losed																																
****************************************************************************/
uchar write_eeprom(uint *edata, const uint *data, uchar count)
{
  uint *darr = edata; 
  const uint *sarr = data;
  uchar con = count;
  
  //uint data1 = 0;
  //uint data2 = 0;
  uchar eflag = 0; //1:write completed
  uchar errtimes = 0;  //errer times
  uchar i;
  again:while(errtimes < 2)
  {
    while(eflag == 0)
    {
      if(((uint)darr | 0xfffc) == 0xfffc)  //the last two bits of address is 00
      {
        data1 = *sarr++;
        if(count == 1)
        {
          darr++;
          data2 = *darr;
          darr--; 
          count--;
        }
        else
        {
          data2 = *sarr++;
          count--;
          count--;
        }
      }
      if(((uint)darr & 0x0003)  == 0x0002) //the last two bits of address is 10
      {
        darr--;
        data1 = *darr;
        data2 = *sarr++;
        count--;
      }
      if(((uint)darr & 0x0001) == 0x0001)  //invlid address
      {
        return(ERROR);
      }
    
      while(ESTAT_CBEIF == 0);
      *darr++ = data1;
      ECMD = 0x60;  //modify
      ESTAT_CBEIF = 1;
      
      if(ESTAT_ACCERR == 1 || ESTAT_PVIOL == 1)
      {
        ESTAT_ACCERR = 1;
        ESTAT_PVIOL = 1;
        errtimes++;
        goto again;
      }
  
      while(ESTAT_CBEIF == 0);
     
      *darr++ = data2;
      ECMD = 0x20;  //program
      ESTAT_CBEIF = 1;
    
      if(ESTAT_ACCERR == 1 || ESTAT_PVIOL == 1)
      {
        ESTAT_ACCERR = 1;
        ESTAT_PVIOL = 1;
        errtimes++;
        goto again;
      }
      
      if(count == 0)
      {
        while(ESTAT_CCIF == 0);
        eflag = 1;
      }
    } /*end while*/
  
    //verify
    darr = edata;
    sarr = data;
    for(i=0; i<con; i++)
    {
      if(*darr != *sarr)
      {
        errtimes++;
        goto again;
      }
      darr++;
      sarr++;
    }
    
    return(DONE);
  }
  return(ERROR);
}
/****************************************************************************
* 函数名称:init_eepara()																												
* 函数功能:EEPROM parameter初始化:模式3参数、油量转速限制																												
* 入口参数:无																																
* 出口参数:无																																
****************************************************************************/
void init_eepara(void)
{
  while((write_eeprom(&enrm.rksp,MODE3_NRM,MODE3NI) == ERROR)  
     || (write_eeprom(&emax.rksp,MODE3_MAX,MODE3NI) == ERROR) 
     || (write_eeprom(&emin.rksp,MODE3_MIN,MODE3NI) == ERROR) 
     || (write_eeprom(&eoil.lmt1,MODE7_OILLM,MODE7NI) == ERROR) 
     || (write_eeprom(&erot.lmt1,MODE7_ROTLM,MODE7NI) == ERROR)
     || (write_eeprom((uint *)etemperature_value,(uint *)TEMPERATURE,13) == ERROR)
     || (write_eeprom(eoil_temperature_data,WO_TEMPERATURE,26) == ERROR)
     || (write_eeprom(egas_temperature_data,GAS_TEMPERATURE,26) == ERROR)
     || (write_eeprom(erotation,ROTATION,10) == ERROR)
     || (write_eeprom(eposition,POSITION,10) == ERROR)
     || (write_eeprom(&eegr[0][0],&EGR[0][0],100) == ERROR))
  {
    PORTB_BIT2 = 0;//light led3,indicate eeprom is not initilized properly!
  }
  //while(write_eeprom(&emax.rksp,(uint *)mode3_init_max,MODE3NI) == 0);
  //while(write_eeprom(&emin.rksp,(uint *)mode3_init_min,MODE3NI) == 0);
  //while(write_eeprom(&eoil.lmt1,(uint *)mode7_oillm,MODE7NI) == 0);
  //while(write_eeprom(&erot.lmt1,(uint *)mode7_rotlm,MODE7NI) == 0);
}
/****************************************************************************
* 函数名称:init_ect()																												
* 函数功能:ECT初始化																													
* 入口参数:无																																
* 出口参数:无																																
*****************************************************************************/
void init_ect(void) 
{
  TIOS = 0x00;   //all channels act as input capture
  TSCR1_TEN = 1; //enable main counter
  //TSCR1_TFFCA = 1;  //
  TSCR2 = 0x03;  //prescaler factor = 8,so f(main_counter) = 8/8 = 1MHz
  //TSCR2 = 0x04;  //prescaler factor = 16,so f(main_counter) = 8/16 = 0.5MHz
  TCTL3 = 0x00;  //disable channel4-7 capture 
  TCTL4 = 0x05;  //disable channel2-3 capture,channel0-1 
                 //capture on the rising edges only
  TIE = 0x00;    //disable interrupt
  ICOVW = 0x03;  //no input capture overwrite
  //HPRIO = 0xde;  //set overflow interrupt highest priority
}

/****************************************************************************
* 函数名称:init_cop()																												
* 函数功能:COP watchdog初始化																													
* 入口参数:无																																
* 出口参数:无																																
*****************************************************************************/
void init_cop(void) 
{
  //COPCTL = 0x07;  //t(COP) = 2^24/4*10^(-6) = 4.196s
  //COPCTL = 0x02;  //t(COP) = 2^16/4*10^(-6) = 16ms
  COPCTL = 0x06;  //t(COP) = 2^22/4*10^(-6) = 1.024s
}

/****************************************************************************
* 函数名称:init_rti()																												
* 函数功能:RTI初始化																													
* 入口参数:无																																
* 出口参数:无																																
*****************************************************************************/
void init_rti(void) 
{
  RTICTL = 0x15;//t(RTI) = 4*2^10/4.1943*10(-3) = 1ms 
  //RTICTL = 0x7f; //t(RTI) = 250ms
  CRGINT_RTIE = 1;  //RTI enable
}

/****************************************************************************
* 函数名称:init_pll()																												
* 函数功能:PLL初始化																													
* 入口参数:无																																
* 出口参数:无																																
*****************************************************************************/
void init_pll(void) 
{
  REFDV = 9;
  SYNR = 18;   //PLLCLK = 2*f(OSC)*(SYNR+1)/(REFDV+1) = 16Mhz;
  while(CRGFLG_LOCK == 0);
  CLKSEL_PLLSEL = 1;     
}

/****************************************************************************
* 函数名称:init_sci()																												
* 函数功能:串口初始化																													
* 入口参数:无																																
* 出口参数:无																																
*****************************************************************************/
void init_sci(void)
{
  unsigned char clear;
  SCI0BDH = 0x00;						 //baud rate: 9600
  SCI0BDL = 52;//3M_20;//8M_52;
  SCI0CR1 = 0x00;            //start,8 data,stop,
  SCI0CR2 = SCI0CR2_TE_MASK+SCI0CR2_RE_MASK+SCI0CR2_RIE_MASK;//enable send and receive
  
  clear = SCI0SR1;//clear TDRE flag. step 1:read SCI0SR1;
                   //step 2:write to SCI0DRL
}

/****************************************************************************
* 函数名称:init_mcu()																												
* 函数功能:MCU硬件初始化																													
* 入口参数:无																																
* 出口参数:无																																
*****************************************************************************/
void init_mcu(void) 
{
  INTCR_IRQEN = 0;  //disable external interrupt
  DDRB = 0xcf;//set Port B Data Direction Register:PB4,PB5输入,其他为输出
  //DDRE = DDRE & 0xf0 | 0x10; //set Port E Data Direction Register 
  PEAR = 0x00;  //PE4 is the external E clock pin
  //INITEE = 0x21;
  PORTB = PORTB & 0xf0;		//light leds
  delay();
  //delay();
  //delay();
  //delay();
  //delay();
  //delay();  
  PORTB = PORTB | 0x0f;		//turn down leds
  pre_tc0 = TC0;
  //HPRIO = 0xf0; //set rti interrupt to the highest priority 
  HPRIO = 0xd6; //set sci interrupt to the highest priority 
  //PORTB_BIT6 = 1;
}

/****************************************************************************
* 函数名称:init_atd()																												
* 函数功能:ATD初始化																													
* 入口参数:无																																
* 出口参数:无																																
*****************************************************************************/
void init_atd(void) 
{
    				//Power up;ATD fast flag clear;Halt conversion during wait mode;
  ATD0CTL2 = 0xe0; //Ddiable external trigger mode
//ATD0CTL3 = 0x23;//4 times conversions per sequence;non-FIFO;Freeze immediately
  ATD0CTL4 = 0x01; //10 Bit;Prescale value = 4,so f(ATD) = 8/4Mhz
  								//Right justified;Unsigned;Single Conversion Sequence;
  //atdctl5 = 0x80; //Sample only one channel
}

/****************************************************************************
* 函数名称:init_pwm()																												
* 函数功能:PWM初始化																													
* 入口参数:无																																
* 出口参数:无																																
*****************************************************************************/
void init_pwm(void) 
{
  PWME = PWME | 0xaa;    //PWME = 1x1x1x1x,PWM channel 1,3,5,7 is enabled
  PWMCTL = PWMCTL | 0xf0;//pwm concatenate enable
  PWMPOL = PWMPOL | 0xaa;//PWM output is high firstly
  PWMCAE = PWMCAE & 0x55;//left aligned
  PWMCLK = PWMCLK & 0x55;//select clock A,B as the channels' clock q
  PWMPRCLK = 0x11; //clock A,B = bus clock/2
  PWMPER01 = 6666; //f(PWM) = f(bus)/PWMPRCLK/PWMPERx = 600Hz;f(bus) = 16/2MHz
  PWMPER23 = 6666; //PWM) = 600Hz
  PWMPER45 = 6666; //f(PWM) = 600Hz
  PWMPER67 = 6666; //f(PWM) = 600Hz
  PWMDTY01 = 1; //initial DUTY = 50%
  PWMDTY23 = 1; //initial DUTY = 50%
  PWMDTY45 = 1; //initial DUTY = 50%
  PWMDTY67 = 1; //initial DUTY = 50%
}

/****************************************************************************
* 函数名称:init_eeprom()																												
* 函数功能:EEPROM初始化																													
* 入口参数:无																																
* 出口参数:无																																
*****************************************************************************/
void init_eeprom(void)
{
  ECLKDIV = 0x16;  //eclk = 182khz
  ECNFG = 0x00;  //no interrupt
  EPROT_EPOPEN = 1; //no protection
  EPROT_EPDIS = 1; 
}
/****************************************************************************
* 函数名称:atd_conversion()																												
* 函数功能:ATD转换函数																													
* 入口参数:uchar channel 待转换通道	times,转换次数/conversion sequence																															
* 出口参数:uint ATD_result 10位AD转换结果																																
*****************************************************************************/
uint atd_conversion(uchar channel,uchar times)
{										 
  uint atd_result = 0;
  switch(times)
  {
    case 4:
      ATD0CTL3 = 0x20;
      ATD0CTL5 = ATDCTL5 | channel;//start the ATD conversion;
      break;
    case 2:
      ATD0CTL3 = 0x10;
      ATD0CTL5 = ATDCTL5 | channel;//start the ATD conversion;
      break;
    case 1:
      ATD0CTL3 = 0x08;  
      ATD0CTL5 = ATDCTL5 | channel;//start the ATD conversion;
      break;
    default:
      break; 
  }
  while(!(ATD0STAT0 & 0x80));  //wait until ATD SCF = 1
  switch(times)
  {
    case 4:
      atd_result = (ATD0DR0 + ATD0DR1 + ATD0DR2 + ATD0DR3)/4;//取平均值
      break;
    case 2:
      atd_result = (ATD0DR0 + ATD0DR1)/2;
      break;
    case 1:
      atd_result = ATD0DR0;
      break;
    default:
      break; 
  }
  return(atd_result);
} 
 
/****************************************************************************
* 函数名称:open_ovrot()																												
* 函数功能:打开超保																													
* 入口参数:无																																
* 出口参数:无																																
*****************************************************************************/
void open_ovrot(void) 
{
  while(!(PORTE_BIT0==1 && PORTE_BIT1==1)) 
  {
    PORTB_BIT7 = 1;//Generates two pulse
    delay(); //delay about 5ms
    PORTB_BIT7 = 0;
    delay(); //delay about 5ms
  } /* end while */
}

/****************************************************************************
* 函数名称:set_flags()																												
* 函数功能:设置众标志字																													
* 入口参数:无																																
* 出口参数:无																																
*****************************************************************************/
void set_flags() 
{
    /* check the main or sub. rotation ,and set the flags */
  if(PTIT_PTIT6 == 0)
  {
    no_mrot_flag = 1;   //if no main rotation,set the flag
  }
  else
  {
    no_mrot_flag = 0;   //clear
  }  
  
  if(PTIT_PTIT7 == 0)
  {
    no_srot_flag = 1;   //if no sub rotation,set the flag
  }
  else
  {
    no_srot_flag = 0;   //clear
  }  
  
  //check the protect port and set the flags 
  if(PORTE_BIT2 == 0)
  {
    no_rot_flag = 1;  //no rotation,so set the flag
    PORTB_BIT1 = 0;      //light led2,indicate no rotation
    set_rot = LROT;      //启动转速
    set_exe = min.rliml; //最小油量
    fb_rot = 0;
    coun3 = INTIMES;
  }
  else
  {
    PORTB_BIT1 = 1;    //turn down led2
    no_rot_flag = 0;  //clear
  }  
  
  if(PORTE_BIT1 == 0)
  {
    first_ovrot_flag = 1;//first over rotation,so set the flag   
  }
  else
  {
    first_ovrot_flag = 0;//clear
  }  
  
  if(PORTE_BIT0 ==0)
  {
    second_ovrot_flag = 1;//second over rotation,so set the flag
    //PORTA_BIT4 = 1;    //relay1输出
    if(ovslc-- == 0) 
    {
      ovslc = OVSLCN;
      PORTB_BIT3 = ~PORTB_BIT3;
    }
  }
  else
  {
    second_ovrot_flag = 0;//clear
  }
    
    /*4 channels I/O input check and set the corresponding flags */
  if(PORTA_BIT0 == 0)   //按钮1:测试
  {
    delay(); //delay 5ms,prevent twitter
    if(PORTA_BIT0 == 0)
    {
      PORTB_BIT6 = 1;   //disable no rotation protection

⌨️ 快捷键说明

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