www.pudn.com > DCL.rar > DCL.c


/*                            PIC16F73 
                          ---------------- 
                        -|1         RB7 28|- (加热) 
       IGBT Temperature -|2 RA0     RB6 27|- (弱加热) 
                Voltage -|3 RA1     RB5 26|- (保温) 
       REAL Temperature -|4 RA2     RB4 25|- (关机) 
                Current -|5 RA3     RB3 24|- Beep 
                        -|6 RA4     RB2 23|- 
                        -|7 RA5     RB1 22|- Test Plus 
                        -|8         RB0 21|- (中断) 
                        -|9             20|- 
                        -|10            19|- 
                        -|11 RC0    RC7 18|- 
             PWM Output -|12 RC1    RC6 17|- 
            Capture/Fan -|13 RC2    RC5 16|- 
                        -|14 RC3    RC4 15|- 
                          ---------------- 
 
*/ 
 
 
//包括的头文件 
#include  
#include  
 
 
//定义 
#define uchar unsigned char 
#define uint unsigned int 
#define bPLUS          RB1                                         //发试探脉冲的管脚 
#define bBEEP          RB3 
 
#define bSDATA         RC7                                         //SER 
#define bSDCLK         RC5                                         //SRCLK 
#define bSCLK          RC6                                         //RCLK 
 
#define Turnoff_PWM_Output() {CCP2CON &= 0x0F0; T2CON &= 0x0FB;}   //停止PWM的输出 
#define Low_PWM_Output() {  RC1 = 0; bPLUS = 0;}                   //并把PWM管脚拉低 
#define High_Test_Output() {bPLUS = 1;}                            //把测试脉冲管脚电平拉高 
#define Open_Fan() { RC4 = 1;}                                     //打开风扇 
#define Turnoff_Fan() { RC4 = 0;}                                  //关闭风扇 
 
#define DEFus           252 
#define DEF20us         225 
#define DEF10ms         61 
#define PLUSCOUNT       3 
#define TRUE            1 
#define FALSE           0 
#define MAXPLUSNUM      12 
#define MINIREAD        15 
#define IPOINTS         5 
 
#define TMR1LOW         0X78 
#define TMR1HIGH        0X0ec 
 
#define T3RESTTIME      3      //300W时,工作3秒,休息5秒 
#define T3WORKTIME      2 
 
#define T6WORKTIME      4      //600W时,工作6秒,休息2秒 
#define T6RESTTIME      1 
 
 
#define gate_Voltage    0X88    //电压AD转化通道选择 
#define gate_Current    0X98    //电流AD转化通道选择 
#define gate_Pan_Warm   0X90    //锅底温度AD转化通道选择 
#define gate_IGBT_Warm  0X80    //IGBT温度AD转化通道选择 
#define gate_Key        0X0a0   //按键AD转化通道选择 
 
#define switchTURNOFF   0x10 
#define switchKEEPWARM  0x20 
#define switchWEAKWARM  0x40 
#define switchCOOKING   0x80 
#define switchSHIELD    0x0F0 
 
#define PWM_period      0x0a0                       //PWM的周期 
 
