当前位置:文档之家› 储罐液位控制系统程序

储罐液位控制系统程序

储罐液位控制系统——计算机控制技术课程设计①核心:单片机89s52②片外扩展:8KB RAM存储器6264,I/O口扩展8155③转换器:ADC0809,DAC0832④锁存器等:74HC373,74H377,74HC245和3-8译码器74HC138⑤输入/输出部件:6个LED,4个按键89S52的RD及PSEN用与门接在一起后送入6264的OE端,使得6264既可以作为数据存储器,也可以作为程序存储器。

①液位信号(电压值)从ADC0809的IN0引脚输入,A/D 转换后存储。

②液位给定值由键盘设定,与液位信号比较得出偏差值。

若超限,则报警,LED4现实P,同时以P1.0驱动报警器,以P1.1驱动蜂鸣器。

③按达林算法计算控制器的输出值。

④输出值经D/A 转换得到模拟电压值并输出。

⑤液位信号的电压值经标度转换后,变为液位值存储,送LED 显示。

6个LED显示如图a所示。

LED5显示H或L,LED4为超限指示,LED3~LED0显示液位值,LED1数码管加小数点,显示围为000.0~999.9。

显示器与键盘设置LED5 LED4 LED3 LED2 LED1 LED0H 1 9 9.5⑥键盘设定液位的高低报警限。

采用4键方式,4个按键的功能如图b所示。

显示与键盘循环扫描,无键按下时,LED显示实时液位,右键按下时,进入液位报警限的修改。

先按选择键方可进入修改,先按其他3个键无效。

进入修改状态后,待修改的显示位LED5闪动,按+或-键可循环选择H或L,同时后4位LED显示对应的液位值。

按确认件后调到下一个待修改的显示为LED3并闪动,按+或-键循环修改0~9数字,再按确认键调到下一位置,如此进行,知道4个数字修改完毕后退出修改状态。

在修改状态时,若不按确认键,则8秒后退出修改状态。

从视觉舒适的角度考虑,数字应为每0.4秒闪动一次。

显示器与键盘设计选择+ - 确定①数据采集:A/D转换,采样周期为10s。

②数字滤波:采用5个数平均滤波法。

③标度转换:将液位变送器的标准电压信号转换为液位值。

④动态显示:动态循环显示。

⑤键盘扫描:读键值并判断功能。

⑥控制计算:达林算法。

⑦控制输出:D/A转换。

⑧报警处理:超过高、低报警器限时驱动报警灯及蜂鸣器。

