📄 temperature_control.c
字号:
#include <AT89X51.H>
unsigned char display_code[10]={~0x3f,~0x06,~0x5b,~0x4f,~0x66,~0x6d,~0x7d,~0x07,~0x7f,~0x67};
unsigned char display_buffer[4];
bit set=0;
bit pid_allow=0;
sbit eoc=P3^3;
sbit oe=P3^2;
sbit st=P3^4;
sbit k1=P2^4;
sbit k2=P2^5;
sbit k3=P2^6;
sbit k4=P2^7;
sbit light=P3^6;
sbit heal=P3^7;
unsigned char i=0;
float t,t_now,tout=100,t_diff=0,t_target=60,temp=0;
unsigned int k=5000;
int ttemp1=0;
unsigned char ttemp2=0,ttemp3=1;
float KP=28,KI=2.5;
void display(void); //数码管显示
void adc0809(void); //AD转换
void pid(void); //pid控制量计算
void p_out(void); //输出控制
void main()
{
TMOD=0x11;
TL0=(65536-3000)%256;
TH0=(65536-3000)/256;
TL1=(65536-40000)%256;
TH1=(65536-40000)/256;
EA=1;
ET0=1;
ET1=1;
TR0=1;
TR1=1;
light=0;
heal=1;
while(1)
{
display_buffer[0]=(unsigned char)t_now/10; //刷新显示
display_buffer[1]=(unsigned char)t_now%10;
display_buffer[2]=(unsigned char)t_target/10;
display_buffer[3]=(unsigned char)t_target%10;
if(set==0) //按键扫描
{
if(k1==0) //复位
{
while(k--);
if(k1==0){t_target=40;}
}
if(k2==0) //目标温度+1
{
while(k--);
if(k2==0){if((t_target++)>=90)t_target=90;}
}
if(k3==0) //目标温度-1
{
while(k--);
if(k3==0){if((t_target--)<=40)t_target=40;}
}
if(k4==0) //开始工作
{
while(k--);
if(k4==0){pid_allow=1;set=1;light=1;}
}
}
else if(set==1)
{
if(k1==0) //停止,复位
{
while(k--);
if(k1==0){t_target=40;light=0;set=0;heal=1;tout=0;temp=0;tout=100;t_diff=0;}
}
}
}
}
/****************************************************
函数:定时器0中断程序
功能:3000uS中断一回,对数码管进行显示
*****************************************************/
void time0() interrupt 1 using 0
{
TL0=(65536-3000)%256;
TH0=(65536-3000)/256;
display();
}
/****************************************************
函数:定时器1中断程序
功能:40000uS中断一回,进行AD转换,控制输出量
*****************************************************/
void time1() interrupt 3 using 0
{
TL1=(65536-40000)%256;
TH1=(65536-40000)/256;
adc0809();
// if(pid_allow==1)
if((pid_allow==1)&&(t_target-t_now<=5))
{
pid_allow=0;
pid();
}
if(set==1)
{
if((ttemp1++)==500)
{
ttemp1=0;
pid_allow=1;
}
p_out();
}
}
/****************************************************
函数:中断中对动态扫描刷新函数
*****************************************************/
void display(void)
{
if(i==0)P2=0xfe;
if(i==1)P2=0xfd;
if(i==2)P2=0xfb;
if(i==3)P2=0xf7;
P0=display_code[(display_buffer[i])];
i++ ;
if( i>3) i=0;
}
/****************************************************
函数:中断中AD转换函数
*****************************************************/
void adc0809(void)
{
oe=0;
st=0;
st=1;
st=0;
while(!eoc);
oe=1;
t=P1;
t_now=100*t/256;
oe=0;
}
/****************************************************
函数:中断中控制输出函数
*****************************************************/
void p_out(void)
{
int j;
j=(int)tout;
if(ttemp3<=j)heal=0;
else heal=1;
if((ttemp2++)==5)
{
ttemp2=0;
ttemp3++;
}
if(ttemp3>100)ttemp3=1;
}
/****************************************************
函数:进行pid计算,得出控制量函数
*****************************************************/
void pid()
{
temp=t_diff;
adc0809();
t_diff=t_target-t_now;
tout+=KP*(t_diff-temp)+KI*t_diff;
if(tout<0)tout=0;
else if(tout>=100)tout=100;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -