#include<reg52.h>
#include<intrins.h>
#include<math.h>
#include<string.h>
struct PID {
unsigned int SetPoint; // 设定目标 Desired Value
unsigned int Proportion; // 比例常数 Proportional Const
unsigned int Integral; // 积分常数 Integral Const
unsigned int Derivative; // 微分常数 Derivative Const
unsigned int LastError; // Error[-1]
unsigned int PrevError; // Error[-2]
unsigned int SumError; // Sums of Errors
};
struct PID spid; // PID Control Structure
unsigned int rout; // PID Response (Output) 响应输出
unsigned int rin; // PID Feedback (Input)//反馈输入
unsigned char high_time,low_time,count=0;//占空比调节参数
#define uchar unsigned char
#define uint unsigned int
sbit output=P1^0;
sbit ds=P3^2;
sbit DQ=P3^2;//ds18b20与单片机连接口
sbit lcden=P2^7;//LCE使能引脚
sbit lcdrs=P2^5;
sbit lcdrw=P2^6;
sbit ledred=P1^6;
sbit ledgreen=P1^7;
sbit key0=P2^0;//按键引脚
sbit key1=P2^1;
uchar set[2]={0};
uchar code str1[]="now temp: C";
uchar code str2[]="set temp: C";
uchar code table[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};
uchar n,num;
int set_temper=30,temper,temp; //温度变量定义
unsigned int s;
float f_temp;//转换后的温度
uint tvalue;
uchar tflag;//温度正负标志
void delay(i)//延时函数
{
uint j;
for(i;i>0;i--)
for(j=110;j>0;j--);
}
void wr_com(uchar ml)//写命令
{
lcdrs=0;
P0=ml;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void wr_data(uchar shuju)//写数据
{
lcdrs=1;
//lcden=1;
P0=shuju;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void init() //按照时序操作的初始化
{
lcdrw=0;
wr_com(0x38);//显示模式设置,设置为16*2显示,5*7点阵,八位数据口
wr_com(0x0c);//开显示,但不开光标,光标不闪
wr_com(0x06);//显示光标移动设置
wr_com(0x01);// 清屏
wr_com(0x80); // 数据指针初始化
for(num=0;num<16;num++)
{
wr_data(str1[num]);//now temp
}
wr_com(0x80+0x40); //地址初始化
for(num=0;num<16;num++)
{
wr_data(str2[num]);//set temp
}
}
/*************************DS1820程序****************************/
void delay_18B20(unsigned int i)//延时1微秒
{
while(i--);
}
void ds1820rst(void)/*ds1820复位*/
{
unsigned char x=0;
DQ = 1; //DQ复位
delay_18B20(4); //延时
DQ = 0; //DQ拉低
TR0=0;
delay_18B20(100); //精确延时大于
TR0=1;
DQ = 1; //拉高
delay_18B20(40);
}
uchar ds1820rd(void)/*读数据*/
{
unsigned char i=0;
unsigned char dat = 0;
TR0=0;
for (i=8;i>0;i--)
{
DQ = 0; //给脉冲信号
dat>>=1;
DQ = 1; //给脉冲信号
if(DQ)
dat|=0x80;
delay_18B20(10);
}
return(dat);
}
void ds1820wr(uchar wdata)/*写数据*/
{
unsigned char i=0;
TR0=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = wdata&0x01;
delay_18B20(10);
DQ = 1;
wdata>>=1;
}
}
uint get_temper()//获取温度
{
uchar a,b;
ds1820rst();
ds1820wr(0xcc);//*跳过读序列号*/
ds1820wr(0x44);//*启动温度转换*/
ds1820rst();
ds1820wr(0xcc);//*跳过读序列号*/
ds1820wr(0xbe);//*读取温度*/
a=ds1820rd();
b=ds1820rd();
tvalue=b;
tvalue<<=8;
tvalue=tvalue|a;
TR0=1;
if(tvalue<0x0fff) tflag=0;
else {tvalue=~tvalue+1;tflag=1;}
tvalue=tvalue*(0.625);//温度值扩大10倍,精确到1位小数
temp=tvalue;
return temp;
}
void dis_temp(int t)//显示温度
{
uchar d0,d1,d2,d3;
//t=26;
if(tflag==0)
{
d0=t/1000+0x30;
d1=t%1000/100+0x30;
d2=t%100/10+0x30;
d3=t%10+0x30;
if(d0==0x30)
{
wr_com(0x80+9);
wr_data(d1);
wr_com(0x80+10);
wr_data(d2);
wr_com(0x80+11);
wr_data(0x2e);
wr_com(0x80+12);
wr_data(d3);
}
else
{
wr_com(0x80+9);
wr_data(d0);
wr_com(0x80+10);
wr_data(d1);
wr_com(0x80+11);
wr_data(d2);
wr_com(0x80+12);
wr_data(' ');
}
}
else
{
wr_com(0x80+9);
wr_data('-');
wr_com(0x80+10);
wr_data(d1);
wr_com(0x80+11);
wr_data(d2);
wr_com(0x80+12);
wr_data(' ');
//wr_com(0x80+12);
//wr_data(d3);
}
wr_com(0x80+14);
wr_data(0xdf);
temper=t/10;
}
void keyscan()//键盘扫描
{
if(key0==0)
{
delay(1);
if(key0==0)
{
while(!key0);
delay(1);
while(!key0);
set_temper++;
}
set[0]=set_temper/10; //获得设置温度显示值
set[1]=set_temper%10;
wr_com(0x80+0x40+9);
wr_data(table[set[0]]);
delay(1);
wr_com(0x80+0x40+10);
wr_data(table[set[1]]);
delay(1);
//wr_com(0x80+0x40+11);
//wr_data(0x2e);
//wr_com(0x80+0x40+14);
//wr_data(0xdf);
delay(1);
}
if(key1==0)
{
delay(3);//延时去抖
if(key1==0)
{
while(!key1);
delay(3);
while(!key1);
set_temper--;//温度减
if(set_temper==0)
{set_temper=0;}
}
set[0]=set_temper/10; //获得设置温度显示值
set[1]=set_temper%10;
wr_com(0x80+0x40+9); //显示设置温度值
wr_data(table[set[0]]);
delay(1);
wr_com(0x80+0x40+10);
wr_data(table[set[1]]);
delay(1);
//wr_com(0x80+0x40+11);
//wr_data(0x2e);
wr_com(0x80+0x40+14);
wr_data(0xdf);
delay(1);
}
}
void PIDInit (struct PID *pp)
{
memset ( pp,0,sizeof(struct PID)); //用参数0初始化pp
}
unsigned int PIDCalc( struct PID *pp, unsigned int NextPoint ) //PID计算
{
unsigned int dError,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); // 微分项
}
/***********************************************************
温度比较处理子程序
***********************************************************/
void compare_temper(void)
{
unsigned char i;
if(set_temper>temper) //设置温度大于当前温度
{
ledred=0;
ledgreen=1;
if(set_temper-temper>1) //温度相差1度以上
{
high_time=100;
low_time=0;
}
else //设置温度不大于当前温度
{
for(i=0;i<10;i++)
{
get_temper();
rin = s; // Read Input
rout = PIDCalc ( &spid,rin ); // Perform PID Interation
}
if (high_time<=100) high_time=(unsigned char)(rout/800);
else high_time=100;
low_time= (100-high_time);
}
}
else if(set_temper<=temper) //设置温度不大于当前温度
{
ledred=1;
ledgreen=0;
if(temper-set_temper>0) //温度相差0度以上
{
high_time=0;
low_time=100;
}
else
{
for(i=0;i<10;i++)
{
get_temper();
rin = s; // Read Input
rout = PIDCalc ( &spid,rin ); // Perform PID Interation
}
if (high_time<100) high_time=(unsigned char)(rout/10000);
else high_time=0;
low_time= (100-high_time);
}
}
}
/*****************************************************
T0中断服务子程序,用于控制电平的翻转 ,40us*100=4ms周期
******************************************************/
void serve_T0() interrupt 1 using 1
{
if(++count<=(high_time)) output=0;
else if(count<=100)
{
output=1;
}
else count=0;
TH0=0x2f;
TL0=0x40;
}
/***********主函数**********/
void main(void)
{
unsigned char i;
init();//LCD初始化
TMOD=0x01;
TH0=0x2f;
TL0=0x40;
EA=1;
ET0=1;
TR0=1;
high_time=50;
low_time=50;
PIDInit ( &spid ); // Initialize Structure
spid.Proportion= 10; // Set PID Coefficients
spid.Integral = 8;
spid.Derivative =6;
spid.SetPoint =100; // Set PID Setpoint
set[0]=set_temper/10;
set[1]=set_temper%10;
wr_com(0x80+0x40+9); //显示设置温度
wr_data(table[set[0]]);
delay(1);
wr_com(0x80+0x40+10);
wr_data(table[set[1]]);
delay(1);
wr_com(0x80+0x40+14); //显示温度符号
wr_data(0xdf);
delay(1);
while(1)
{
keyscan(); //按键扫描
for(i=0;i<10;i++) //循环10次
{
dis_temp(get_temper()); //显示温度值
if((key0==0)||(key1==0)) break; //如果有按键退出显示循环
}
if((
没有合适的资源?快使用搜索试试~ 我知道了~
基于单片机PID算法的恒温控制系统仿真与程序源码设计(DS18B20传感器)
共32个文件
workspace:4个
png:3个
bak:3个
需积分: 5 0 下载量 38 浏览量
2024-05-21
15:12:50
上传
评论
收藏 757KB ZIP 举报
温馨提示
基于单片机PID算法的恒温控制系统仿真与程序源码设计(DS18B20传感器) 基于单片机PID算法的恒温控制系统仿真与程序源码设计(DS18B20传感器) 基于单片机PID算法的恒温控制系统仿真与程序源码设计(DS18B20传感器) 基于单片机PID算法的恒温控制系统仿真与程序源码设计(DS18B20传感器) 基于单片机PID算法的恒温控制系统仿真与程序源码设计(DS18B20传感器) 基于单片机PID算法的恒温控制系统仿真与程序源码设计(DS18B20传感器) 基于单片机PID算法的恒温控制系统仿真与程序源码设计(DS18B20传感器) 基于单片机PID算法的恒温控制系统仿真与程序源码设计(DS18B20传感器) 基于单片机PID算法的恒温控制系统仿真与程序源码设计(DS18B20传感器) 基于单片机PID算法的恒温控制系统仿真与程序源码设计(DS18B20传感器) 基于单片机PID算法的恒温控制系统仿真与程序源码设计(DS18B20传感器) 基于单片机PID算法的恒温控制系统仿真与程序源码设计(DS18B20传感器) 51单片机 仿真工程 实物图 PCB图 代码
资源推荐
资源详情
资源评论
收起资源包目录
基于单片机PID算法的恒温控制系统仿真与程序源码设计(DS18B20传感器).zip (32个子文件)
基于单片机PID算法的恒温控制系统仿真与程序源码设计(DS18B20传感器)
1DS18B20 控温 源程序
Test.M51 26KB
Test_uvproj.bak 13KB
Test.build_log.htm 1005B
NB1600.C 8KB
Test.uvproj 14KB
STARTUP.LST 14KB
Test.pdsprj.DESKTOP-9PH0PO4.PC.workspace 4KB
NB1600.OBJ 24KB
Test_uvopt.bak 6KB
Test.SDF 0B
Test.pdsprj 24KB
NB1600.LST 15KB
STARTUP.A51 6KB
Test.hex 7KB
Test.uvgui.Administrator 70KB
Test 23KB
Test.uvgui_Administrator.bak 70KB
STARTUP.OBJ 749B
Test.lnp 43B
Test.uvopt 6KB
Test.uvgui.PC 88KB
Test.pdsprj.XEXGT2J4AZO5KDL.Administrator.workspace 1KB
Test.plg 273B
Last Loaded Test.DBK 122KB
1.png 68KB
4.png 652KB
3.jpg 134KB
2.png 51KB
仿真
Test.pdsprj.DESKTOP-7FSAA6I.Eric.workspace 1KB
Test.hex 7KB
Test.dsn 122KB
Test.pdsprj.XEXGT2J4AZO5KDL.Administrator.workspace 1KB
共 32 条
- 1
资源评论
2401_85184911
- 粉丝: 0
- 资源: 1
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功