基于51单片机的压力过程控制系统设计说明
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
东北大学分校自动化工程系
《过程控制系统》课程设计
设计题目:智能化压力测量仪设计
学生:玲娜
专业:测控技术与仪器
班级学号: 5091030
指导教师:宋爱娟
设计时间:2011.6.18-2011.7.1
前言............................................................................. (3)
一、设计任务书................................................................... .. (4)
二、器件选择................................................................... (4)
2.1 压力传感器的选
择.........................................................................
(4)
2.2键盘显示控制芯片
8279.......................................................................
(6)
2.3模数转换
器.........................................................................
(7)
(1)A/D转换器ADC0809........................................................................ (8)
(2)A/D转换器ADC0808........................................................................ (9)
2.4 显示数码管 (10)
2.5 D锁存器74LS373 (11)
2.6地址锁存器74LS273 (12)
2.7 译码器74LS138 (13)
三、系统设计................................................................... .. (13)
3.1 设计思
路.........................................................................
(13)
3.2 系统硬件框
图.........................................................................
(14)
3.3 控制系统总体结
构.........................................................................
..............................,14
四、硬件设计................................................................... (15)
4.1 气压传感器MPX4115模块 (15)
4.2 温度传感器9013补偿模 (16)
4.3 数据转换模
块.........................................................................
(16)
4.4 单片机处理模
块.........................................................................
(16)
4.5 键盘显示模
块.........................................................................
(17)
五、软件设计................................................................... .. (19)
5.1 系统软件流程
图.........................................................................
(19)
5.2 软件模块分
析.........................................................................
(20)
5.2.1 压力采集模块流
程.....................................................................
(20)
5.2.2 键盘显示模
块.....................................................................
(21)
六、参考文献................................................................... .. (21)
七、结束语................................................................... (22)
附录一仿真原理图................................................................... (23)
附录二仿真程序................................................................... . (24)
前言
压力是过程控制系统中的重要测量参数之一,压力的检测和控制是使生产顺利进行和设备安全工作的必要条件。
如高压容器的压力超过额定值时便是不安全的,必须进行测量和控制。
在某些工业生产过程中,压力还直接影响产品的质量和生产效率,如生产合成氨时,氮和氢不仅须在一定的压力下合成,而且压力的大小直接影响产量高低。
此外,在一定的条件下,测量压力还可间接得出温度、流量和液位等参数。
实现智能化压力测量系统对工业生产过程的控制具有非常重要的意义。
在生产过程控制系统中,被控对象参数检测的精确与否将直接影响一个生产企业的经济利益,在以往的控制系统中,由于对环境温度、生产设备老化等影响因素的考虑较少,传感器检测到的信号往往存在偏差,造成了不可避免的损失。
而压力测量的智能化可以弥补一些外界因素对系统造成的干扰,单片机通过对外界各种干扰因素的检测、整合、处理,可以得到更理想的控制变量,可以使控制更精确也更及时。
本课设主要完成了以单片机为核心的智能化压力测量仪的设计。
课题结合了实际生产过程控制系统的相关技术特点,利用压力传感器获取被控对象指标,以温度传感器监测环境变量,由键盘输入控制该控制系统的启停及置位复位,运用芯片ADC0808实现由模拟量到数字量的转换,AT89S52单片机采集处理信号,并由芯片8279实现对LED显示的实时控制,此外,通过温度补偿电路减小了测量误差,完成对被控对象的压力实时检测,并能够根据处理结果,使系统做出实时调整,保证生产的顺利进行。
一、设计任务书
·压力传感器采用美国ICSensors公司生产的ICSl220型硅压力传感器,单片机为核心流量控制系统。
系统主要由压力传感器,单片机控制系统、对象、执行器(查找资料自行选择)等组成.
·写出压力测量过程,绘制压力测量仪组成框图
·系统硬件电路设计
单片机采用89S52;键盘显示电路采用8279方案,矩阵键盘,共阴极数码管,A/D采用ADC0808,测量温度的三极管9013作为温度补偿器件。
·编制压力测量程序:软件采用模块化程序结构设计,由压力采集程序、压力校准程序、与测量程序三部分组成。
二、器件选择
2.1 压力传感器的选择
压力传感器芯片的性能受温度的影响非常大,主要表现为零点和灵敏度随温度变化而发生漂移。
1220型是经过温度补偿的硅压阻式压力传感器,采用双列直插封装结构,适用要求成本低,性能优越,长期稳定性好的应用领域。
通过激光修正的电阻实现了0~50℃的温度补偿,还提供一个激光修正的电阻用于调节差动放大器的增益来校正传感器的压力灵敏度变化,使具有良好的互换性,互换性误差仅为±1%。
从0~2psi至0~100psi量程围均有表压,差压和绝压产品。
ICSl220系列具有如下优点:
(1)放大、校准和温度补偿;
(2)多级压力非线性修正;
(3)直接输出经放大校准的模拟信号;
(4)输出与输入电压成正比;
(5)温补围为0~70℃,满足绝大部分用户的需求;
(6)有表压、差压和绝压配置,有微压和低压等量程; ICSl220传感器性能参数图如下:
图2.1ICSl220传感器性能参数
2.2键盘显示控制芯片8279
8279 是通用的可编程键盘/显示器接口芯片。
它包含有键盘输入和显示输出两种功能,在单片机系统中应用很广泛。
8279部有键盘 FIFO (先进先出堆栈)/传感器,当键盘输入时,8279能提供自动扫描,能与按键或传感器组成的矩阵相连,接收输入信息,还能自动消除抖动并具有双键锁定保护功能。
显示RAM 容量为 16*8,即显示器最大配置可达 16 位LED 数码显示。
8279芯片特点:
(1)可同时进行键盘扫描及文字显示;
(2)键盘扫描模式(Scanned Keyboard Mode);
(3)传感器扫描模式(Scanned Sensor Mode);
(4)激发输入模式(Strobe Input Entry Mode);
(5)8乘8键盘FIFO(先进先出);
(6)具有接点消除抖动,2键锁定及N键依此读出模式;
(7)双排8位数或双排16位数的显示器;
(8)右边进入或左边进入。
16位字节显示存储器。
图 2.2
控制芯片8279引脚图
(1)数据线
DB0→DB7是双向三态数据总线,在接口电路中与系统数据总线相连,用以传送CPU 和8279之间的数据和命令。
(2)地址线
/CS=0,8279被选,当A0=1时,为命令字及状态字地址;当A0=0时,为片数据地址,故8279芯片占用2个端口地址。
(3)控制线
CLK:8279 的时钟输入线,100KHz为最佳选择。
IRQ:中断请求输出线,高电平有效。
/RD、/WR:读、写输入控制线。
SL0---SL3:扫描输出线,用来作为扫描键盘和显示的代码输出或直接输出线。
RL0---RL7:回复输入线,它们是键盘或传感器矩阵的信号输入线。
SHIFT:来自外部键盘或传感器矩阵的输入信号,它是8279键盘数据的次高位即D6位的状态,该位状态控制键盘上/下档功能。
在传感器方式和选通方式中,该引脚无用。
CNTL/S:控制/选通输入线,高电平有效。
键盘方式时,键盘数据最高位(D7)的信号输入到该引脚,以扩充键功能;选通方式时,当该引脚信号上升沿到时,把RL0---RL7数据存入 FIFO RAM 中。
OUTA0---OUTA3:通常作为显示信号的高4 位输出线。
OUTB0---OUTB3:通常作为显示信号的低4 位输出线。
/BD:显示熄灭输出线,低电平有效。
当/BD=0时将显示全熄灭
2.3模数转换器
(1) A/D模数转换芯片ADC0809
ADC0809是目前广泛使用的逐位逼近型8位单片A/D转换芯片,片含8 路模拟开关,可允许8路模拟量输入。
主要由3部分组成:模拟输入选择部分、转换器部分、输出部分。
ADC0809芯片为28引脚为双列直插式封装,ADC0809主要信号引脚功能说明如下:
IN7~IN0——八路模拟量输入通道。
ALE——地址锁存允许信号。
START——转换启动信号。
START=1转换启动。
A、B、C——地址线、通道端口选择线。
CLK——时钟信号。
ADC0809要求外接时钟频率为10kHz~1.2MHz。
通常使用频率为500KHz的时钟信号。
EOC——转换结束信号。
EOC=1,转换结束。
D7~D0——数据输出线。
OE——输出允许信号。
OE=1,输出转换得到的数据。
Vcc—— +5V电源。
Vref——参考电源参考电压用来与输入的模拟信号进行比较,作为逐次逼近的基准。
其典型值为+5V(Vref(+)=+5V, Vref(-)=-5V)。
ADC0809与MCS-51单片机的连接主要涉及两个问题。
一是8路模拟信号通道的选择,二是A/D转换完成后转换数据的传送。
转换数据的传送有定时传送方式、查询方式、中断方式这三种方式。
A、B、C的值与被选择的通道之间的关系
如下表2—1所示:
表2—1 通道选择表
实际画图时由于PROTEUS中没有ADC0809,因此用ADC0808代替。
ADC0808和ADC0809的使用接发相同,只是ADC0809的转换误差为1位,ADC0808为5位而已。
(2)A/D模数转换器芯片ADC0808
ADC0808是逐位逼近型8位模/数转换器件。
其部有一个8通道多路开关,它可以根据地址码锁存译码后的信号,只选通8路模拟输入信号中的一个进行A/D 转换。
总的不可调误差: ADC0808为±0.5LSB , ADC 0809为±1LSB。
使用时不需进行零点和满刻度调节。
ADC0808是ADC0809的简化版本,它们除精度略有差别外(前者精度为8位、后者精度为7位),功能基本相同。
图2.3 ADC0808(ADC0809)芯片引脚图
ADC0808芯片有28条引脚,采用双列直插式封装,如图2.3所示。
引脚功能如下:
(1)IN0~IN7:8路模拟量输入端。
(2)D0~D7:8位数字量输出端。
(3)ALE:地址锁存允许信号,输入,高电平有效。
(4)START: A/D转换启动脉冲输入端,输入一个正脉冲(至少100ns 宽)使其启动(脉冲上升沿使0809复位,下降沿启动A/D转换)。
(5)EOC: A/D转换结束信号,输出,当A/D转换结束时,此端输出一个高电平(转换期间一直为低电平)。
(6)OE:数据输出允许信号,输入,高电平有效。
当A/D转换结束时,此端输入一个高电平,才能打开输出三态门,输出数字量。
(7)CLK:时钟脉冲输入端。
要求时钟频率不高于640KHZ。
(8)VREF(+)和VREF(-):参考电压输入端
(9)Vcc:主电源输入端。
(10)GND:地。
(11)ADDA、ADDB、ADDC:3位地址输入线,用于选通8路模拟输入中的一路。
2.4 显示数码管
把发光二极管的阴极连在一起构成公共阴极。
使用时会共阴极接地,阳极端输入高电平的段发光二极管导通点亮,输入低电平的则不点亮。
图2.4 共阴极数字显示数码管示意图
2.5 D锁存器74LS373
在MCS-51单片机系统中,常采用74LS373作为地址锁存器使用。
其中输入端1D~8D接至单片机的P0口,输出端提供的是低8位地址,G端接至单片机的地址锁存允许信号ALE。
输出允许端OE接地,表示输出三态门一直打开。
芯片引脚图如图2.5,真值表如表2--2所示:
图2.5 74LS373芯片引脚图
表2--2 芯片74LS373真值表
工作原理:(1)1脚是输出使能OE,低电平有效,当1脚是高电平时,不管输入及锁存控制端G如何,输出Q0、Q1、Q2、Q3、Q4、Q5、Q6、Q7全部呈现高阻状态(或者叫浮空状态);(2)当1脚是低电平时,只要11脚(锁存控制端G)上出现一个下降沿,输出Q0、Q1、Q2、Q3、Q4、Q5、Q6、Q7立即呈现输入脚3、4、7、8、13、14、17、18的状态;(3)锁存端LE 由高变低时,输出端8 位信息被锁存,直到LE 端再次有效。
当三态门使能信号OE为低电平时,三态门导通,允许Q0~Q7输出,OE为高电平时,输出悬空。
当74LS373用作地址锁存器时,应使OE为低电平,此时锁存使能端C为高电平时,输出Q0~Q7 状态与输入端D1~D7状态相同;当C发生负的跳变时,输入端D0~D7 数据锁入Q0~Q7。
51单片机的ALE信号可以直接与74LS373的C连接。
2.6 地址锁存器74LS273
工作原理:(1)1脚是复位/MR,低电平有效,当1脚是低电平时,输出脚Q1、Q2、Q3 、Q4 、Q5 、Q6 、Q7全部输出0,即全部复位;(2)当1脚是高电平时,脚11(即CP)是锁存器控制端,属于上升沿触发;当11脚有一个上升沿,立即锁存输入端的电平信号,并立即呈现在输出脚Q1、Q2、Q3 、Q4 、Q5 、Q6 、Q7上。
其引脚图及真值表如下:
图2.6.1 芯片74LS273引脚图图2.6.2 芯片74LS273真值表
2.7 译码器74LS138
74LS138的管脚排列和真值表见下图。
由真值表可知,4、5、6脚是控制脚,只有当6脚为高电平而4、5脚都为低电平时,74LS138才对1、2、3脚的输入进行译码,选择和从这三个管脚输入的三位二进制码相对应的某一个输出脚输出低电平,否则所有的输出脚都是输出高电平。
图2.7 74LS138引脚图表2---3 74LS138真值表
三、系统设计
3.1 设计思路
压力传感器(1210—030G—3S)测量气缸中的压力(0~207kPa)输出电流信号(75~150mA),经A/D模数转换(结果为00000000~11111111即0~255)后给单片机,单片机进行算法处理将传感器的输出信号和测量的压力对应起来并实时显示在LED上,当所测压力大于176kPa时,放气阀打开进行放气,当所测压力小于64kPa时,放气阀关闭,进气阀给气缸充气。
此过程中若放气或充气10S 任没达到正常的压力围则进行1S报警。
当然A/D转换的启停、压力大小的判断、10S延时都由单片机来控制。
由于硬件条件有限,本设计只能着重于整个系统中的反馈回路即测量部分的设计。
本智能化压力测量仪基于ICSl220压力传感器,设计通过proteus进行软件仿真;根据设计要求,硬件部分设计以压力传感器、温度补偿电路、A/D软换芯片、单片机、LED显示电路、键盘等几部分组成。
软件部分通过C语言进行编程,实现压力测量,压力信号修正,测量数据的显示,以及外围的键盘控制,其中,外围键盘能够实现设定给定值,对外输出相应的控制信号等功能。
3.2 系统硬件框图
系统硬件主要由四几大模块组成:信号采集模块、数据转换模块、单片机处理模块、键盘控制显示模块。
结构框图如图3.1所示:
图3.1
系统结构框图 3.3 控制系统总体结构
完整的闭环过程控制系统结构如图3.2,根据要求及硬件条件,本设计只设计以单片机为核心的检测回路。
图3.2 控制系统总体结构图
四、硬件设计
4.1 气压传感器MPX4115模块
气压传感器MPX4115的主要作用就是感知系统的气压的变化,并将这种气压值转变成电流信号,传到I/V转换器中。
图4.1 气压传感器MPX4115电路
4.2 温度传感器9013补偿模块
温度传感器9013的作用是通过温度补偿的方法是测量值更加靠近真实值,以此来减小误差。
图4.2温度补偿电路
系统采用三极管9013进行环境温度的监测,并对压力检测装置进行补偿。
利用三极管9013作为温度传感器,主要依据三极管的PN结对温度比较敏感来实现,连接电路如图。
三极管9013基极和集电极短接,利用基极与发射结之间的PN结随温度变化的特性,输出相应的电压信号Ube, 工作温度 -55℃ ~ +150℃,变化率为-2.2mv/℃,因此根据△Ube的变化将电路接入传感器参考电压端,即可
实现温度补偿。
4.3 数据转换模块
传感器电压由通道0送入AD转换器,当启动转换时,由单片机WR端和74LS373的A3端口选通IN0,同时启动转换,通过检测EOC端口信号来判断转换是否结束,如果结束,由RD和74LS373的A3端口控制,从地址0XFFF0端口读出转换数据进行处理。
图4.3 A/D数据转换电路
4.4 单片机处理模块
AT89S52单片机主要功能分为:电压值读取、电压值校正、给定值输入、键盘控制、显示部分几个部分。
单片机系统含有74LS373用来使P0和P2口联合输出地址进行外部器件的寻址,另外还包含8279,用来扩展单片机端口从而更方便的控制键盘和LED显示器。
图4.5 单片机系统电路图
4.5 键盘显示模块
利用8279的独特功能与特性设计了键盘显示模块,该设计主要通过两个地址端口0xFFEF和0xFFCF对8279进行读写。
其中数码管位选和矩阵键盘扫描部分,由74LS138译码器对8279输出的扫描信号进行译码来实现,使其能够随时扫描键盘和显示端口。
键盘电路能够很稳定的实现对系统的控制,包括启动、停止,输入给定值等。
数码管选用六位的数码管,能够充分显示数据的精度。
仿真图如下:
图4.6 键盘显示电路
键盘显示采用人性化设计,本设计给键盘设置以下功能:
START 键:该键用于启动电路工作,只有按下此键,电路才能进入工模式,才能实现其他相应功能;
STOP 键:停止键用于关闭工作电路,按下之后电路停止工作;DISSET 键:用于查询输入的给定值;按下之后显示系统的给定值;SET 键:该键用于设定给定值,对于控制电路,给定值会随实际情况不同而定,按下此键,可以进入给定值输入模式,数值围为
15KP-115KP,五位有效值,还有一位小数点,可以根据要求
人为设定;
ENTER 键:清除键用于退出给定值输入模式和显示给定值模式,按下之后,进入正常显示模式;
0—9 键:数字键盘包括小数点主要用于数据输入,此系统只用于输入
给定值.
五、软件设计
5.1 系统软件流程图
系统软件采用C语言,利用keil C软件进行编程,具体的软件模块分为:压力信号采集模块、压力数据校正模块、键盘控制和显示模块。
系统的整体流程图为:
图5.1 系统软件流程图
5.2 软件模块分析
5.2.1 压力采集模块流程
传感器直接输出电压信号,电压信号经过A/D转换变为数字信号,单片机通过地址端口读取该数据,流程图为:
图5.2.1 采集流程图
程序设定0xFFF0为ADC0808的端口地址,首先通过端口地址选择模拟通道0,并启动转换,当转换结束后,EOC输出一个高电平,通过查询EOC端口,然后从地址0xFFF0端口度出数据。
线性化原理:采用线性参数标度变换的方法进行电压与压力的线性化标度变换,同时进行校正。
设电压转换值用X表示,KPA用P表示,则根据此公式即可求出线性化后的显示值,即程序中的Y值;线性化公式如下:
5.2.2 键盘显示模块
键盘和显示电路采用8279方案,该方案可大大节省单片机资源,通过该方案可以很大程度的减少控制和显示的复杂性。
该模块关键是对8279芯片的掌握,重点掌握端口地址和命令格式。
在程序中对8279设置两个地址端口,分别是ODE 0xFFEF以及DAT 0xFFCF。
通过这两个端口对8279进行命令操作和数据传输。
该模块的流程结构为:
图5.2.2 键盘和显示流程框图
六、参考文献
[1]邵裕森、戴先中.过程控制工程.:机械工业,2000.5
[2]文定.过程控制系统的MATLAB仿真.机械工业,2009.2
[3]萧德云译.过程控制系统——应用、设计与整定(第3版).清华大学,2004.5
[4]金以慧.过程控制.清华大学,2002.3
七、结束语
本课设是基于AT89S52单片机的测量与显示,通过压力传感器将压力转换为电信号,再经过运算放大器进行信号放大,送至ADC0808,将模拟信号转换成单片机可以识别的数字信号,再经过单片机转换成LED显示器可以识别的信息,显示输出。
在显示的过程过键盘,向计算机系统输入各种数据和命令,亦可通过使用键盘,让单片机系统处于预定的功能状态,显示需要的值。
要实现压力的显示需硬件与软件的配合,最终调试出来的。
本次课设,我学会了使用proteus软件进行单片机系统仿真,我们组成员通过仪器讨论,分工合作,从找元器件开始学起,讨论并研究解决一个一个问题,我们从中学会了很多知识。
该课设用到学过的单片机的知识,有些芯片我们之前没接触过,通过查阅资料,熟悉芯片管脚以及芯片引脚功能。
在此基础上,需要对系统进行设计编程。
通过进一步的交流,让我明白了,编程不难,难的是总体的编程思想,这正是我所欠缺的,需要在以后加以学习弥补。
此次课设的硬件软件都是我们自己设计,这更加锻炼了我们对于整个系统的从设计到实现的技能,提高了全面性思考问题的能力。
通过解决一个又一个的问题让我意识到系统的设计需要将理论与实践相结合,软件硬件相结合,我深刻体会到自身能力的严重不足。
此次的课程设计的顺利完成,离不开我们大家的团结合作和共同努力,在此感大家的辛苦付出,更要对我们的组长,也感老师给我们这次宝贵的锻炼机会。
附录一仿真原理图
附录二仿真程序
程序一:
#include<reg52.h>
#include<math.h>
#include<absacc.h> //用74ls系列芯片用于扩展 i/o 口
#define uchar unsigned char
#define uint unsigned int
char data disbuf[6]={16,16,16,16,16,16};//disbuf[]是一个显示缓冲,里面放的是实际要显示的数值.
unsigned char code SEG[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};//共阴级数码管编码表unsigned char code key__table[]={0xee,0xde,0xbe,0x7e,
0xed,0xdd,0xbd,0x7d,
0xeb,0xdb,0xbb,0x7b,
0xe7,0xd7,0xb7,0x77};// 按键值编码表
uchar xdata ORDER _at_ 0xFF82; //8279命令口地址
uchar xdata DATA _at_ 0xFF80; //8279数据口地址
uchar xdata ADC08 _at_ 0xFFF0; //ADC0808地址
uchar ge,shi,bai,shifen,baifen,value,zhengshu,x,ST;// 定义相关标量
sbit ps=P2^2; // 压力传感器信号号
sbit Beep=P2^3; // 蜂鸣器报警
sbit Dula=P2^6; // 数码管段选线声明锁存器的的端口sbit Wela=P2^7; // 数码管位选线声明锁存器的端口
sbit EOC= P3^4; // 传输数据的开始和停止
sbit ADWR=P3^6; // 定义 wr的端口
sbit ADRD=P3^7; // 定义 rd 的端口
sbit LED0=P1^0; // 定义发光二极管的数值
sbit LED1=P1^1;
uint press, keyval,OE; // 定义压力数据
uint press_l1=64; // 设置压力的自自值
uint press_h1=176; // 设置压力的高值
uint xiaoshu,shuzhi;
double sum,y,DAT[6];
float f_press; // 定义浮点型的压力数据
void delay_ms(int i)
{
uchar j;
while(i--)
{
for(j=115;j>0;j--) //延时程序
{
;
}
}
}
void delay1ms(uint a) //延时子程序设计
{
uchar b,c;
for(;a>0;a--)
for(b=125;b>0;b--)
for(c=10;c>0;c--);
}
/* 压力值的选区及控制阀门 */
void fun1(uint m) //AD转换处理子程序{
extern uint ; //定义全局变量
while(m>0)
{
if(m>0)
{
OE=1; //启动转换
ps=P0;
ps=(P0*1.0)/255*207; //压力转换
OE=0;
P2=0xfe; //个位延时
P1=SEG[P0%10];
delay1ms(500);
P2=0xfd; //十位延时
P1=SEG[P0/10%10];
delay1ms(500);
P2=0xfb; //百位延时
P1=SEG[P0/100%10];
delay1ms(500);
if(P0>176) Beep=1; LED0=1; //打开放气 if(P0<64) Beep=1; LED1=1;
m=m-1;
delay1ms(1000); //延时时间
}
}
}
/* 矩阵键盘显示电路程序 **///
void key_table()
{
uchar temp,key;
P3=0xfe;
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay1ms(10); //延时防止抖动
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case (0xee): key=0; break;
case (0xde): key=1; break;
case (0xbe): key=2; break;
case (0x7e): key=3; break;
}
P1=0xfd;
temp=P1;
switch(temp)
{
case(0xed): key=4;break;
case(0xdd): key=5; break;
case(0xbd): key=6; break;
case(0x7d): key=7; break;
}
P1=0xfb;
temp=P1;
switch(temp)
{
case(0xeb):key=8;break;
case(0xdb):key=9;break;
case(0xbb):key=10;break;
case(0x7b):key=11;break;
}
P1=0xf7;
temp=P1;
switch(temp)
{
case(0xe7):key=12; break;
case(0xd7):key=13; break;
case(0xb7):key=14; break;
case(0x77):key=15; break;
}
}
}
}
void Init_8279() //8279 初始化函数{
ORDER=0x00;
ORDER=0xd1;
}
void Disset() // 显示给定值
{ uchar DAT;
ORDER=0x90;
LED0=1;
DAT[1]=SEG[disbuf[0]];
DAT[2]=SEG[disbuf[1]];
DAT[3]=SEG[disbuf[2]];
DAT[4]=SEG[10];
DAT[5]=SEG[disbuf[4]];
DAT[6]=SEG[disbuf[5]];
LED0=0;
}
void Setvalue() //预设给定值程序
{
uint k;
uchar r,s;
k=0;
Init_8279();
for(r=0;r<7;r++)
{
disbuf[r]=0;
}
while(k!=8)
{
if(ORDER&0x01)
{
ORDER=0x50; //有键按下,写入读键值命令 r=DATA;
s=0;
while(r!=keyval[s]){s++;}
if(k!=7)k++;
else
if(r==0x13)k++; //如果确定键按下跳出循环 }
disbuf[k-1]=s; //将设定值存入数组
Disset(); //显示设定值
}
}
/* *显示子程序* ***////
void Display()
{
zhengshu=(unsigned int)y;
xiaoshu=(y-zhengshu)*100;
bai=zhengshu/100;
shi=zhengshu/10%10;
ge=zhengshu%10;
shifen=xiaoshu/10;
baifen=xiaoshu%10;
Init_8279();
ORDER=0x90; //开显示器
DAT[1]=SEG[bai];
DAT[2]=SEG[shi];
DAT[3]=SEG[ge];
DAT[4]=SEG[10];
DAT[5]=SEG[shifen];
DAT[6]=SEG[baifen];
}
/* 采集子程序 */
void getvalue()
{ uint i;
ADWR=1; //启动 A/D 转换
ADC08=0;
ADWR=0; // A/D转换结束
delay1ms(10);
ADWR=1;
for(i=10;i>0;i++)
{
display(shuzhi);
}
if(EOC==1)
{
Value =ADC08; //取ADC0808值
}
x=Value;
y=0.4347*x+9.297826;
Display(); //显示转换值
}
/* 键值处理子程序* *////
void keyvalue()
{
uchar KEY;
if(ORDER&0x01) //判断是否有键按下 { Beep=1;
ORDER=0x50; //取键值
KEY= DATA;
Beep=0;
switch(KEY)
{
case 0x1b: setvalue();break; //SET功能键
case 0x1a: Disset();delay_ms(500);break; //DISSET功能键
case 0x19: ST =0;Init_8279(); break; //stop键}
}
}
/* *主程序** */
void main()
{
Init_8279(); //初始化8279
while(1)
{
if(ORDER&0x01)
{
OORDER=0x50;
Beep=0;
LED0=0;
LED1=0;
}
ST= DATA;
while(ST ==0x18) //等待START键按下
{
Beep=1;
LED0=1;
LED1=0;
getvalue(); //取ADC08 值
delay1ms(10);
keyvalue(); //按键处理
}
LED1=1;
}
}
程序二:
#include<reg52.h>
#include<absacc.h>
#define uchar unsigned char
#define uint unsigned int
sbit EOC= P3^4;
char data disbuf[6]={16,16,16,16,16,16};
uchar code keyval[]= {0x00,0x01,0x02,0x03,0x08,0x09,0x0a,0x0b,
0x10,0x11,0x12,0x13,0x18,0x19,0x1a,0x1b}; //键值表
uchar code SEG[]= {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f, //0~9等字符
0x6f,0x80,0x7c,0x39,0x5e,0x79,0x71,0x00,0x40}; //数码管表
uchar xdata ODE _at_ 0xFFEF; //8279命令口地址
uchar xdata DAT _at_ 0xFFCF; //8279数据口地址
uchar xdata ADC _at_ 0xFFF0; //ADC0808地址
uchar GE,SF,BF,BA,SH,Value,ZS,x,ST; //相关变量定义
uint XS;
float sum,y;
/********************1ms延时程序**********************/
void delay_ms(uint d)
{
uint a,b,c;
for(c=d;c>0;c--)
for(b=142;b>0;b--)
for(a=2;a>0;a--);
}
/*******************8279初始化函数*********************/
void Init_8279()
{
ODE=0x00;
ODE=0xd1;
}
/**********************显示设定值**********************/ void Disset()
{
ODE=0x90;
DAT=SEG[disbuf[0]];
DAT=SEG[disbuf[1]];
DAT=SEG[disbuf[2]];
DAT=SEG[disbuf[3]];
DAT=SEG[disbuf[4]];
DAT=SEG[disbuf[5]];
}
/********************预设给定值程序*********************/ void setvalue()
{
uint k;
uchar i,j;
k=0;
Init_8279();
for(i=0;i<7;i++)
{
disbuf[i]=16;
}
while(k!=8)
{
if(ODE&0x01)
{
ODE=0x50;//有键按下,写入读键值命令
i=DAT;
j=0;
while(i!=keyval[j]){j++;}
if(k!=7)k++;
else
if(i== 0x13)k++; //如果确定键按下跳出循环 }
disbuf[k-1]=j; //将设定值存入数组
Disset(); //显示设定值
}
}
/*******************显示子程序***********************/ void Display()
{
ZS=(unsigned int)y;
XS=(y-ZS)*100;
BA=ZS/100;
SH=ZS/10%10;
GE=ZS%10;
SF=XS/10;
BF=XS%10;
Init_8279();
ODE=0x90; //开显示器
DAT=SEG[BA];
DAT=SEG[SH];
DAT=SEG[GE];
DAT=SEG[10];
DAT=SEG[SF];
DAT=SEG[BF];
}
/*******************采集子程序***********************/ void getvalue()
{
ADC=0;
delay_ms(10);
if(EOC==1)
{
Value =ADC; //取ADC0808值
}
x=Value;
y=0.4347*x+9.297826;
Display(); //显示转换值
}
/*******************键值处理子程序*********************/
void keyvalue()
{
uchar KEY;
if(ODE&0x01) //判断是否有键按下
{
ODE=0x50; //取键值
KEY= DAT;
switch(KEY)
{
case 0x1b: setvalue();break; //SET功能键
case 0x1a: Disset();delay_ms(500);break; //DISSET功能键 case 0x19: ST =0;Init_8279(); //stop键
}
}
}
/**********************主程序************************/
void main()
{
Init_8279(); //初始化8279
while(1)
{
if(ODE&0x01)
{
ODE=0x50;
}
ST= DAT;
while(ST ==0x18) //等待START键按下
{
getvalue(); //取ADC值
delay_ms(10);
keyvalue(); //按键处理
}
}
}。