void Send_Test_Plus(void);                         //发脉冲宽度为6us的试探脉冲 
void Send_IGBT_Plus(unsigned int PWM_hi);         //发IGBT的驱动脉冲,是PWM的正脉冲宽度 
void Check_Machine_Wave(void);                     //发出试探脉冲后,检测机器返回的振荡波 
void interrupt INT_Service_Prog(void);             //中断服务程序 
void PIC_Timer(uchar uKind,uchar uNum);             //定时程序 
void Mcu_init(void);                               //单片机初始话程序 
void Power_control(uchar iPower);                   //功率档位控制,间隙工作,连续工作 
void DISPLAY1(uchar shu1, uchar shu2);              //显示子程序 
void Display(void);                                 //显示档位,错误代码 
void Judge_Switch_State(void);                      //中断后,对开关状态进行判断 
void Read_Switch_State(void);                       //读开关状态,如与档位不一样,立即中断 
void Power_adjust(void);                            //功率控制,与工作档位有关,连续工作,间隙工作 
void work_condition_check(void);                    //对工作条件进行检测,主要是电压,温度传感器 
void Voltage_check(void);                           //在电磁炉工作的情况下,测试电压,查表得出电流,以横功率 
uchar ad_out(uchar uchannel);                        //AD转化子程序,参数是各AD通道的选择 
 
 
//定义标志位 
bit  gTimerOver;      //定时器Tmr0定时是否结束,1:Yes,0:No 
bit  gWorkNow;        //间隙工作模式下,是否在工作,1:Yes,0:No 
bit  bDCLoff;         //电磁炉关机标志,用于关机后1MIN延时,然后等待 
bit  bDCLon;          //用在打开加热档的一个标志 
bit  bSwitch;         //用在读开关状态的标志,发现开关状态与工作档位不一样,置标志,延时5MS,在读一次 
bit  bKeyChange;      //多个循环标志,若开关状态改变,产生中断,置标志,这样,主程序中的某些循环条件就不满足了 
bit  bNopan;          //无锅标志,在发试探脉冲后,检测到无锅 
bit  bLVoltage;       //检测到电压太低标志 
bit  bHVoltage0;      //检测到电压太高标志0 
bit  bHVoltage1;      //检测到电压太高标志1 
bit  bHpan_tem;       //检测到锅底温度太高的标志 
bit  bHigbt_tem;      //检测到IGBT温度太高的标志 
bit  bL_Current;      //检测到电流太小的标志,是无锅状态 
bit  bH_Current;      //检测到电流太大的标志,是电路故障 
bit  bProtect0;       //用在条件的子程序中,如果在条件检测时,发生有错误,置标志 
bit  bProtect1;       //在检测电流过程中,电流过大或过小,置标志 
bit  bErro;           //只要有一个错误发生,就关机,去不断检测条件 
 
uchar gDoCircle;      //是否持续工作 
uchar gTimerDur;      //定义20us延时,还是10ms延时 
uchar gTimerNum;      //定义延时的时间因子 
uchar gPlusNum;       //定义在取试探脉冲时,多少个就可以满足要求 
uchar gPlusNo;        //用于数组的下标 
uchar gRevPlus;       //表示发出试探脉冲后,机器返回的脉冲个数 
uchar gOldSwitch;     //开关原来的状态 
uchar gNowSwitch;     //开关现在的状态 
uchar iPower;         //功率档的标志,1关机,8加热,4弱加热,2保温 
uchar uWorkTime;      //间隙工作时,工作的时间 
uchar uRestTime;      //间隙工作时,休息的时间 
uchar bCirCndit;      //在条件检测过程中,每次只检测哪一个的标志 
uchar x,a;              //横功率控制,查表用的下标 
uchar d01ms,d10ms,d100ms,d01s,d60s,d01h;            //中断的时间单元 
uchar t1s,w,t750ms,t10ms,t1ms,t120ms,t2s,t3s,t01s;  //程序控制中需用的时间 
 
uint  PWM_hi;                                       //PWM的占空比 
uint gCPLZ[PLUSCOUNT];                              //此数组用于记录捕获到的信号的时间量 
union tUNION                                       //定义了一个联合体 
{ 
    uint iX; 
    uchar uY[2]; 
}gCAPU; 
 
 
//调试中,显示用 
//0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f 
const unsigned char table[20]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0X07,0x7F, 
                        0x6F,0x77,0x7C,0x58,0x5E,0x79,0x71,0x7f,0xbf,0x89,0xff}; 
 
const unsigned char current_table[22]={0x52,0x4F,0x4B,0x49,0x46,0x44,0x41,0x3F, 
                        0x3D,0x3A,0x38,0x3F,0x3D,0x3A,0x38,0x36,0x34,0x32,0x30, 
                        0x2E,0x2C,0x2A}; 
 
