温度PID控制源码基于51单片机.docx

上传人:b****8 文档编号:9953793 上传时间:2023-02-07 格式:DOCX 页数:15 大小:17.70KB
下载 相关 举报
温度PID控制源码基于51单片机.docx_第1页
第1页 / 共15页
温度PID控制源码基于51单片机.docx_第2页
第2页 / 共15页
温度PID控制源码基于51单片机.docx_第3页
第3页 / 共15页
温度PID控制源码基于51单片机.docx_第4页
第4页 / 共15页
温度PID控制源码基于51单片机.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

温度PID控制源码基于51单片机.docx

《温度PID控制源码基于51单片机.docx》由会员分享,可在线阅读,更多相关《温度PID控制源码基于51单片机.docx(15页珍藏版)》请在冰豆网上搜索。

温度PID控制源码基于51单片机.docx

温度PID控制源码基于51单片机

/************************************************************

类型:

温度传感器液晶综合运用。

现象:

在液晶上面显示当前环境温度。

编写:

铁牛电子

时间:

2009.3

修改:

【版权】Copyright(C)铁牛电子AllRightsReserved

【声明】此程序仅用于学习与参考,引用请注明版权和作者信息!

************************************************************/

#include//52单片机头文件,一般不要改动,里面包含特殊功能寄存器的定义

#include

#include

#include

#defineucharunsignedchar//将unsignedchar定义为uchar,简化输写。

提高编程速度

#defineuintunsignedint//将unsignedchar定义为uint,简化输写。

提高编程速度

uintshi,ge,xiaoshu;

uintmiao,fen,shi0;

uchari,x,c,crout,d,high_time,low_time;

uintnum;

uintset_temp;

sbitlcdrs=P1^0;//数据命令选择控制

sbitlcdrw=P1^1;//读/写选择控制

sbitlcden=P1^2;

sbits1=P0^0;

sbits2=P0^1;

sbits3=P0^2;

sbitrd=P0^7;

sbitjdq=P3^5;

structPID{

uintSetPoint;//设定目标DesiredValue

uintProportion;//比例常数ProportionalConst

uintIntegral;//积分常数IntegralConst

uintDerivative;//微分常数DerivativeConst

uintLastError;//Error[-1]

uintPrevError;//Error[-2]

uintSumError;//SumsofErrors

};

structPIDspid;//PIDControlStructure

uintrout;//PIDResponse(Output)

uintrin;//PIDFeedback(Input)

uintNextPoint;

uinttemper;

unsignedcharj;

ucharcount,s1num;

ucharcodet0[]="Thetemperature";

ucharcodet1[]="isC";

ucharcodet2[]="Thetemperature";

ucharcodet3[]="isC";

ucharcodewendu[]="0123456789";//利用一个温度表解决温度显示乱码

sbitDS=P3^3;//定义温度DS18B20接口,详情见原理图

voiddelay(ucharz)

{

ucharx,y;

for(x=100;x>1;x--)

for(y=z;y>1;y--);

}

voidwrite_com(ucharcom)//写指令码

{

lcdrs=0;

lcden=0;

P2=com;//送指令码

delay(5);

lcden=1;

delay(5);

lcden=0;

}

voidwrite_date(uchardate)

{

lcdrs=1;

lcden=0;

P2=date;

delay(5);

lcden=1;

delay(5);

lcden=0;

}

voidinit_lcd()//初始化程序

{

//dula=0;

//wela=0;//关掉数码管

lcden=0;

lcdrw=0;

write_com(0x38);//显示模式设置

write_com(0x01);

write_com(0x0c);

write_com(0x06);

write_com(0x80);

for(i=0;i<16;i++)

{

write_date(t0[i]);

delay(0);

}

write_com(0x80+0x40);

for(i=0;i<16;i++)

{

write_date(t1[i]);

delay(0);

}

}

/*************DS18B20温度读取模块*************/

voidtmpDelay(intnum)//延时函数

{

while(num--);

}

voidInit_DS18B20()//初始化ds1820

{

unsignedcharx=0;

DS=1;//DS复位

tmpDelay(8);//稍做延时

DS=0;//单片机将DS拉低

tmpDelay(80);//精确延时大于480us

DS=1;//拉高总线

tmpDelay(14);

x=DS;//稍做延时后如果x=0则初始化成功x=1则初始化失败

tmpDelay(20);

}

unsignedcharReadOneChar()//读一个字节

{

unsignedchari=0;

unsignedchardat=0;

for(i=8;i>0;i--)

{

DS=0;//给脉冲信号

dat>>=1;

DS=1;//给脉冲信号

if(DS)

dat|=0x80;

tmpDelay(4);

}

return(dat);

}

voidWriteOneChar(unsignedchardat)//写一个字节

{

unsignedchari=0;

for(i=8;i>0;i--)

{

DS=0;

DS=dat&0x01;

tmpDelay(5);

DS=1;

dat>>=1;

}

}

unsignedintReadtemp()//读取温度

