Ⅰ 如何用PID算法编程,使单片机通过控制继电器来实现恒温功能。
/***********************************************************************
PID温度控制程序
程序说明:
系统上电后显示 “--温度”
表示需要先设定温度才开始进行温度检测
温度设定完毕后程序才开始进行PID温控
***********************************************************************/
#include <reg52.h>
#include <absacc.h>
#include"DS18B20.H"
#include"PID.H"
#define uchar unsigned char
#define uint unsigned int
unsigned char code tab[]=
{
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xBF
}
;
/*个位0~9的数码管段码*/
unsigned char code sao[]=
{
0x7f,0xbf,0xdf,0xef
}
;
//扫描码
uchar set=30,keyflag=1 ; //set初始化为30° keyflag为进入温度设定的标志位
//4个按键使用说明
sbit key_out=P1^0 ; //用于温度设定后的退出
sbit key_up=P1^1 ; //设定温度加
sbit key_down=P1^2 ; //设定温度减
sbit key_in=P1^3 ; //在程序的运行中如需要重新设定温度 按下此键才能进入设置模式并且此时是停在温度控制的,按下key_out键后才表示设定完毕
void Show_key();
/***********************************************************/
void delays(unsigned char k)
{
unsigned char i,j ;
for(i=0;i<k;i++)
for(j=0;j<50;j++);
}
/*********************************************************
//数码管显示函数
P0口 作为数据口
P2口的低四位作为扫描口
变量 x表示扫描
d表示是否要加小数点 为1是 为0不加
y表示传递的数值
*********************************************************/
LCD_disp_char(uchar x,bit d,uchar y)
{
P2=0XFF ;
P0=0xFF ;
if(d==0)
P0=tab[y];
else
P0=tab[y]&0x7f ; //与上0x7f表示是否要加小数点
P2=sao[x]; //打开扫描端号
}
/*********************************************************
按键扫描
*********************************************************/
void keyscan(void)
{
if(key_in==0) //按键进入函数
{
delays(10); //延时消抖 (以下同)
if(key_in==0)
{
while(key_in==0)
{
Show_key(); //如果一直按着键不放 就一直显示在当前状态 (以下同)
}
keyflag=1 ; //按键标志位
}
}
/***********************/
if(key_out==0) //按键退出
{
delays(10);
if(key_out==0)
{
while(key_out==0)
{
Show_key();
}
keyflag=0 ;
set_temper=set ;
}
}
/*************************/
if(key_up==0) //设定温度的加
{
delays(10);
if(key_up==0)
{
while(key_up==0)
{
Show_key();
}
if(keyflag==1)
{
set++;
if(set>90) //如果大于90°就不在加
set=90 ;
}
}
}
/*************************/
if(key_down==0) //温度设定的减
{
delays(10);
if(key_down==0)
{
while(key_down==0)
{
Show_key();
}
if(keyflag==1)
{
set--;
if(set<30) //温度减到30°时不在往下减
set=30 ;
}
}
}
}
/*********************************************************************
按键按下时的显示函数
***********************************************************************/
void Show_key()
{
output=1 ;
LCD_disp_char(3,0,10); //显示 -
delays(3);
LCD_disp_char(2,0,10); //显示- (表示温度设定 )
delays(3);
LCD_disp_char(1,0,set/10); //显示温度十位
delays(3);
LCD_disp_char(0,0,set%10); //显示温度个位
delays(3);
}
/*****************************************************************/
void main()
{
unsigned int tmp ;//声明温度中间变量
unsigned char counter=0 ;
PIDBEGIN(); //PID参数的初始化
output=1 ; //关闭继电器输出
while(1)
{
keyscan();
if(keyflag)
{
Show_key(); //显示温度设定
}
else
{
if(counter--==0)
{
tmp=ReadTemperature();//每隔一段时间读取温度值
counter=20 ;
}
LCD_disp_char(3,0,tmp/1000); //显示温度十位
delays(3);
LCD_disp_char(2,1,tmp/100%10); //显示温度个位
//显示小数点
delays(3);
LCD_disp_char(1,0,tmp/10%10); //显示温度小数后一位
delays(3);
LCD_disp_char(0,0,tmp%10);//显示温度小数后二位
delays(3);
P2=0XFF ;
P0=0xff ;
compare_temper(); //比较温度
}
}
}
/**********************************************************************************************************************************************/
//PID算法温控C语言2008-08-17 18:58
#ifndef _PID_H__
#define _PID_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)
sbit output=P1^4;
unsigned char high_time,low_time,count=0 ;
//占空比调节参数
unsigned char set_temper ;
void PIDInit(struct PID*pp)
{
memset(pp,0,sizeof(struct PID)); //PID参数初始化全部设置为0
}
unsigned int PIDCalc(struct PID*pp,unsigned int NextPoint)
{
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()
{
unsigned char i ;
//EA=0;
if(set_temper>temper)
{
if(set_temper-temper>1)
{
high_time=100 ; //大于1°不进行PID运算
low_time=0 ;
}
else
{ //在1°范围内进行PID运算
for(i=0;i<10;i++)
{
//get_temper();
rin=s;
// Read Input
rout=PIDCalc(&spid,rin); //执行PID运算
// 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) //当实际温度大于设置温度时
{
if(temper-set_temper>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);
//EA=1;
}
}
}
/*****************************************************
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=0xe0 ;
}
void PIDBEGIN()
{
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
}
#endif
转自他人程序。
Ⅱ 基于单片机的恒温控制系统
我刚帮别人做了一个,是按这个要求做的,你可以提出任意修改要求。
程序是汇编的,已经调试通过。
ProteUS仿真文件下载地址:
推荐:70电加热PRE.rar( http://ishare.iask.sina.com.cn/f/7033603.html )
; 设计基于单片计算机的温度控制器。用于控制电加热炉的温度。具体要求如下:
; 1. 温度连续可调,范围为30℃~150℃
; 2. 超调量σ%≤20%
; 3. 温度误差≤±0.5℃
; 4. 人-机对话方便
; 5. 控制算法采用PID或改进的PID或其他算法.
; (我用的是AT89C52的单片机:
; A.电加热炉经由温度传感器测量后,
; 通过V/F变换器的模数转换,
; 将电压或电流量转换为数字信号进入单片机内,
; 然后通过移位寄存器和译码器的信息转换,
; 通过显示驱动器来进行LED数码管的温度显示;
; B.单片机也通过双向可控硅来控制炉内的温度;
; C.用户通过按键来设置温度上限、下限值)
Ⅲ 怎样用PID算法对恒温箱的温度进行控制,求相关的51单片机汇编程序
本设计要求:本温度控制系统为以单片机为核心,实现了对温度实时监测和控制,实现了控制的智能化。设计恒温箱温度控制系统,配有温度传感器,采用DS18B20数字温度传感器,无需数模拟∕数字转换,可直接与单片机进行数字传输,采用了PID控制技术,可以使温度保持在要求的一个恒定范围内,配有键盘,用于输入设定温度;配有数码管LED用来显示温度。
技术参数和设计任务:
1、利用单片机AT89C2051实现对温度的控制,实现保持恒温箱在最高温度为110℃。
2、可预置恒温箱温度,烘干过程恒温控制,温度控制误差小于±2℃。
3、预置时显示设定温度,恒温时显示实时温度,采用PID控制算法显示精确到0.1℃。
4、温度超出预置温度±5℃时发出声音报警。
5、对升、降温过程没有线性要求。
6、温度检测部分采用DS18B20数字温度传感器,无需数模拟∕数字转换,可直接与单片机进行数字传输
7、人机对话部分由键盘、显示和报警三部分组成,实现对温度的显示、报警。
需要的话联系用户名扣扣
Ⅳ 利用单片机制作一个可调节的恒温装置,有人能给一些思路吗
一个温度传感器,一套驱动电路,一套加热装置(如电阻丝)。
温度传感器一般输出的是电压信号,接入单片机的AD管脚。
驱动电路驱动加热装置,一般接上单片机的PWM输出管脚。
单片机采到温度传感器的信号,将其转化为具体的温度值,然后依据温度值可以采用PID来调节PWM波来驱动加热器。
Ⅳ 基于单片机恒温箱控制系统
只有图,没有程序。从图来看,端口配置不好,单一功能要充分利用端口,原则上P0口作为段吗,这里,如果作为位码的话可以节省一级驱动,应为P0口的驱动能力较强,极力推鉴1051-4051(端口驱动20mA),降低硬件成本,减少软件编程量。这里有一个仿真器带的温度显示程序。你参考一下,如果加上控制,在程序合适位置加入判断语句如if(****,P1.x=?),再配置一个输出端口,就行了。程序如下,附仿真图。
#include<reg52.h>
#include<intrins.h>
#defineucharunsignedchar
#defineuintunsignedint
sbitDATA=P1^0;//DS18B20接入口
ucharcodetable[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
char,shi,ge;//定义变量
/*延时子函数*/
voiddelay(uintnum)
{
while(num--);
}
/*************DS18b20温度传感器函数*********************/
voidInit_DS18B20(void) //传感器初始化
{
ucharx=0;
DATA=1; //DQ复位
delay(10); //稍做延时
DATA=0; //单片机将DQ拉低
delay(80); //精确延时大于480us//450
DATA=1; //拉高总线
delay(20);
x=DATA; //稍做延时后如果x=0则初始化成功x=1则初始化失败
delay(30);
}
//读一个字节
ReadOneChar(void)
{
uchari=0;
uchardat=0;
for(i=8;i>0;i--)
{
DATA=0;//给脉冲信号
dat>>=1;
DATA=1;//给脉冲信号
if(DATA)
dat|=0x80;
delay(8);
}
return(dat);
}
//写一个字节
voidWriteOneChar(unsignedchardat)
{
uchari=0;
for(i=8;i>0;i--)
{
DATA=0;
DATA=dat&0x01;
delay(10);
DATA=1;
dat>>=1;
}
delay(8);
}
//读取温度
intReadTemperature(void)
{
uchara=0;
ucharb=0;
intt=0;
floattt=0;
Init_DS18B20();
WriteOneChar(0xCC);//跳过读序号列号的操作
WriteOneChar(0x44);//启动温度转换
Init_DS18B20();
WriteOneChar(0xCC);//跳过读序号列号的操作
WriteOneChar(0xBE);//读取温度寄存器等(共可读9个寄存器)前两个就是温度
a=ReadOneChar(); //低位
b=ReadOneChar(); //高位
t=b;
t<<=8;
t=t|a; //得到温度值的各个位的值
t=t*0.0625; //得到实际的温度值
return(t);
}
/*显示子函数*/
voiddisplay(int,intshi,intge)
{
P0=0xff; //对数码管清零,防止串扰
P2=0xfb;
P0=table[]; //显示百位
delay(50); //一小段延时动态显示
P0=0xff; //对数码管清零,防止串扰
P2=0xf7;
P0=table[shi]; //显示十位
delay(50);
P0=0xff;
P2=0xef;
P0=table[ge]&0x7f; //显示个位
delay(100);
P0=0xff;
P2=0xdf;
P0=table[0]; //显示小数位,这里没有处理小数位,默认的为0
delay(50);
}
voidmain()
{
inttemp;
while(1)
{
temp=ReadTemperature(); //读温度
=temp/100; //获取百位
shi=temp%100/10; //获取十位
ge=temp%10; //获取个位
display(,shi,ge); //显示函数
}
}
Ⅵ 基于单片机的热水器温度控制系统
东华理工大学毕业设计(论文)
基于单片机的热水器温度控制
摘 要
温度是日常生活中不可缺少的物理量,温度在各个领域都有积极的意义。很多行业中以及日常生活中都有大量的用电加热设备,如用于加热处理的加热热水器,用于洗浴的电热水器及各种不同用途的温度箱等,采用单片机对它们进行控制具有控制方便、简单、灵活性大等特点,而且还可以大幅提高被控系统的性能,从而能被大大提高产品的质量。因此,智能化温度控制技术正被广泛地应用。
本温度设计采用现在流行的AT89C51单片机为控制器,用PID控制方法,再配以其他电路对热水器的水温进行控制。
关键词:89C51; PID; 温度控制
I
1/41页
东华理工大学毕业设计(论文)
ABSTRACT
Temperature is essential physical in daily life ,and in various fields has positive implications.A lot of businesses and daily lives have a lot of electric heating equipment.Such as electric water heater for bathing and variety of different uses of the temperature boxes. MCU to control them with easy to control,simple,flexibility and other characteristics,also can significantly improve the performance of the controlled system,which can be greatly improved proct quality. Therefore,intelligent temperature control technology is being widely used.
The temperature control design uses the now popular AT89C51 MCU controller,with PID control method, which together with