标题: 51单片机PID液位控制系统设计 程序PCB和实训报告论文都有 [打印本页]
作者: pdh 时间: 2016-1-11 10:06
标题: 51单片机PID液位控制系统设计 程序PCB和实训报告论文都有
用51单片机做的PID液位控制系统 程序PCB和设计实训报告一应俱全.
51单片机PID液位控制系统设计所有文件下载(包含程序 论文 pcb文件):
液位控制.rar
(453.09 KB, 下载次数: 266)
以下是单片机pid液位控制系统设计的论文预览:
桂林电子科技大学信息科技学院
《自动化仪表与过程控制》实训报告
班级:自动化一班
学号: 00000000000000
姓 名:00
指导教师:xxx
2015 年 6 月 15 日
实训题目:液位控制系统
1 系统设计
1.1 设计要求
1.1.1 基本原理
水箱为双容水箱,仅使用一个作为被控对象,即单容液位控制(将水箱设为自衡系统),水箱采用水泵进行给水,水泵为12V直流电机控制,可采用PWM方式。液位传感器为压力式,输出为电压信号。设计调节器(模拟或数字式),能够根据用户设定,将水位控制在要求值(采用PID或PI规律)。
1.1.2 性能指标要求
1、设计制作硬件系统电路,标记姓名学号及制作日期;
2、实现水泵的控制、信号检测(显示)及调节器控制规律;
3、系统能够尽快的克服扰动;
1.1.3 设计方法与步骤
1、根据设计基本原理和性能指标要求选择总体方案,画出设计框图;
2、参阅相关资料,根据设计框图进行电路的设计;
3、列出元件清单;
4、画原理图,布PCB图,并制作电路板;
5、根据器件由小到大的顺序安装电路,并进行自检测试;
6、数学建模、设计合适的控制参数;
7、调试所制作的电路;
1.2 设计思路及设计框图
1.2.1设计思路
调节器和PWM信号产生用51单片机执行,单片机与驱动模块之间使用光电耦合器进行隔离。液位变送器根据水压不同输出模拟电流信号(0-20mA),然后经250欧电阻转成0-5V的电压信号经过ADC0809芯片转换成数字信号,再把数字信号传给单片机的P1口,用单片机进行数据处理。用两位数码管显示AD值(调试用的),经多次测量AD值所对应的液位高度,记下多组数据,再用MATLAB,Polyfit(x,y,n)
函数,拟合曲线,得到线性关系,然后再把之前显示AD值的两位数码管用来显示拟合出来的AD值所对应的液位。另外两位数码管则用来显示设定液位的高度。
水泵的驱动用达林顿三级管驱动,可以通过单片机模拟出来的PWM控制水泵的转速。
1.2.2总体设计框图
2 各个模块的程序的设计
1、PID算法控制:
#include"PID.H"
/*PID参数初始化*/
voidIncPIDInit(void)
{
//sptr->SumError = 0;
sptr->LastError = 0; //Error[-1]
sptr->PrevError = 0; //Error[-2]
sptr->Proportion = 100; //比例常数Proportional Const
sptr->Integral = 1;//积分常数Integral Const
sptr->Derivative = 1; //微分常数Derivative Const
}
/*增量式 PID 计算部分*/
intIncPIDCalc(int NextPoint)
{
register int iError,iIncpid; //当前误差
iError = sptr->SetPoint - NextPoint;//增量计算
iIncpid = sptr->Proportion *iError//E[k]项
-sptr->Integral*sptr->LastError//E[k-1]项
+ sptr->Derivative *sptr->PrevError; //E[k-2]项
//存储误差,用于下次计算
sptr->PrevError = sptr->LastError;
sptr->LastError = iError;
//返回增量值
return(iIncpid);
}
2、ADC0809模数转换:
voidInitAdc(void) //ADC初始化
{
ST=0;
OE=0;
ST=1;
ST=0;
}
voidAdcObtainData(void) //ADC或出数据
{
while(EOC==0);
OE=1;
getdata=P1;
YEWEI=5*(getdata-50);
SHI=YEWEI>>4;
GE=YEWEI&0X0F;
OE=0;
DelayMs(200); //延时防止采集频率过快
}
3、数码管显示模块:
voidTimer1Interrupt(void) interrupt 3
{
TH1 = 0x0EC;
TL1 = 0x78;
switch(c)
{
case0:P2=0X8f;P0=dofly_DuanMa[0];break;//显示2位液位值break;
case1:P2=0X4f;P0=dofly_DuanMa[YEWEI/100];break;
case2:P2=0X2f;P0=dofly_DuanMa[YEWEI%100/10];break;//显示2位数液位break;
case3:P2=0X1f;P0=dofly_DuanMa[YEWEI%10];break;
}
c++;
if(c==4){c=0;}
d++;
if(d==400){d=0;}
}
4、按键控制模块:
voidSheZhi(void)//按键设置液位高度
{
if(KeyPlus==0) //液位增加按键
{
DelayMs(100);//防止按键抖动
while(!KeyPlus);
KZ++;
}
if(KeyMinus==0) //液位降低按键
{
DelayMs(100);//防止按键抖动
while(!KeyMinus);
KZ--;
}
}
5、PWM电机控制模块:
voidjishi(void) interrupt 1 using 1 //定时器中断0输出PWM
{
TH0 = (65536-50)/256; //求模 0.05ms
TL0 = (65536-50)%256; //求余
/*用来电机调速*/
speed_L++;
if(speed_L < PWM_L) //调速给出高电平占空比
{
ENA= 0;
}
else if(speed_L > PWM_L) //调速给出低电平占空比
{
ENA= 1;
}
if(speed_L == 256) //1S周期至256时清零
{
speed_L= 0;
ENA= 0;
}
CLK=~CLK;
}
3 制作与调试过程
①制作:本次实训在制作电路板的过程中,根据所查找的资料提供的原理图进行修改,从原理图中减去了很多的元件。然后用AD软件画出原理图,接着转为PCB,手动布线,并将PCB转印在板子上,腐蚀、打孔后,完成实训电路板。
②调试:当电路板制作完成后,需要调试电路板能否完成实训要求的功能,在调试的过程中我发现了数码管是共阳的,随后在P2口焊上1K上拉电阻,本次实训没有用到三极管导致数码管不够亮,但是并不影响参数整定,而且晶振也换为12兆。
4功能测试
4.1测试仪器和设备
万用表、传感器设备、双容水箱
4.2性能指标测试
①实现液位标定(误差%5)
②完成参数的整定
5.硬件工作模块
51最小系统
最小系统是指是指用最少的元件组成的单片机可以工作的系统,它包括单片机、复位电路和时钟电路。
复位电路:单片机第9脚为复位信号引脚(RST),复位信号高电平有效,但高电平维持时间必须维持在24个振荡周期以上才能完成复位。系统使用12MHZ晶振则复位需要两个机器周期。通电瞬间RC电路充电,RST引脚得到了一定脉宽的信号,只要信号脉宽维持在复位允许时间,单片机即可复位。
起振电路:在外部连接晶振和起振电容便可构成内部振荡电路,产生振荡时钟脉冲。
单片机:AT89S52,它是一种低功耗、高性能CMOS8位微控制器,具有8K系统可编程Flash储存器。
A/D转换
ADC0809是一款8通道复用的8位AD转换器,数据获取的关键部分是它的八位8位模/数转换器。这个部分由三部分组成:266R的阶梯网络,连接逼近的电阻和比较器。ADC0809为8路模拟信号的份上采集转换器。片内有8路模拟选通开关,以及相应的通道抵制锁存用译码电路,其转换时间为100US左右。
电机模块
5.实训心得
经过本次实训,让我对过程控制这一门课有了更深刻的了解。特别是双位控制和PID控制,不仅对理论有了跟深刻的了解,还对它们实际应用有了一定的认识。这次实训首先设计原理图和布局PCB,然后做板子。在设计原理图的时候没有注意到数码管是共阳的,也没加三极管,导致数码管很暗,后来在接数码管位选的IO口上接了一个1K的上拉电阻,有效的解决了这个问题。其中本次实训的关键在于调试,这也是最难,它不仅考验了知识,还考验了耐心。调试主要包括了测量参数,利用参数经数学计算工具拟合出曲线,还有就是不断的修改程序,首先就是调节P值,不让I作用,让水位能在设定值的附近比较稳定的上下波动,出现等幅振荡最好。最后加入I调节,调整I参数,是系统跟加好的稳定。不过本次实训中我只调了P,因为调了P水位也能比较稳定的在设定值的附近微小的波动。
附录1:原件清单
51单片机
ADC0809 数码管
达林顿三极管
四个独石电容
两个瓷片电容
多个电阻 RS232串口芯片
DB9
1K上拉电阻
若干插针
接线柱
12M晶振 三个按键
一个极性电容
光耦
下载接口
附录2:程序清单
- #include <reg51.h>
- #define uchar unsigned char
- #define uint unsigned int
- uint c=0; //获取液位AD值,
- unsigned char code dofly_DuanMa[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,
- 0x90,0X88,0X83,0Xc6,0Xa1,0X86,0X8e};// 显示段码值0~9
- /*ADC0809*/
- sbit EOC=P3^2; //转换结束信号
- sbit OE=P3^3; //允许输出信号
- sbit ST=P3^4; //转换启动信号
- sbit CLK=P3^5; //时钟
- /*按键*/
- sbit KeyPlus=P2^0;//按键加
- sbit KeyMinus=P2^1;//按键减
- /*驱动*/
- sbit ENA=P3^6;//进出水控制
- double KZ=100;
- double YEWEI; //获取液位AD对应液位值,
- uint rout; // PID Response (Output)
- uint getdata;
- uint PWM_L;
- uint speed_L = 0;
- void DelayUs2x(unsigned char t)
- {
- while(--t);
- }
- void DelayMs(unsigned char t)
- {
- while(t--)
- {
- //大致延时1mS
- DelayUs2x(245);
- DelayUs2x(245);
- }
- }
- void InitTimer0(void)
- {
- TMOD = 0x11;
- TH0 = (65536-500)/256; //求模 0.5ms
- TL0 = (65536-500)%256; //求余
- TH1 = 0x0EC;
- TL1 = 0x78;
- EA = 1;
- ET0 = 1;
- TR0 = 1;
- ET1 = 1;
- TR1 = 1;
- }
- void InitAdc(void) //ADC初始化
- {
- ST=0;
- OE=0;
- ST=1;
- ST=0;
- }
- void AdcObtainData(void) //ADC或出数据
- {
- while(EOC==0);
- OE=1;
- getdata=P1;
- if(getdata<53)
- {
- getdata=53;
- }
- YEWEI=(double)5*((double)(getdata)-53);//AD值是70就对应100mm的液位高度
- OE=0;
- DelayMs(200); //延时防止采集频率过快
- }
- typedef struct PID
- {
- int SetPoint;//设定目标Desired Value
- //long SumError; //误差累计
- double Proportion; //比例常数Proportional Const
- double Integral; //积分常数Integral Const
- double Derivative; //微分常数Derivative Const
- int LastError; //Error[-1]
- int PrevError; //Error[-2]
- }
- PID;
- static PID sPID;
- static PID *sptr = &sPID;
- /*PID参数初始化*/
- void IncPIDInit(void)
- {
- //sptr->SumError = 0;
- sptr->LastError = 0; //Error[-1]
- sptr->PrevError = 0; //Error[-2]
- sptr->Proportion = 5; //比例常数Proportional Const
- sptr->Integral = 0;//积分常数Integral Const
- sptr->Derivative = 0; //微分常数Derivative Const
-
- }
-
- /*增量式 PID 计算部分*/
- int IncPIDCalc(int NextPoint)
- {
- register int iError,iIncpid; //当前误差
- iError = sptr->SetPoint - NextPoint;//增量计算
- iIncpid = sptr->Proportion * iError//E[k]项
- - sptr->Integral*sptr->LastError//E[k-1]项
- + sptr->Derivative * sptr->PrevError; //E[k-2]项
- //存储误差,用于下次计算
- sptr->PrevError = sptr->LastError;
- sptr->LastError = iError;
- //返回增量值
- return(iIncpid);
- }
- void SheZhi(void)//按键设置液位高度
- {
- if(KeyPlus==0) //液位增加按键
- {
- DelayMs(100); //防止按键抖动
- while(!KeyPlus);
- KZ=KZ+10;
- }
- if(KeyMinus==0) //液位降低按键
- {
- DelayMs(100); //防止按键抖动
- while(!KeyMinus);
- KZ=KZ-10;
- }
- }
- void Control(void) //液位控制
- {
- InitAdc();
- AdcObtainData();
- if(KZ>YEWEI)
- {
- if(KZ-YEWEI>50)
- {
- PWM_L=250;
- }
- else
- {
- rout=IncPIDCalc(YEWEI);
- PWM_L=(uchar)(rout);
- if(PWM_L>80)
- PWM_L=80;
- }
- }
- }
- void main(void)
- {
- InitTimer0();
- IncPIDInit(); //初始化PID
- while(1)
- {
- sptr->SetPoint = KZ ;
- SheZhi(); //调用设置函数
- Control();//调用控制函
- }
- }
- void jishi(void) interrupt 1 using 1 //定时器中断0输出PWM
- {
- TH0 = (65536-500)/256; //求模 0.5ms
- TL0 = (65536-500)%256; //求余
- /*用来水泵调速*/
- speed_L++;
- if(speed_L < PWM_L) //左轮PWM调速给出高电平占空比
- {
- ENA = 0;
- }
- else if(speed_L > PWM_L) //左轮PWM调速给出低电平占空比
- {
- ENA = 1;
- }
- if(speed_L == 300) //周期至300时清零
- {
- speed_L = 0;
- ENA = 0;
- }
- /*ADC时钟*/
- CLK=~CLK;
- }
- void Timer1Interrupt(void) interrupt 3
- {
- TH1 = 0x0ec;
- TL1 = 0x78;
- switch(c)
- {
- case 0:P2=0X8f;P0=dofly_DuanMa[((uint)YEWEI)/16];break;//显示2位当前液位值break;
- case 1:P2=0X4f;P0=dofly_DuanMa[((uint)YEWEI)%16];break;
- case 2:P2=0X2f;P0=dofly_DuanMa[(uint)KZ/16];break;//显示设定液位值break;
- case 3:P2=0X1f;P0=dofly_DuanMa[(uint)KZ%16];break;
- }
- c++;
- if(c==4){c=0;}
- }
复制代码
作者: 陈小生 时间: 2016-4-14 14:12
在么
如果把输出量改为控制电机的正反转 当液位高于设定值是电动机正转 当液位低于设定值时电动机反转 这个程序要怎么弄啊
作者: 陈小生 时间: 2016-4-14 14:13
能给我一个你的联系方式么
作者: waz 时间: 2016-5-9 14:11
感谢楼主贡献资源
作者: jiyidewang 时间: 2017-3-9 18:50
怎样实现温度和液位一起控制啊?
作者: 图样图森破2号 时间: 2017-3-15 11:21
怎么在里面填加多个传感器实现PID控制
作者: zzzzk 时间: 2017-3-19 23:14
没有protues原理图?
作者: zqy181818 时间: 2017-3-20 11:40
感谢楼主你的分享
作者: linnyshow 时间: 2017-7-23 16:12
感谢楼主。。。。
作者: 风中飘飘 时间: 2017-7-24 10:22
谢谢,支持一下
作者: a865138312 时间: 2017-9-18 11:00
感谢分享,多多支持
作者: 白水带老司机 时间: 2017-12-5 09:46
非常感谢,支持一下
作者: 新人1 时间: 2017-12-16 19:18
如果用PIC该怎么控制?
作者: 新人1 时间: 2017-12-17 19:21
有没有proteus?
作者: GROW 时间: 2017-12-20 20:33
这个如何利用电机的正反转作为输出?
作者: simple666 时间: 2018-6-14 14:53
能简单解释一下整个电路的工作原理吗?
作者: 894977238 时间: 2018-6-20 22:27
感谢楼主
作者: 李景丽 时间: 2019-5-31 20:49
非常感谢
作者: Angelaboby 时间: 2019-7-17 08:45
浪费黑币,谨慎下载
作者: 南-wgw 时间: 2024-3-27 10:32
能有温度控制就好了
作者: 菲菲哥 时间: 2025-3-16 21:58
有没有proteus?
作者: 菲菲哥 时间: 2025-3-16 23:17
有仿真吗?
作者: 菲菲哥 时间: 2025-3-17 21:36
有仿真吗
欢迎光临 (http://www.51hei.com/bbs/) |
Powered by Discuz! X3.1 |