main.c

来自「项目是为日本瑞萨工作所做的BAKE炉温控系统 整个文件夹包括设计文档」· C语言 代码 · 共 357 行

C
357
字号
//-------------------------------------------------------------------------*
//工程文件名:Bake.prj                                                      *
//硬件连接:                                                                *
//  TLC2543的CS,I/O CLOCK,DATA INPUT,DATA OUT分别接PTC0,PTD1~PTD3        *
//  LCD的数据口为PTB0~PTB7,控制口为PTC1~PTC4                              *
//  报警灯:红灯及蜂鸣器、绿灯、黄灯、Bake阀、Cool阀分别接PTA的第0~4脚     *
//  温度电位器、时间电位器、热敏电阻、红外传感器分别接TLC2543的第0~3脚    
//程序描述:由TLC2543采集来的AD值确定设定时间、设定温度、当前温度和         *
//         Cool箱中是否有物体                                              *
//         判断如果Bake炉内温度变化超过设定温度一定范围,则红灯闪并报警    *
//         否则等加热到设定时间后黄灯闪,切掉Bake炉电源,提示取出加热物体  *
//         放入Cool箱,冷却阀闭合,当物体移出Cool箱后,冷却阀断开          *
//日    期:2007.04.25                                                      *
//-------------------------------------------------------------------------*
#include "Includes.h"           //总头文件

//内部函数声明
void LightAlarm(INT8U Light);   //通过不同颜色灯闪,提示进一步操作
INT16U ConvertCT(INT16U adv);   //将AD值转换当前温度
INT16U ConvertT(INT16U adv);    //将AD值转换设定温度
INT16U ConvertTime(INT16U adv); //将AD值转换设定时间
void ReFlash(void);