//程序开始了... 
void main(void) 
{ 
   uchar uAD; 
   uint  iRecordVoltage,u,u1,uHi1,ss1; 
   uchar uNum; 
   uchar uAD2,uAD0,uADy; 
   uchar j,p,t,i; 
   uint  uUad  ; 
 
   Mcu_init(); 
 
   bBEEP=1;                                  //蜂鸣器长叫一声。时间2秒 
   t3s = 0; 
   while(t3s<2); 
   bBEEP=0; 
 
   INTF = 1;                                 // 强行中断,读开关状态,与00比较 
   gOldSwitch = 0x00;                        //开关的初始状态为0 
 
 
  while(1) 
  { 
 
    if(bKeyChange == 1)                      //开关状态改变 
    { 
        bKeyChange = 0 ; 
 
        Turnoff_PWM_Output();                //关闭PWM的输出 
        Low_PWM_Output();                    //PWM管脚拉低 
 
        for(j=256;j>0;j--);                  //延时一会 
 
        Judge_Switch_State();                //判开关的状态 
 
        gWorkNow=0;                          //确保在切换开关后,能马上工作起来 
        t1s=20;                              //间隙工作时,马上工作的条件 
     } 
 
 
    if(RB2==0)                               //显示 
    {  Display(); } 
 
 
    if(bDCLoff == 1)                         //关机动作,风扇再工作一分钟 
    { 
       Turnoff_PWM_Output();                  //关闭PWM的输出 
       Low_PWM_Output();                      //PWM管脚拉低 
 
 
       t2s=0;                                 //延时一分钟 
       while((bKeyChange == 0)&&(t2s<90)) 
       {    Read_Switch_State();     }        //要不断的去读开关状态 
 
       Turnoff_Fan();                         //关闭风扇 
 
       while(bKeyChange == 0)                 //已关机,风扇已工作了,等待开机 
       { 
          Read_Switch_State();                 //要不断的去读开关状态 
 
          if(RB2==1)                           //显示 
          {  Display(); } 
 
       } 
 
    } 
 
 
    if(iPower==1) 
     { Turnoff_Fan();  }                       //关闭风扇 
    else 
     { Open_Fan();     }                       //打开风扇 
 
 
    while(bKeyChange == 0)                   //功率控制 
    { 
      if(RB2==0) 
      {  Display(); } 
 
      Read_Switch_State();                              //读开关状态 
 
      work_condition_check();                           //条件检测 
 
      if((bProtect0==1)||(bProtect1==1)||(bNopan==1))   //发生错误,置标志,推出循环 
      { bErro=1;  break; } 
      else 
        bErro=0; 
 
      Power_control(iPower);                             //工作状态控制 
 
      if((iPower==8)||(gWorkNow == 1))                   //横功率控制 
      { 
          if(t01s>9)                                    //工作后,延时等待在检测 
         { t01s=10; 
           Voltage_check();                              //检测电压 
           Power_adjust();                               //检测电流,查表调整PWM 
         } 
      } 
 
    } 
 
 
    if(bErro==1)                                         //发生错误,进行处理 
    { 
       Turnoff_PWM_Output();                             //关闭PWM的输出 
       Low_PWM_Output();                                 //PWM输出低电平 
 
       while(1) 
       { 
          if(RB2==0)                                     //显示 
          {  Display(); } 
 
          bBEEP =1;                                      //蜂鸣器报警 
          bProtect1=0; 
 
          Read_Switch_State();                           //读开关状态 
          if(bKeyChange == 1)                            //开关状态改变,退出 
          { bErro =0; 
            bBEEP =0; 
            break; 
 
          } 
 
 
          if(bH_Current==1)                              //对电流太大进行处理 
          { bH_Current=0; 
            t2s=0; 
            while(t2s<2);                                //延时2秒,退出处理程序,再去检查 
            bBEEP =0;                                     //关蜂鸣器,取消错误标志 
            bErro =0; 
 
            gWorkNow=0;                                   //确保在工作条件满足后,能马上工作起来 
            t1s=20; 
            bDCLon=0; 
            PWM_hi=0x0c0; 
 
            break; 
          } 
 
 
          if((bL_Current==1)||(bNopan==1))               //对无锅进行处理 
          {  t2s=0; 
             while(t2s<1); 
 
             Check_Machine_Wave();                       //发试探脉冲,检测返回个数 
             if(gRevPlus >= MAXPLUSNUM)                  //如果测试到的脉冲数大于预先设定的脉冲数 
                bNopan=1;                                //则认为无锅 
             else 
                bNopan=0; 
           } 
 
 
          if(bProtect0==1)                                //对温度传感器或电压错误进行处理 
          { work_condition_check();        } 
 
 
          if((bProtect0==0)&&(bNopan==0))                //条件正常,退出 
          { bErro =0; 
            bBEEP =0; 
 
            gWorkNow=0;                                  //确保在工作条件满足后,能马上工作起来 
            t1s=20; 
            bDCLon=0; 
            PWM_hi=0x0c0; 
 
            break; 
          } 
 
 
 
       } 
 
     } 
 
  } 
 
} 
 
 
 