//实现程序//#include <reg52.h>#include <math.h>#define uchar unsigned char#define uint unsigned intuchar xdata *p=0x0000;uchar xdata *p1=0x2000;uint getdata;//采样值uint w=0,jishi8=0;//计数加长计时,时间uint yh,yl,ye;//液位高低限及期望值sbit jingdeng=P1^0;sbit jingsheng=P1^1;uchar code table[]={ //段码0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x76,0x73,0x38};//19个字符uchar dispbuf[4]={0,0,0,0};float e[2]={0,0},u[6]={0,0,0,0,0,0};float con=0;jingdeng=0;//警灯jingsheng=0;//,蜂鸣器初始化viod main(){void intdingshi();//定时器初始化//键盘扫描及修改设定值//void keyscan();//实时液位显示//void led();//达林算法实现,DAC控制输出//void dalin();void control();//输出控制量//报警程序//void baojing();while(1){//键盘扫描及修改设定值//keyscan();//实时液位显示//led();//达林算法实现,DAC控制输出//dalin();control();//输出控制量//报警程序//baojing();}}viod delay(uchar i) //延时{while(i--)_nop_();}//实现每八秒采样一次//void intdingshi()//定时器初始化{TMOD=0x01;IT0=1;TH0=0x3C;TL0=0xB0;//定时50msTR0=1;//启动定时器EA=1;//开中断ET0=1;}void dingshi() interrupt 1 //定时器0中断,实现八秒定时{TH0=0x3C;TL0=0xB0;//定时50msw++;jishi8++;while(w==200){p=0x8000;//指针ADC地址*p=0x00;//qi dongEX0=1;//打开外部中断0,采样一次w=0;}TR0=1;//启动定时器}void waibu() interrupt 0 //外部中断0,实现ADC采样5次,取平均值{uint i=0,a5=0;p=0x8000;//指针ADC地址P0=*p;getdata=P0;a5=a5+getdata;i++;if(i==5){qy=a5/5;//平均滤波i=0;a5=0;}}//实时液位显示//void led(){dispbuf[3]=qy/100;dispbuf[2]=(qy%100)/10;dispbuf[1]=(qy%100)%10;dispbuf[0]=int((qy-dispbuf[3]*100-dispbuf[2]*10-dispbuf[0])*10); p=0xC000;*p=0xFE;p1=0xE000;*p1=table[dispbuf[0]];delay(5);*p=(*p)<<1;*p1=table[dispbuf[1]];delay(5);*p=(*p)<<1;*p1=table[dispbuf[2]];delay(5);*p=(*p)<<1;*p1=table[dispbuf[3]];delay(5);}//达林算法实现,DAC控制输出//void dalin(){e[0]=qy-ye;//求出输入误差u[0]=0.9355*u[1]+0.0645*u[5]+0.8377*e[0]-0.8054*e[1];con=u[0],//数字控制量输出e[1]=e[0];u[5]=u[4];u[4]=u[3];u[3]=u[2];u[2]=u[1];u[1]=u[0];}void control()//输出控制量{p=0x6000;*p=con;}//键盘扫描及修改设定值//void keyscan(){uint a=16,b=dispbuf[3],c=dispbuf[2],d=dispbuf[1],e=dispbuf[0];//记录各位设定值p=0xA000;P0=*p;if(P0==0xfe)//说明开始修改,键0{void dispplay(a,b,c,d,e);void dispplay(a,b,c,d,e);//延时10msp=0xA000;P0=*p;if(P0==0xfe)p1=0xc000;//字位*p1=0xdf;//led5位选p1=0xe000;//字段disp(18);//初始显示"L"P0=*p;while(P0!=0xf7)//键3{void dispplay(a,b,c,d,e);void dispplay(a,b,c,d,e);//延时10msp=0xA000;P0=*p;//读键盘if(P0==0xfd)//键1{a++;if(a>=18)a=18;}elseif(P0==0xfb)//键2{a--;if(a<=16)a=16;}p1=0xc000;//字位*p1=0xdf;p1=0xe000;//字段disp(a);//初始显示"L"if(jishu8>=160)//超时跳出扫描{jishu8=0;goto keyz; }}key2: P0=*p;while(P0!=0xf7){void dispplay(a,b,c,d,e);//延时10msvoid dispplay(a,b,c,d,e);p=0xA000;P0=*p;if(P0==0xfd){b++;if(b>=9)b=9;}elseif(P0==0xfb){if(b>=1);b--;else b=0;}p1=0xc000;//字位*p1=0xf7;//led3位选p1=0xe000;//字段disp(b);//初始显示"L"if(jishu8>=160){jishu8=0;goto keyz;}}key3: P0=*p;while(P0!=0xf7){void dispplay(a,b,c,d,e);void dispplay(a,b,c,d,e);//延时10msp=0xA000;P0=*p;if(P0==0xfd){c++;if(c>=9)c=9;}elseif(P0==0xfb){if(c>=1);c--;else c=0;}p1=0xc000;//字位*p1=0xfb;//led2位选p1=0xe000;//字段disp(c);//初始显示"L"if(jishu8>=160){jishu8=0;goto keyz;}}key4: P0=*p;while(P0!=0xf7)//键3{void dispplay(a,b,c,d,e);void dispplay(a,b,c,d,e);//延时10msp=0xA000;P0=*p;if(P0==0xfd)//键1{d++;if(d>=9)d=9;}elseif(P0==0xfb)//键2{if(d>=1);d--;else d=0;}p1=0xc000;//字位*p1=0xfd;//led1位选p1=0xe000;//字段disp(d);//初始显示"L"if(jishu8>=160){jishu8=0;goto keyz;}}key5: P0=*p;while(P0!=0xf7){void dispplay(a,b,c,d,e);void dispplay(a,b,c,d,e);//延时10msp=0xA000;P0=*p;if(P0==0xfd){e++;if(e>=9)e=9;}elseif(P0==0xfb){if(e>=1);e--;else e=0;}p1=0xc000;//字位*p1=0xfe;//led0位选p1=0xe000;//字段disp(e);//初始显示"L"if(jishu8>=160){jishu8=0;goto keyz;}if(a==18)yl=b*100+c*10p+d+e*0.1;//液位低限sheding elseif(a==16)yh=b*100+c*10p+d+e*0.1; //液位高限elseif(a==17)ye=b*100+c*10p+d+e*0.1; //液位期望值}keyz: return}}disp(uint x){*p1=table[x];}//扫描时液位显示,充当延时除颤程序//void dispplay(uint x0,uint x1,uint x2,uint x3,uint x4,) {p=0xC000;*p=0xFE;p1=0xE000;*p1=table[x1];delay(5);*p=(*p)<<1;*p1=table[x2];delay(5);*p=(*p)<<1;*p1=table[x3];delay(5);*p=(*p)<<1;*p1=table[x4];delay(5);*p=(*p)<<2;*p1=table[x0];}//报警程序//void baojing(){while(qy>=qh||qy<=ql){jingdeng=~jingdeng;jingsheng=1;p=0xC000;*p=0xef;p1=0xe000;*p1=table[17];delay(5000);}}。

相关主题