//主函数
void main()
{
   INT16U InitTime;         //开始计时的基值
   INT16U tmp;
   INT8U i;
   INT16U sum;
  
   //初始化
   DisableMCUInterrupt();   //禁止总中断
   MCUInit();               //芯片初始化
   SCIInit();               //串口初始化
   LCDInit();               //LCD初始化
   Timer1init();            //定时器1初始化,1秒溢出中断
   Timer2Init();            //定时器2初始化,2通道都是下降沿输入捕捉中断
   SPIInit();               //SPI初始化
   LightInit();             //按钮开关灯控制口
   SwitchOutput_Init();     //开关量输出初始化
   EnTm1OverflowInt();      //开放Timer1溢出中断
   EnableSCIReInt();        //开放串行中断

MainLoop:    
   //初始化标志
   StateFlag=1;             //初始状态为1:开绿灯、Bake炉电源
   CoolFlag=0;              //开始工作时,Cool箱中是没物体的
   SendFlag=0;              //需要向PC发显示参数时在串行中断里置1
   FlashFlag1=0;            //需要校准当前温度时在串行中断里置1
   FlashFlag2=0;            //需要修改MCU号时在串行中断里置1
   ResetFlag=0;             //复位按钮没被按下,捕捉中断里置1
   BakeFlag=0;              //Bake炉电源重启开关没被按下,捕捉中断里置1
   
   //初始化全局变量(预防措施)
   ScdTim=0;
   MntTim=0;  //按复位键后计时应清0的!否则可能溢出
   
   EnableMCUInterrupt();    //开放总中断
 
   //主循环
   while(1)
   {
          
     //1 采集A/D值,转换为设定温度、设定时间、当前温度和红外传感器值
     sum=0;
     for(i=0;i<2;i++)
     {
         ADC11P(0,ADValue);
         sum+=ADValue[0];
     }
     sum/=2;
     CurtTmp=ConvertCT(sum);   //第0路为当前温度
       
/*  
     ADC11P(0,ADValue);
     CurtTmp=ConvertCT(ADValue[0]);   //第0路为当前温度
*/   
     Temper=ConvertT(ADValue[1]);     //第1路为设定温度
     Time=ConvertTime(ADValue[2]);    //第2路为设定时间
//Time=1;
     Infrared=ADValue[3];             //第3路为红外传感器的值
     ADCurtTmp=ADValue[0];            //校准当前温度时写flash用


       //2 LCD显示每1s刷新一次
    //将需要显示的各数据转换成LCD可显示的格式,并放入LcdShowBuff中
    InBuff(CurtTmp,Temper,CurtTime,Time,LcdShowBuff); 
    //显示LcdShowBuff中的数据 
    LcdShCh(LcdShowBuff);
    //在Lcd上显示自定义32*16点阵的字符
    LcdShBigNum(0,0,(INT16U *)BigNumCode,CurtTmp);



     //2 将校准参数或MCU号写Flash
     if((FlashFlag1==1) ||(FlashFlag2==1))  //需要将校准值或MCU号写flash
     {  
       ReFlash();
       
       CurtTmp=ConvertCT(sum);   //第0路为当前温度
       LcdShBigNum(0,0,(INT16U *)BigNumCode,CurtTmp);
  
    }
        
     //3 接收到PC读数据的请求就发送显示参数
     if(SendFlag==1)  
     {
     
         SCISend1('S');              //帧头'S'
         SCISend1(CurtTmp>>8);       //当前温度
         SCISend1(CurtTmp);
         SCISend1(Temper>>8);        //设定温度
         SCISend1(Temper);
         SCISend1(CurtTime>>8);      //当前时间
         SCISend1((INT8U)CurtTime);
         SCISend1(Time>>8);          //设定时间
         SCISend1(Time);
         SCISend1(ScdTim);           //当前秒数,供PC显示横坐标刻度
         SCISend1(sum>>8);    //当前温度的AD值
         SCISend1(sum);
         SCISend1('E');              //帧尾'E'
         SendFlag=0;                 //清标志     
     } 





     //4 Bake炉根据不同状态,作不同处理
     switch(StateFlag)
     {
       case 1://状态1:绿灯亮,Bake炉电源接通,其电源指示灯亮
              SwitchOutput(C_GreenLight,1); //系统开始工作后,绿灯常亮
              SwitchOutput(C_BakeSw,1);     //使Bake炉电源接通
              LightOut(1);                  //Bake炉电源指示灯亮
//              BakeFlag=1;
              StateFlag=2;                  //进入状态2
              break;
       case 2://状态2:等待炉内温度达到设定值
              if(CurtTmp>=Temper)   //温度达到设定值
              {
                InitTime=MntTim;    //记录此刻时间,作为加热时间的基值
                StateFlag=3;        //进入状态3
              }
              break;
       case 3://状态3:如果当前炉内温度偏离设定温度过大,则报警提示复位系统
              if(CurtTmp>Temper)    //允许正负偏一定值,tmp为两者的差值
                 tmp=CurtTmp-Temper;
              else
                 tmp=Temper-CurtTmp;
              if(tmp>C_TmpPC)  //如果当前温度与设定温度偏差大于5,作异常处理
              {
                 SwitchOutput(C_BakeSw,0);    //断开Bake炉电源
                 LightOut(0);                 //Bake炉电源指示灯灭
//                 BakeFlag=0;
                 SwitchOutput(C_GreenLight,0);//绿灯灭
                 StateFlag=6;                 //进入状态6
              }
              else 
              {
                 StateFlag=4;                 //无异常,进入状态4
              }   
              break;
       case 4://状态4:如果加热到设定时间,黄灯闪,提示将加热物体拿出放入冷却箱
              CurtTime=MntTim-InitTime;
              if(CurtTime>=Time)     //加热时间到,黄灯闪提示,直到Cool阀开
              {
                 LightAlarm(C_YellowLight);   //断开Bake阀、绿灯灭、黄灯闪
                 StateFlag=5;        //进入状态5
              }
              else
              {   
                 StateFlag=3;        //加热时间未到,回状态3,边判边等
              }   
              break;  
       case 5://状态5:冷却箱中无物体放入,黄灯继续闪
              if(Infrared>C_Exist)
                 StateFlag=4;        //无物体放入,回状态4,黄灯继续闪 
              else
                 StateFlag=7;        //有物体放入,去状态7
              break;
       case 6://状态6:Bake炉内温度异常后红灯报警,直至有复位开关按下
              SwitchOutput(C_RedLight,1);  //红灯亮并报警
              if(ResetFlag==1)             
              {
                 ResetFlag=0;
                 SwitchOutput(C_RedLight,0);
                 goto MainLoop;
              }
              break;
       case 7://状态7:Bake炉加热时间到后,等Bake炉电源重启按钮按下
              if(BakeFlag==1)
              {
                 BakeFlag=0;
                 StateFlag=1;  
              }
              break;
     }//switch
     
     //3 冷却箱的处理
     if(Infrared<=C_Exist && CoolFlag==0)      //从无到有
     {
        SwitchOutput(C_CoolSw,1);              //打开冷却阀
        CoolFlag=1;        //有物体放入置此标志
     }
     else  if(Infrared>C_Exist && CoolFlag==1) //从有到无
     {
        SwitchOutput(C_CoolSw,0);             //关冷却阀
        CoolFlag=0;        //没有物体放入清此标志
     }
 
   }//while    

}