//开关状态改变 
void Judge_Switch_State(void) 
{ 
   gOldSwitch = gNowSwitch;                                     //承认开关状态改变,更新开关状态 
 
   bSwitch = 0 ;                                                //清在读开关状态过程中,发现开关状态与档位不一样时,置的标志 
 
   if((gNowSwitch & switchTURNOFF) == switchTURNOFF)            //是关机状态 
        iPower = 1 ;                                            //定义开关状态单元 
 
   else if((gNowSwitch & switchCOOKING) == switchCOOKING)       //是保温状态 
    {   iPower = 2 ;                                             //定义开关状态单元 
        uWorkTime = T3WORKTIME;                                  //给工作,休息时间赋初值 
        uRestTime = T3RESTTIME; 
    } 
 
   else if((gNowSwitch & switchWEAKWARM) == switchWEAKWARM)     //是弱加热状态 
    {   iPower = 4 ;                                             //定义开关状态单元 
        uWorkTime = T6WORKTIME;                                  //给工作,休息时间赋初值 
        uRestTime = T6RESTTIME; 
    } 
 
   else if ((gNowSwitch & switchKEEPWARM) == switchKEEPWARM)    //是加热状态 
    {   iPower = 8; 
        bDCLon = 0;                                              //定义开关状态单元,置开始加热标志 
    } 
   else 
    {   asm("nop");    }                                        //出错 
 
   PWM_hi=0x0c0; 
 
   if(iPower ==1)                                               //若是关机,置关机标志 
       bDCLoff = 1; 
   else 
       bDCLoff = 0; 
 
} 
 
 
 
