资源描述
储罐液位控制系统 计算机控制技术课程设计 核心:单片机 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为超限指示,LED3LED0显示液位值,LED1数码管加小数点,显示范围为000.0999.9。 显示器与键盘设置LED5 LED4 LED3 LED2 LED1 LED0 H 1 9 9. 5键盘设定液位的高低报警限。采用4键方式,4个按键的功能如图b所示。显示与键盘循环扫描,无键按下时,LED显示实时液位,右键按下时,进入液位报警限的修改。先按选择键方可进入修改,先按其他3个键无效。进入修改状态后,待修改的显示位LED5闪动,按+或-键可循环选择H或L,同时后4位LED显示对应的液位值。按确认件后调到下一个待修改的显示为LED3并闪动,按+或-键循环修改09数字,再按确认键调到下一位置,如此进行,知道4个数字修改完毕后退出修改状态。在修改状态时,若不按确认键,则8秒后退出修改状态。从视觉舒适的角度考虑,数字应为每0.4秒闪动一次。 显示器与键盘设计 选择+-确定数据采集:A/D转换,采样周期为10s。数字滤波:采用5个数平均滤波法。标度转换:将液位变送器的标准电压信号转换为液位值。动态显示:动态循环显示。键盘扫描:读键值并判断功能。控制计算:达林算法。控制输出:D/A转换。报警处理:超过高、低报警器限时驱动报警灯及蜂鸣器。 /实现程序/#include #include #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=P10;sbit jingsheng=P11;uchar code table= /段码0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x76,0x73,0x38;/19个字符uchar dispbuf4=0,0,0,0;float e2=0,0,u6=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;/定时50ms TR0=1;/启动定时器 EA=1;/开中断 ET0=1; void dingshi() interrupt 1 /定时器0中断,实现八秒定时 TH0=0x3C; TL0=0xB0;/定时50ms w+; jishi8+; while(w=200) p=0x8000;/指针ADC地址*p=0x00;/qi dong EX0=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() dispbuf3=qy/100; dispbuf2=(qy%100)/10; dispbuf1=(qy%100)%10; dispbuf0=int(qy-dispbuf3*100-dispbuf2*10-dispbuf0)*10); p=0xC000; *p=0xFE; p1=0xE000; *p1=tabledispbuf0; delay(5); *p=(*p)1; *p1=tabledispbuf1; delay(5); *p=(*p)1; *p1=tabledispbuf2; delay(5); *p=(*p)=18) a=18; elseif(P0=0xfb)/键2 a-; if(a=160)/超时跳出扫描 jishu8=0; goto keyz; key2: P0=*p; while(P0!=0xf7) void dispplay(a,b,c,d,e);/延时10ms void 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);/延时10ms p=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);/延时10ms p=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);/延时10ms p=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=tablex;/扫描时液位显示,充当延时除颤程序/void dispplay(uint x0,uint x1,uint x2,uint x3,uint x4,) p=0xC000; *p=0xFE; p1=0xE000; *p1=tablex1; delay(5); *p=(*p)1; *p1=tablex2; delay(5); *p=(*p)1; *p1=tablex3; delay(5); *p=(*p)1; *p1=tablex4; delay(5); *p=(*p)=qh|qy=ql) jingdeng=jingdeng; jingsheng=1; p=0xC000; *p=0xef; p1=0xe000; *p1=table17; delay(5000);
展开阅读全文