//**************************************************************************
//                              内部函数                                   *
//**************************************************************************

//-------------------------------------------------------------------------*
//函数名:ConvertCT                                                         *
//参  数:AD值                                                              *
//返  回:AD值对应的当前温度                                                *
//功  能:将AD值转换为当前温度                                              *
//-------------------------------------------------------------------------*
INT16U ConvertCT(INT16U adv)
{
     INT8U i;
     INT16U x,y;
     INT32U k,b,tmp;
     for(i=9;i>=0;i--)
     {
         if(ADtoPHY_X[i]!=0 && adv>=ADtoPHY_X[i])
         {
            k=ADtoPHY_k1[i];
            k=k*1000+ADtoPHY_k2[i];
            b=ADtoPHY_b1[i];
            b=b*1000+ADtoPHY_b2[i];
            if(ADtoPHY_b0[i]==0)
              tmp=k*adv+b;
            else 
              tmp=k*adv-b;
            y=tmp/1000; 
          break;
         } 
     }
     return(y);


}
//-------------------------------------------------------------------------*
//函数名:ConvertT                                                          *
//参  数:AD值                                                              *
//返  回:AD值对应的设定温度                                                *
//功  能:将AD值转换为设定温度                                              *
//-------------------------------------------------------------------------*
INT16U ConvertT(INT16U adv)
{
     INT32U tmp;    //32位
     
     tmp=adv; 
     //按线性关系,将AD值范围分为C_TmpBound等分              
     tmp=((tmp*C_TmpBound)/C_RADMax)/10+C_MinTmp;
     return(tmp);      
}
//-------------------------------------------------------------------------*
//函数名:ConvertTime                                                       *
//参  数:AD值                                                              *
//返  回:AD值对应的设定时间                                                *
//功  能:将AD值转换为设定时间                                              *
//-------------------------------------------------------------------------*
INT16U ConvertTime(INT16U adv)
{
     INT32U tmp;  //32位

     tmp=adv; 
     //按线性关系,将AD值范围分为C_TimBound等分         
     tmp=((tmp*C_TimBound)/C_RADMax/10+C_MinTim); 
     return(tmp);      //显示可精确到0.1分,此处计时只精确到1分
/////////////////////////////////////////
//return(2);
//////////////////////////////////////////////////////////     
}

//-------------------------------------------------------------------------*
//函数名:LightAlarm                                                        *
//参  数:无                                                                *
//返  回:无                                                                *
//功  能:切掉Bake炉电源、通过不同颜色灯闪,提示进一步操作                  *
//-------------------------------------------------------------------------*
void LightAlarm(INT8U Light)
{
   INT8U  i,j;
   
   //Bake炉内温度异常,切掉Bake炉电源,指示灯灭
   SwitchOutput(C_BakeSw,0);
   LightOut(0);
//   BakeFlag=0;
   
   //绿灯灭
   SwitchOutput(C_GreenLight,0);
   
   //灯亮
   SwitchOutput(Light,1);
         
   //延时
   for(i=0;i<200;i++)
      for(j=0;j<200;j++);
          
   //灯灭
   SwitchOutput(Light,0);
         
   //延时
   for(i=0;i<200;i++)
      for(j=0;j<200;j++);
}


//校准当前温度,或修改MCU号,写flash函数
void ReFlash(void)
{
   INT8U RecvFlash[112];
   INT8U i,j;
  
   
   //校准当前温度
   if(FlashFlag1==1)                 
   {           
        DisableMCUInterrupt();   //擦些Flash时要关中断
        FLBPR=0b11111111;     //不保护FLASH区域
        EraseFlash(0x8080); //擦除0x8000为始址的一个页
        FLBPR=0b11111111;     //不保护FLASH区域
        WriteFlash(0x8080); //将FlashData[8]数组的8个数据写入0x8000为始址的一个页
        EnableMCUInterrupt();
        
        SCISendN(110,(INT8U *)0x8080);  
        FlashFlag1=0;
   }
    
   //修改MCU号
   if(FlashFlag2==1)      
   {
        FlashData[0]=NewMCUno;        //PC发来的新MCU号    
        FlashFlag2=0;
    
        N=1;
        DisableMCUInterrupt();   //擦些Flash时要关中断
        EraseFlash(0x8000); //擦除0x8000为始址的一个页
        WriteFlash(0x8000); //将FlashData[8]数组的8个数据写入0x8000为始址的一个页
        EnableMCUInterrupt();
   }
   
}

⌨️ 快捷键说明

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