//主要用于判断工作条件是否满足 
//X用于恒功率查表,判断电流用 
void work_condition_check(void) 
{  uchar u,pan_temp,igbt_temp; 
   uchar U_max,U_min,Cpan_max,Cigbt_max; 
 
   if(bErro==1)                          //此处为保护的一些参数设定 
   { U_min=0x93; U_max=0x0ba;            //出错后的参数 
     Cpan_max=0x40; Cigbt_max=0x6a; 
   } 
   else 
   { U_min=0x8d; U_max=0x0c1;            //出错前的参数 
     Cpan_max=0x60; Cigbt_max=0x82; 
   } 
 
   if(bCirCndit==0) 
   {  bCirCndit = 1; 
      u = ad_out(gate_Voltage); 
      if(uU_max) 
        bHVoltage0=1;                       //电压过高保护 
      else 
        bHVoltage0=0; 
    } 
    else if(bCirCndit==1) 
    { bCirCndit = 2; 
      pan_temp  = ad_out(gate_Pan_Warm); 
      if((pan_temp > Cpan_max)||(pan_temp==0)) 
        bHpan_tem=1;                       //锅低温度过高保护 
      else 
        bHpan_tem=0; 
 
      if(pan_temp<0x09) 
         a=0; 
      else if(pan_temp<0x2b) 
         a=1; 
      else if(pan_temp<0x3a) 
         a=2; 
      else if(pan_temp<0x50) 
         a=3; 
      else 
         a=4; 
 
     } 
    else if(bCirCndit==2) 
    { bCirCndit=3 ; 
      igbt_temp = ad_out(gate_IGBT_Warm); 
      if(igbt_temp>Cigbt_max) 
        bHigbt_tem=1;                     //IGBT温度过高保护 
      else 
        bHigbt_tem=0; 
     } 
    else if(bCirCndit==3) 
    { bCirCndit=0; 
      if(RC3==0) 
         bHVoltage1=1; 
      else 
         bHVoltage1=0; 
     } 
    else 
    { bCirCndit = 0; } 
 
   if((bLVoltage==1)||(bHVoltage0==1)||(bHpan_tem==1)||(bHigbt_tem==1)||(bHVoltage1==1)) 
      bProtect0=1;                     //只要发生一个错误,就置错误标志 
   else 
      bProtect0=0; 
 
} 
 
 
void Voltage_check(void) 
{  uchar u; 
   u = ad_out(gate_Voltage); 
   if  (u<0x98)   x=1;                //主要为功率控制查表用 
   else if (u< 0x9c) x=2; 
   else if (u<0x0a0) x=3; 
   else if (u<0x0a4) x=4; 
   else if (u<0x0a8) x=5; 
   else if (u<0x0ac) x=6; 
   else if (u<0x0b0) x=7; 
   else if (u<0x0b4) x=8; 
   else if (u<0x0b8) x=9; 
   else  x=10; 
} 
 
 
//功率调整 
//主要通过电流AD转换和已设定的值进行比较的 
void Power_adjust(void) 
{  uchar i,y,z,Current_AD0,Current_AD1; 
   uint  uHi1,ss1; 
 
   i = ad_out(gate_Current); 
   if(i<0x08)                             //电流过低,属于无锅,需保护 
      bL_Current=1 ; 
   else 
      bL_Current=0; 
 
   if(i>0x8f)                             //电流过高,需保护 
      bH_Current=1 ; 
   else 
      bH_Current=0; 
 
 
   if ((bL_Current==1)||(bH_Current==1)) 
      bProtect1=1;                        //电流过大或过小,都需保护,置标志 
   else 
      bProtect1=0; 
 
   if(iPower==8)                          //给查电流表赋偏移量 
      y=0; 
   else 
      y=11; 
 
   z=x-a;                                 //计算下标 
   if(z<1 ) z=1; 
   if(z>10) z=10; 
 
   z=y+z; 
 
   Current_AD0 = current_table[z-1];      //电流AD转化的下限值 
   Current_AD1 = current_table[z];        //电流AD转化的上限值 
 
   if(i> 2); 
      ss1=uHi1 & 0x0003; 
      CCP2CON |= ((ss1 <<4) & 0x0030);    //CCP2CON<5:4>=0; 
    } 
   else if(i > Current_AD1)              //电流太大 
    { PWM_hi--;                           //减小占空比 
 
      uHi1 = PWM_hi;                      //修改PWM的占空比 
      ss1=uHi1 & 0x03fc; 
      CCPR2L = (ss1 >> 2); 
      ss1=uHi1 & 0x0003; 
      CCP2CON |= ((ss1 <<4) & 0x0030);    //CCP2CON<5:4>=0; 
    } 
   else 
    { asm("nop"); } 
 
} 
 
 
//读开关状态,确保工作状态 
void Read_Switch_State(void) 
{ uchar uSwOne,uSwTwo; 
  uSwTwo = iPower<<4 ; 
  if(bSwitch == 0) 
  {  uSwOne = PORTB & switchSHIELD;          //读开关的值 
    if( uSwOne != uSwTwo)                   //判断是否与原来的值相等 
    {  t10ms = 0 ; 
       bSwitch = 1 ; 
    } 
  } 
  else 
 {  if( t10ms>1 ) 
    {  uSwOne = PORTB & switchSHIELD;       //读开关的值 
       if(uSwOne != uSwTwo)                 //前后两次的值是否相等 
       {  INTF = 1;  }                      //触发中断 
    } 
 
  } 
} 
 
 
//功率控制 
//主要是连续工作,间隙工作,错误状态要关机 
void Power_control(uchar iPower) 
{ uint Pwm_h; 
 
  if(iPower ==1) 
  { 
     if (bDCLoff==0) 
     { 
        Turnoff_PWM_Output();                       //关闭PWM的输出 
        Low_PWM_Output();                           //PWM输出低电平 
        bDCLoff = 1; 
     } 
     else 
     {  asm("nop");  } 
 
  } 
  else if(iPower ==8) 
  { 
     if (bDCLon==0) 
     { 
        Check_Machine_Wave(); 
        if(gRevPlus >= MAXPLUSNUM)                  //如果测试到的脉冲数大于预先设定的脉冲数 
          bNopan=1;                                  //则认为无锅 
        else 
        { Pwm_h = PWM_hi; 
          Send_IGBT_Plus(Pwm_h); 
          t120ms=0;                                  //延时一段时间100ms 
          while(t120ms<11); 
          High_Test_Output(); 
          bDCLon = 1; 
          bNopan = 0; 
 
          t01s=0;                                    //用于电流检测 
        } 
 
      } 
      else 
      {   asm("nop");   } 
   } 
   else if((iPower ==2)||(iPower ==4)) 
   { 
      if(gWorkNow == 1) 
      {                                                  //目前正在工作 
          if( t1s > uWorkTime ) 
          {                                              //工作的定时时间到了 
             gWorkNow = 0;                               //开始休息啦 
             t1s = 0 ; 
             Turnoff_PWM_Output();                       //关闭PWM的输出 
             Low_PWM_Output();                           //PWM输出低电平 
          } 
          else 
          {  asm("nop");  } 
      } 
      else                                              //目前正在休息 
      { 
         if( t1s > uRestTime ) 
         {                                               //休息的定时时间到了 
            gWorkNow = 1;                                //开始工作了 
            t1s = 0; 
 
            Check_Machine_Wave(); 
            if(gRevPlus >= MAXPLUSNUM)                  //如果测试到的脉冲数大于预先设定的脉冲数 
              bNopan=1;                                 //则认为无锅 
            else 
            { Pwm_h = PWM_hi; 
              Send_IGBT_Plus(Pwm_h); 
              t120ms=0;                                 //延时一段时间10ms 
              while(t120ms<11); 
              High_Test_Output(); 
              bNopan = 0; 
 
              t01s=0;                                    //用于电流检测 
            } 
         } 
         else 
         { 
            asm("nop");                                 //继续休息 
         } 
      } 
 
   } 
   else 
   { 
     Turnoff_PWM_Output();                       //关闭PWM的输出 
     Low_PWM_Output();                           //PWM输出低电平 
   } 
 
} 
 
