电烤箱温度控制系统程序
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
52070329
徐高飞
//每隔 10 s,即定时器 1 溢出 50000 次,重新计算占空比 Pdr //计算 PID 参数 //T1 溢出次数清零,进入下一个控制周期
6/7
电烤箱温度控制系统程序
定时器 T1 中断服务程序:
void intT1() interrupt 3 { uint q; if(T==50000) q=Pdr; T++; if(temp<r) if(Pdr>=0) { pwm=1; Pdr--; } Else pwm=0; else pwm=0; if(T%100==0) Pdr=q; }
52070329
徐高飞
xdata unsigned char lcdwir _at_ 0xb000 ; // 液晶写指令地址,液晶显示屏 CS 接 138 译码器 Y5 xdata unsigned char lcdwdr _at_ 0xb001 ; // 液晶写数据地址 xdata unsigned char lcdrir _at_ 0xb002 ; // 液晶读状态地址 xdata unsigned char lcdrdr _at_ 0xb003 ; // 液晶读数据地址 /*检查 LCD 状态函数*/ bit lcd_checkbusy() { unsigned char lcdstate; lcdstate=lcdrir;//读取 lcd 的状态 lcdstate &=0x80; return((bit)lcdstate); } /*写 LCD 命令函数*/ void lcd_wrcmd(unsigned char lcdwr) /* 写 LCD 命令函数*/ { while(lcd_checkbusy()); lcdwir=lcdwr; } /*写数据函数*/ void lcd_wrdata(char lcddata) /* 在当前显示位置显示数据*/ { while(lcd_checkbusy()); lcdwdr=lcddata; } //液晶初始化函数 void lcd_init() { lcd_wrcmd(0x01); lcd_wrcmd(0x38); lcd_wrcmd(0x0c); }
1/7
电烤箱温度控制系统程序
//ADC0809 转换函数 float measure_temp() { uchar i,j; for(j=0;j<10;j++) { P2=0xd0; P0=0x00; adwr=1;_nop_(); adwr=0;_nop_(); adwr=1; //ADC0809 开始转换 delayms(1); adrd=1;_nop_(); adrd=0;_nop_(); i=P0; adrd=1; } adval_sum=add(adval); adval_aver=adval_sum/10; voltage=(float)adval_aver/256*5.00; temp=voltage*40+20; return temp; } //电压值 //开始读取数据
52070329
徐高飞
uint adval_sum; //十次温度值之和 float adval_aver,voltage,temp; //延时子函数 延时 Zms void delayms(uint z) { uint x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } //加和函数 对十次温度值求和 uint add(uchar a[10]) { uchar i=0; uint sum=0; for(i=0;i<10;i++) sum=sum+a[i]; return sum; } //字节转换函数 /*将从 P0 口读到的数据 a: D0 D1 D2 D3 D4 D5 D6 D7 调整为 b:D7 D6 D5 D4 D3 D2 D1 D0 */ uchar exchange(uchar a) { uchar b,c,d; d=a; b=0x00; a=d; c=a<<7; c&=0x80; //c: D7 0 0 0 0 0 0 0 b|=c; //b: D7 0 0 0 0 0 0 0 } a=d; c=a<<5; c&=0x40; b|=c; a=d; c=a<<3; c&=0x20; b|=c; a=d; c=a<<1; c&=0x10; b|=c; a=d; c=a>>1; c&=0x08; b|=c; a=d; //b: D7 D6 D5 D4 D3 0 0 0 //b: D7 D6 D5 D4 0 0 0 0 //b: D7 D6 D5 0 0 0 0 0 //c: 0 D6 0 0 0 0 0 0 //b: D7 D6 0 0 0 0 0 0
7/7
//一个控制周期分 500 个 PWM 信号周期
5/7
电烤箱温度控制系统程序 主函数
#include <reg52.h> #include <intrins.h> #include <adc0809.h> #include <lcd1602.h> #include <initial.h> #include <PID.h> #define uchar unsigned char #define uint unsigned int sbit pwm=P1^6; sbit led=P1^7; uint T; float temp; void main() { EA=1; ET1=1; T=50000; TMOD=0x20; TH1=0x48; TL1=0x48; TR1=1; while(1) { temp=measure_temp(); lcd_show(temp); delayms(10); if(T==50000) { calculate_PID(temp); T=0; } } } //测温度 //显示温度 //使用定时器 1,工作于方式 2 //定时 200 us //定时器 1 溢出次数 //温度值
52070329
徐高飞
adval[j]=exchange(i);
//需要根据实际测出温度和电压的关系式
2/7
电烤箱温度控制系统程序
头文件 lcd1602.h:LCD 应用程序
#include<reg52.h> #include<intrins.h> #include<math.h> #define uchar unsigned char #define uint unsigned int
//清屏 //设置显示模式:两行 5×7,光标开 //整体显示, 关光标, 不闪烁
3/7Biblioteka Baidu
电烤箱温度控制系统程序
//显示温度函数 void lcd_show(float temp) { int B,S,G,SF; float value; value=temp*10; B=(int)value/1000; //取出温度值的百位
52070329
徐高飞
//每次计算出新的“占空比”Pdr,把它保存在变量 q 中 //定时器 1 溢出次数加 1 //如果温度 temp 小于给定 r,可以按控制规设置 PWM 信号 //如果在当前的 PWM 信号周期中,高电平所占比例未达到指定比例, // 则在 T1 的下一个定时周期中,PWM 信号保持高电平 //在当前的 PWM 信号周期中, “占空比”Pdr 减一 //如果在当前的 PWM 信号周期中,高电平所占比例已达到指定比例, //则在当前的 PWM 信号周期接下来的时间里,PWM 信号保持低电平 //如果温度 temp 不小于小于给定 r, PWM 信号保持低电平 //如果指令已经执行了一个 PWM 信号周期,即定时器 1 溢出了 100*N 次 //恢复 Pdr 的值,开始下一个 PWM 信号周期
52070329
徐高飞
S=(int)value%1000/100; //取出温度值的十位 G=(int)value%100/10; //取出温度值的个位 SF=(int)value%10; B+=0x30; S+=0x30; G+=0x30; SF+=0x30; lcd_init(); lcd_wrcmd(0x80); lcd_wrdata('T'); lcd_wrdata('E'); lcd_wrdata('M'); lcd_wrdata('P'); lcd_wrdata(0x3A); //显示 TEMP: lcd_wrdata(B); lcd_wrdata(S); lcd_wrdata(G); lcd_wrdata(0x2e); //百位 //十位 //个位 //"." //指定初始显示位置 //取出温度值的十分位 //将各位数值调整为 ASCII 码
c=a>>3; c&=0x04; b|=c; //b: D7 D6 D5 D4 D3 D2 0 0 a=d; c=a>>5; c&=0x02; b|=c; //b: D7 D6 D5 D4 D3 D2 D1 0 a=d; c=a>>7; c&=0x01; b|=c; return b; //b: D7 D6 D5 D4 D3 D2 D1 D0
电烤箱温度控制系统程序
头文件 adc0809.h:ADC0809 应用程序
#include<reg52.h> #include<intrins.h> #include<math.h> #define uchar unsigned char #define uint unsigned int sbit adwr=P3^6; sbit adrd=P3^7; uchar adval[10]; //取十次温度值
lcd_wrdata(SF); //十分位 lcd_wrdata(0x43); //"C" }
4/7
电烤箱温度控制系统程序
52070329
徐高飞
头文件 initial.h:定义全局变量: “占空比”Pdr、给定值 r
#include<reg52.h> #define uint unsigned int uint Pdr; uint r; 头文件 PID.h:根据 PID 算法计算“占空比”Pdr #include<reg52.h> #include<intrins.h> #include<math.h> #include<initial.h> #define uchar unsigned char #define uint unsigned int void calculate_PID(float temp) { uint Kp,Ti,Td,y,T; uint a0,a1,a2; uint e[3]={0,0,0}; uint u[2]={0,0}; Kp=20; Ti=20; Td=0; T=10; r=100; y=(uint)temp; a0=Kp*(1+T/Ti+Td/T); a1=Kp*(1+2*Td/T); a2=Kp*Td/T; e[3]=r-y; u[1]=u[0]+a0*e[2]-a1*e[1]+a2*e[0]; u[0]=u[1]; e[0]=e[1]; e[1]=e[2]; Pdr=u[1]/500; if(Pdr>100) Pdr=100; } // Pdr=100 即固态继电器一直导通 //控制周期 10s //给定值 100 // e[2]表示 e[i]、e[1]表示 e[i-1]、e[0]表示 e[i-2] // u[1]表示 u[k]、u[0]表示 u[k-1]