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 + -
显示快捷键?