#include <REGX51.H>
unsigned char m,n,p; //温度的十位 个位 小数
unsigned char test_temp; //温度检定标志
unsigned char key_set_flag; //按键设定进入标志
unsigned char flag=1; //按键保持标志
unsigned char Change_step=1,e; //温度设置步进
unsigned char T0_H = 0,T0_L = 0,T1_H=0,T1_L=0;//PWM
int Real_temp; //实际温度值
int Set_temp; //设置温度
int Disp_temp; //显示温度
int last_error; //上次误差
float I_term; //前面温差和
bit key_hold;
int PID_MAX;
unsigned int out,PWMT,counter,kk,outp,dz;
int time; //脉冲触发时刻
sbit DQ=P2^4; //定义DS18b20的管脚
sbit RS = P2^0; //定义液晶屏定义端口
sbit RW = P2^1; //定义液晶屏定义端口
sbit EN = P2^2; //定义液晶屏定义端口
sbit k1=P1^0;
sbit k2=P1^1;
sbit k3=P1^2;
sbit PWM=P2^7; //PWM控制脚
sbit led1=P3^5;
sbit led2=P3^6;
sbit led3=P3^7;
sbit beep=P1^3;
#define Kp 5 //比例系数
#define Ki 0 //积分系数
#define Kd 1 //微分系数
#define RS_CLR RS=0
#define RS_SET RS=1
#define RW_CLR RW=0
#define RW_SET RW=1
#define EN_CLR EN=0
#define EN_SET EN=1
unsigned char aa[]={'S','e','t','u','p',':',' ',' ',' ',' ','.',' ',' ',' ',' ',' '}; //Distance
unsigned char bb[]={'C','u','r','r','t',':',' ',' ',' ',' ','.',' ',' ',' ',' ',' '};
void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s);
void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data);
void LCD_init(); //LCD初始化
/*------------------------------------------------
uS延时函数,含有输入参数 unsigned char t,无返回值
unsigned char 是定义无符号字符变量,其值的范围是
0~255 这里使用晶振12M,大致延时长度如下 T=tx2+5 uS
------------------------------------------------*/
void DelayUs2x(unsigned char t)
{
while(--t);
}
/*------------------------------------------------
mS延时函数,含有输入参数 unsigned char t,无返回值
unsigned char 是定义无符号字符变量,其值的范围是
0~255 这里使用晶振12M,精确延时请使用汇编
------------------------------------------------*/
void DelayMs(unsigned char t)
{
while(t--) //大致延时1mS
{
DelayUs2x(245);
DelayUs2x(245);
}
}
/*****延时子程序*****/
void delay(unsigned int t)
{
for(;t>0;t--);
}
void delay_50us(unsigned int t)
{
unsigned char j;
for(;t>0;t--)
for(j=19;j>0;j--);
}
/*****初始化DS18B20*****/
unsigned char Init_DS18B20(void)
{
unsigned char x=0;
DQ = 1; //DQ复位
delay(8); //稍做延时
DQ = 0; //单片机将DQ拉低
delay(80); //精确延时,大于480us
DQ = 1; //拉高总线
delay(8);
x = DQ; //稍做延时后,如果x=0则初始化成功,x=1则初始化失败
delay(4);
return x;
}
/*****读一个字节*****/
unsigned char ReadOneChar(void)
{
unsigned char i=0;
unsigned char dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; // 给脉冲信号
dat>>=1;
DQ = 1; // 给脉冲信号
if(DQ)
dat|=0x80;
delay(4);
}
return(dat);
}
/*****写一个字节*****/
void WriteOneChar(unsigned char dat)
{
unsigned char i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
delay(4);
DQ = 1;
dat>>=1;
}
delay(4);
}
/*****读取温度*****/
int ReadTemperature(void)
{
unsigned char a=0;
unsigned char b=0;
unsigned int t=0;
t=Init_DS18B20();
if(t) return Real_temp;
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0x44); //启动温度转换
t=Init_DS18B20();
if(t) return Real_temp;
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器
a=ReadOneChar(); //读低8位
b=ReadOneChar(); //读高8位
t=b;
t<<=8;
t=t|a;
if(t<=0||t>0x900)
return Real_temp;
t=t*0.625+0.5;
return(t);
}
void key_set(void)
{
if(k1==0)
{
delay(10);
while(!k1);
key_hold=~key_hold;
}
if(key_hold==0)
{
if(k2==0) //温度加
{
delay(10);
while(!k2);
Set_temp=Set_temp+1;
if(Set_temp>99)
Set_temp=99;
}
if(k3==0) //温度减
{
delay(10);
while(!k3);
Set_temp=Set_temp-1;
if(Set_temp<1)
Set_temp=1;
}
aa[8]=10*Set_temp/100+'0'; //十位 Assic码
aa[9]=10*Set_temp/10%10+'0'; //个位
aa[11]=10*Set_temp%10+'0'; //十分位
LCD_Write_String(0,0,aa); //显示设定温度
}
}
int PID(int Set_value,int Real_value) //标准PID温度控制算法
{
float uk ,uk1 ,duk;
int pid_out,e ,e1 ,e2;
e=Set_value-Real_value;//误差量 P*e+I*e的积分+d*e的微分
duk=Kp*(e-e1)+Ki*e+Kd*(e-2*e1+e2); //+Kd*(e-2e1+e2)
uk=uk1+duk;
pid_out=(int)uk;
uk1=uk;
e2=e1;
e1=e;
//给pid的输出限幅,防止超调或冲击
if(pid_out>1000)
{
pid_out=998;
}
else if(pid_out<2)
{
pid_out=2;
}
outp=pid_out;//pid的输出赋值给outp
return(pid_out);
}
void T0_int(void) interrupt 1
{
//定时2ms=2000us的中断时间
T0_H = (65535-2000)/256; //PWM=1高位初值计算
T0_L = (65535-2000)%256; //PWM=1低位初值计算
TH0 = T0_H; //通的初值高位
TL0= T0_L; //通的初值低位
kk++;
if(kk>1000)
kk=0;
if(kk>outp)
PWM=1;
else PWM=0;
}
void main()
{
PWMT=128; //128级步进PWM控制
PID_MAX=PWMT;
counter=0;
out=0;
PWM=1;//初始默认输出高电平,也就是不加热
I_term=0;
last_error=0;
Set_temp=30;//初始设定温度为30度
LCD_init(); //LCD初始化
Real_temp=Set_temp*10;//初始化真实温度为设定的十倍,这是由于Ds18B20读取回来的就是原来的十倍
key_hold=1;//默认不设置
Init_DS18B20();//温度传感器初始化
WriteOneChar(0xCC); //跳过读Db18b20序号列号的操作
WriteOneChar(0x44); //启动Db18b20温度转换
delay_50us(150); //等待Db18b20温度测量 delay_50us(15000);
TMOD=0x01; //定时器0模式1,16位定时计数器65535
TR0=1; //允许定时器0计时
ET0=1; //使能定时器0的中断(interrupt)
EA=1; //使能全局中断
aa[12]=0xdf; //°
aa[13]=0x43; //C
bb[12]=0xdf; //°
bb[13]=0x43; //C
aa[8]=10*Set_temp/100+'0';//十位
aa[9]=10*Set_temp/10%10+'0'; //个位
aa[11]=10*Set_temp%10+'0'; //十分位
LCD_Write_String(0,0,aa);
while(1) //循环运行
{
counter++;
DelayMs(500);
if(counter>4)
{
test_temp=1; //进行一次温度检定
counter=0;
}
if(test_temp) //温度检定标志置位
{
Real_temp=ReadTemperature(); //采集当前实际温度,当前是*10倍的数据
test_temp=0; //检定完成,清温度检定标志
bb[8]=Real_temp/100+'0'; //显示温度的数字,当前是*10倍的数据
bb[9]=Real_temp/10%10+'0';
bb[11]=Real_temp%10+'0';
LCD_Write_String(0,1,bb); //写入至LCD
/*****************故障处理*********************/
if((Real_temp/10)<(Set_temp-5))//如果当前温度小于设定的温度-5
{
beep=~beep; //蜂鸣器工作
led1=~led1; //温度过低灯亮
led2=1; //正常工作灯暗
}
else if((Real_temp/10)>(Set_temp+5))//如果当前温度大于设定的温度+5
{
beep=~beep; //蜂鸣器工作
led3=~led3; //温度过高灯亮
led2=1; //正常工作灯暗
}
else //如果当前温度等于设定的温度
{
beep=1; //蜂鸣器不工作
led1=1;
led2=0; //温度正常灯亮
led3=1;
}
}
/******************故障处理********************/
if((Real_temp/10)<(Set_temp-5)) //如果当前温度小于设定的温度-1的值,那就让加热全速进行,也就是电机全速工作,设定PID输出为常数998
{
outp=998;
}
else if((Real_temp/10)>(Set_temp+5)) //如果当前温度大于设定的温度+1,那就让加热基本停止,也就是电机很缓慢工作,设定PID输出为常数2
{
outp=2;
}
else
{
PID(Set_temp*10,Real_temp); ////如果当前温度在设定的温度+-1之间,那就让加热按照PID的程序运行
}
key_set(); //按键温度设置
}
}
///////////////////////////////////////////////////
// 液晶屏显示处理
///////////////////////////////////////////////////
void write_com(unsigned char com) //写命令
{
RS_CLR;
RW_CLR;
P0=com;
DelayMs(1);
EN_SET;
DelayMs(1);
EN
LEODWL
- 粉丝: 2w+
- 资源: 30
最新资源
- Tina 9.3仿真软件
- 【java毕业设计】springboot-酷听音乐(springboot+vue+mysql+说明文档).zip
- 【java毕业设计】基于SpringBoot的遥感影像共享系统(springboot+vue+mysql+说明文档).zip
- 【java毕业设计】springboot的自习室座位预约系统(springboot+vue+mysql+说明文档).zip
- 构建HTTP客户端:Python实现与最佳实践
- Veriloh-HDL实现的通用串口模块,UART通信,支持校验,波特率参数化可设置
- 【java毕业设计】springbootJava Move体育商城(springboot+vue+mysql+说明文档).zip
- 【java毕业设计】springboot乡村生活垃圾(springboot+vue+mysql+说明文档).zip
- 128张云飞24811172自动化(2405)_QQ浏览器转格式.pdf
- ditto安装包+pixpin安装包+notepad++.rar
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
- 1
- 2
- 3
前往页