void Display(void) 
{ uchar uADy0,uAD1; 
 
  if( bErro == 0) 
    { if(iPower==1)                           //显示功率档位用 
           uAD1=0; 
       else if(iPower==8)                     //加热档 
           uAD1=1; 
       else if(iPower==4)                     //弱加热档 
           uAD1=2; 
       else if(iPower==2)                     //保温档 
           uAD1=3; 
       else 
           uAD1=4;                             //档位错误,或没接开关 
    } 
  else 
    {  if(bHVoltage0==1)                       //电压太高 
         uAD1=0x0c; 
       else if(bLVoltage==1)                   //电压太低 
         uAD1=0x0b; 
       else if((bL_Current==1)||(bNopan==1))   //无锅 
         uAD1=0x0a; 
       else if(bHigbt_tem==1)                  //IGBT温度太高 
         uAD1=9; 
       else if(bHpan_tem==1)                   //锅底温度太高 
         uAD1=8; 
       else if(bHVoltage1==1)                  //电压太高 
         uAD1=7; 
       else if(bH_Current==1)                  //电流太大,电路有问题 
         uAD1=6; 
       else 
         uAD1=5;                                //控制出现异常情况 
    } 
 
     DISPLAY1(uADy0,uAD1); 
} 
 
//当MCU发出试探脉冲后,检查返回的脉冲个数及频率 
//TMR1是Capture和定时复合用的 
//在使用Capture之前,现保存TMR1的设置值 
void Check_Machine_Wave(void) 
{ 
    uchar uTMRL; 
    uchar uTMRH; 
    uchar uCON; 
 
 
//保存TMR1的设置值 
    uCON = T1CON; 
    TMR1ON = 0; 
    TMR1IF = 0; 
    TMR1IE = 0; 
    uTMRL = TMR1L; 
    uTMRH = TMR1H; 
 
    RC2 = 0; 
    asm("nop"); 
//CCP1,RC2 
//设置RC2为输入管脚 
    TRISC |= 0x04;     //"00000100" 
 
//延时25ms 
    PIC_Timer(3,2); 
    while(gTimerOver != 1); 
 
 
    gPlusNum = PLUSCOUNT;   //需要采取的上升沿个数 
    gPlusNo = 0x00;         //清零 
 
    gRevPlus = 0x00;        //收到的脉冲数清零 
 
    CCP1CON = 0x00; 
    T1CON = 0x00;           //1:1 
    TMR1L = 0; 
    TMR1H = 0; 
 
//设置CCP1CON 
    CCP1IF = 0; 
    CCP1IE = 1; 
    CCP1CON = 0x05; 
    TMR1ON = 1; 
 
//发试探脉冲 
    Send_Test_Plus(); 
 
//定时160us 
    PIC_Timer(2,8); 
 
//当收到的脉冲数等于MAXPLUSNUM时,同时或者定时时间到,退出循环 
    while((gTimerOver == 0) && (gRevPlus < MAXPLUSNUM)); 
 
//不是定时时间到而退出循环的,关闭定时器 
    if(gTimerOver == 0) 
    { 
        T0IE = 0; 
    } 
 
 
 
//关闭捕捉功能 
    CCP1CON = 0x00; 
    CCP1IE = 0; 
    TMR1ON = 0; 
 
//恢复TMR1的值设置 
    TMR1IF = 0; 
    TMR1IE = 1; 
    TMR1L = uTMRL; 
    TMR1H = uTMRH; 
    T1CON = uCON; 
 
    TRISC &= 0x0fb;     //11111011 
    asm("nop"); 
    RC2=1; 
} 
 