{

unsignedchara=0;

unsignedcharb=0;

unsignedintt=0;

floattt=0;

Init_DS18B20();

WriteOneChar(0xCC);//跳过读序号列号的操作

WriteOneChar(0x44);//启动温度转换

Init_DS18B20();

WriteOneChar(0xCC);//跳过读序号列号的操作

WriteOneChar(0xBE);//读取温度寄存器

a=ReadOneChar();//连续读两个字节数据//读低8位

b=ReadOneChar();//读高8位

t=b;

t<<=8;

t=t|a;//两字节合成一个整型变量。

tt=t*0.0625;//得到真实十进制温度值,因为DS18B20可以精确到0.0625度,所以读回数据的最低位代表的是0.0625度

t=tt*10+0.5;//放大十倍,这样做的目的将小数点后第一位也转换为可显示数字,同时进行一个四舍五入操作。

return(t);

}

voiddisplay()//显示函数

{

write_com(0x80);

for(i=0;i<16;i++)

{

write_date(t2[i]);

delay(5);

}

write_com(0x80+0x40);//更改数据指针,让字符换行

for(i=0;i<16;i++)

{

write_date(t3[i]);

delay(5);//增加延时可以达到动态的效果

}

write_com(0x80+0x40+5);

write_date(wendu[shi0]);

write_com(0x80+0x40+6);

write_date(wendu[fen]);

write_com(0x80+0x40+7);

write_date(0x2e);

write_com(0x80+0x40+8);

write_date(wendu[miao]);

write_com(0x80+0x40+9);

write_date(0xa1);

}

voiddisplay1()

{

uintnum;//定义的时候用uchar宏定义就会出错

uintshi,ge,xiaoshu;//这里的num,shi,ge,xiaoshu必须用uint无符号整数来表示,用uchar字符型则显示错误

num=Readtemp();

shi=num/100;

ge=num/10%10;

xiaoshu=num%10;

write_com(0x80+0x40+5);

write_date(wendu[shi]);

write_com(0x80+0x40+6);

write_date(wendu[ge]);

write_com(0x80+0x40+7);

write_date(0x2e);

write_com(0x80+0x40+8);

write_date(wendu[xiaoshu]);

write_com(0x80+0x40+9);

write_date(0xa1);

}

/*voidwrite_sfm(ucharadd,uchardate)

{

ucharge;

//shi=date/10;

ge=date%10;

//xiaoshu=num%10;

write_com(0x80+0x40+add);

//write_date(0x30+shi);

write_date(0x30+ge);

//write_date(0x30+xiaoshu);

}*/

voidint0()interrupt0

{

EX0=0;

display();

while

(1)

{

rd=0;

if(s1==0)

{

delay(5);

if(s1==0)

{s1num++;

while(!

s1);

if(s1num==1)

{

TR0=0;

write_com(0x80+0x40+8);

write_com(0x0f);

}

}

if(s1num==2)

{

write_com(0x80+0x40+6);

}

if(s1num==3)

{

write_com(0x80+0x40+5);

}

if(s1num==4)

{

s1num=0;

write_com(0x0c);

TR0=1;

set_temp=shi0*100+fen*10+miao;

break;

}

}

if(s1num!

=0)

{

if(s2==0)

{

delay(5);

if(s2==0)

{

while(!

s2);

if(s1num==1)

{

miao++;

if(miao==10)

miao=0;

write_date(wendu[miao]);

write_com(0x80+0x40+8);

}

if(s1num==2)

{

fen++;

if(fen==10)

fen=0;

write_date(wendu[fen]);

write_com(0x80+0x40+6);

}

if(s1num==3)

{

shi0++;

if(shi0==10)

shi0=0;

write_date(wendu[shi0]);

write_com(0x80+0x40+5);

}

}

}

}

}

EX0=1;

}

voidPIDInit(structPID*pp)

{

memset(pp,0,sizeof(structPID));

}

floatPIDCalc(structPID*pp,NextPoint)

{

unsignedintdError,Error;

Error=pp->SetPoint-NextPoint;//偏差

pp->SumError+=Error;//积分

dError=pp->LastError-pp->PrevError;//当前微分

pp->PrevError=pp->LastError;

pp->LastError=Error;

return(pp->Proportion*Error+pp->Integral*pp->SumError+pp->Derivative*dError);

}

compare_temper()

{

spid.SetPoint=set_temp;//SetPIDSetpoint

temper=Readtemp();

set_temp=shi0*100+fen*10+miao;

if(set_temp>temper)

{

if(set_temp-temper>50)

{

jdq=0;

}

elseif(set_temp-temper<=50)

{

for(j=0;j<10;j++)

{

temper=Readtemp();

rin=temper;//ReadInput

rout=PIDCalc(&spid,rin);//PerformPIDInteration

}

if(high_time<=100)

high_time=(unsignedchar)(rout/800);

else

high_time=100;

low_time=(100-high_time);

}

elseif(set_temp<=temper)

{

jdq=1;

}

}

}

voidmain()

{

c=0;

d=0;

PIDInit(&spid);//InitializeStructure

spid.Proportion=10;//SetPIDCoefficients

spid.Integral=8;

spid.Derivative=6;

spid.SetPoint=set_temp;

init_lcd();

set_temp=330;

shi0=set_temp/100;

fen=set_temp%100/10;

miao=set_temp%10;

EA=1;

EX0=1;

IT0=1;

while

(1)

{

//keyscan();

display();

delay(10);

compare_temper();

for(c>0;c

{

jdq=0;

delay(5);

low_time=15750-high_time;

}

for(d=0;d

{

jdq=1;

delay(5);

}

display();

}

}

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 考试认证 > 从业资格考试

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1