#pragma interrupt_level 1 
void interrupt INT_Service_Prog(void) 
{ 
    uint uDelay; 
    uchar uSwOne; 
    uchar uSwTwo; 
 
    if(T0IF == 1)                          //是tmr0中断 
    { 
        T0IF = 0;                          //清楚中断标志 
 
        --gTimerNum;                       //定时个数减一 
        if(gTimerNum == 0)                 //延时时间是否到, 
        { 
           gTimerOver = 1;                 //是,置标志位 
           T0IE = 0;                       //关闭定时器中断 
        } 
        else 
           TMR0 = gTimerDur;               //否,继续置定时器时间常数 
 
    } 
    if(CCP1IF == 1)                        //是capture中断 
    { 
        CCP1IF = 0;                        //清除中断标志 
 
        if(gPlusNum != 0)                  //需要capture的次数是否到了 
        {                                   //没有,记录相关的数据 
            gCAPU.uY[0] = CCPR1L;           //CCPR1L; 
            gCAPU.uY[1] = CCPR1H;           //CCPR1H; 
 
            gCPLZ[gPlusNo] = gCAPU.iX; 
 
            gPlusNo++; 
            gPlusNum--; 
        } 
 
        gRevPlus++;                        //收到的脉冲数加1 
        PIC_Timer(2,8);                    //定时器重新开始定时160us 
    } 
    else if(TMR1IF == 1)                   //是tmr1中断 
    { 
       TMR1IF = 0; 
       TMR1L  = TMR1LOW; 
       TMR1H  = TMR1HIGH; 
       d01ms++; 
       t1ms++; 
       if (d01ms>=10) 
       {  d01ms=0; d10ms++; 
          t750ms++; t10ms++; 
          t120ms++; 
          if(d10ms>=10) 
          {  d10ms=0 ; d100ms++; 
             t01s++; 
 
             if (d100ms>=10) 
             {  d100ms=0;d01s++; 
                t1s++; t2s++; t3s++; 
 
                if (d01s>=60) 
                {  d01s=0; d60s++; 
 
                   if( d60s>=60) 
                   {  d60s=0; d01h++; 
                   } 
                } 
             } 
          } 
       } 
    } 
    else if(INTF == 1)                      //开关状态发生改变 
    { 
        INTF = 0;                            //清除中断标志 
        uSwOne = PORTB & switchSHIELD;       //读开关的值 
        if( uSwOne != gOldSwitch)            //判断是否与原来的值相等 
        { 
            for(uDelay=0;uDelay<300;uDelay++);  //不相等,等待一段时间后,重新读取 
            uSwTwo = PORTB & switchSHIELD; 
            if(uSwOne == uSwTwo)             //前后两次的值是否相等 
            { 
                gNowSwitch = uSwOne;         //如相等,则认为开关状态已经发生变化 
                gDoCircle = FALSE;           //设定重新循环的标志 
                bKeyChange = TRUE ;          //*加热状态改变 
            } 
        } 
    } 
} 
 
 
//uKind = 1,以8us为基准 
//uKind = 2,以20us为基准 
//否则以10ms为基准 
#pragma interrupt_level 1 
void PIC_Timer(uchar uKind,uchar uNum) 
{ 
    T0IF = 0; 
    T0IE = 1; 
//如定时60us,3×20us,为3次 
    gTimerNum = uNum; 
//定时时间到,开始为"0",结束为"1" 
    gTimerOver = 0; 
//不是发试探脉冲定时 
//    gIsPlus = FALSE; 
 
    if(uKind == 1) 
    { 
        OPTION &= 0x0F8; 
        gTimerDur = DEFus; 
    } 
    else if(uKind == 2) 
    { 
        OPTION &= 0x0F8; 
        gTimerDur = DEF20us; 
    } 
    else 
    { 
        OPTION |= 0x07; 
        gTimerDur = DEF10ms; 
    } 
//TMR0的初始值 
    TMR0 = gTimerDur; 
} 
 
 
 
//此函数发试探脉冲 
//试探脉冲的宽度是6us 
void Send_Test_Plus(void) 
{  uchar i; 
   bPLUS = 0; 
   for(i=6;i>0;i--); 
   bPLUS = 1; 
   for(i=2;i>0;i--); 
   bPLUS = 0; 
   for(i=6;i>0;i--); 
} 
 
 
 
void Send_IGBT_Plus(unsigned int PWM_hi) 
{ 
    unsigned int uHi,ss; 
 
    PR2 = PWM_period; 
    uHi = PWM_hi; 
 
    ss=uHi & 0x03fc; 
    CCPR2L = (ss >> 2); 
    ss=uHi & 0x0003; 
    CCP2CON |= ((ss <<4) & 0x0030);    //CCP2CON<5:4>=0; 
 
 
    T2CON = 0x01;       // 1/4 frequency 
 
    CCP2CON |= 0x0C;    //PWM mode 
 
    T2CON |= 0x04;      //打开TMR2 
 
} 
 
uchar ad_out(uchar uchannel) 
{ int iT; 
  ADCON0=uchannel; 
  ADCON0 |=0X01; 
  for(iT=0; iT<60; iT++) ; 
  ADCON0 |= 0X04; 
  asm("NOP"); 
  asm("NOP"); 
  while((ADCON0&0X04)==0X04) ; 
  asm("NOP"); 
  asm("NOP"); 
  ADCON0 &=0X0FE; 
  return(ADRES); 
} 
 
 
void DISPLAY1(uchar shu1, uchar shu2) 
{ char ucdata,ucI,ucshi,ucge; 
 
  ucshi=shu2; 
  ucge =shu2; 
 
  bSDATA = 0; 
  bSDCLK = 0; 
  bSCLK  = 0; 
 
  ucdata=table[ucge]; 
  for(ucI=0;ucI<8;ucI++) 
  {   if (ucdata & 0x80) 
         bSDATA=1; 
      else 
         bSDATA=0; 
 
      asm("NOP"); 
      asm("NOP"); 
 
      bSDCLK=1; 
      asm("NOP"); 
      asm("NOP"); 
      bSDCLK=0; 
 
      ucdata &= 0x07f; 
      ucdata <<= 1; 
   } 
 
 
  ucdata=table[ucshi]; 
  for(ucI=0;ucI<8;ucI++) 
  {   if (ucdata & 0x80) 
         bSDATA=1; 
      else 
         bSDATA=0; 
 
      asm("NOP"); 
      asm("NOP"); 
 
      bSDCLK=1; 
      asm("NOP"); 
      asm("NOP"); 
      bSDCLK=0; 
 
      ucdata &= 0x7f; 
      ucdata <<=1; 
   } 
 
   bSCLK=0; 
   asm("NOP"); 
   asm("NOP"); 
   bSCLK=1; 
 
} 
 
 
void Mcu_init(void) 
{   ADCON1 = 0x00;      //Vref+=VDD,Vref-=VSS,所有的都是A/D口 
                        //87X,10位精度;7X,8位精度 
                        //RA0:IGBT temperature:pin-2 
                        //RA1:Voltage         :pin-3 
                        //RA2:Coil temperature:pin-4 
                        //RA3:Current         :pin-5 
    TRISA = 0x0DF;      //A口全部为输入,用作A/D 
    TRISC = 0X08; 
    TRISB = 0x0F5;      //RB0,RB4,RB5,RB6,RB7 input,others output 
 
    Low_PWM_Output();   //IGBT的驱动脉冲,不工作时为低电平 
                        //测试脉冲为低电平,以防止意外 
 
    T1CON=0X00; 
    PIR1=0X00; 
    INTCON=0X00; 
    TMR1L  = TMR1LOW; 
    TMR1H  = TMR1HIGH; 
    TMR1IE=1; 
 
    INTCON = 0x00; 
    OPTION = 0x0C0;     //RB0/INT上升沿触发, 并禁止弱上拉 
 
    INTE = 1;           //允许外部中断(开关) 
    PEIE = 1;           //允许其他外设中断 
    GIE = 1;            //允许全局中断 
 
    TMR1ON=1; 
 
}