还剩63页未读,继续阅读
本资源只提供10页预览,全部文档请下载后查看!喜欢就下载吧,查找使用更方便
文本内容:
第一章绪论
1.1课题研究的背景意义柴油发电机广泛应用于野外作业、抗洪救灾及军事等领域,它是一种小型发电设备,系指以柴油等为燃料,以柴油机带动发电机的转子做切割磁力线运动而产生发电整套机组一般由柴油机、发电机、控制箱、燃油箱、起动和控制用蓄电瓶、保护装置、应急柜等部件组成整体可以固定在基础上,定位使用,亦可装在拖车上,供__使用尽管柴油发电机组的功率较低,但由于其体积小、灵活、轻便、配套齐全,便于操作和维护,所以广泛应用于矿山、铁路、野外工地、道路交通维护、以及工厂、企业、医院等部门,作为备用电源或临时电源柴油机的转速由油控系统控制,当油控系统增加喷油量时,柴油机转速变快;反之,当油控系统减少喷油量时,柴油机转速变慢,进而决定了输出电压的高低为了使柴油机输出的电压稳定,就要给发电机组配置一套测控系统该测控系统的功能就包括检测柴油机的输出电压,通过一定的算法处理得到喷油控制量,并把喷油控制量传送到油控系统以控制柴油机的转速,进而控制输出电压用发电机测试系统进行测试,是一种全面的性能试验、能够较确切地得到被测电机的有关性能参数的试验其目的是为了确定发电机的输出性能是否能全面达到技术要求,各种型式的发电机均需要通过测试、试验后才能投产或继续生产国际标准和英、苏、德等国家都把型式试验当作一种性能试验,用来检查发电机的特性和参数这种试验一般只对各种型式电机中的第一台或首批的几台样机进行,所以称为型式试验根据需要,试验可包括标准中规定的所有项目,也可以是其中的一部分项目以前的电机型式试验系统主要由模拟设备和机械式测量仪表构成,试验人员工作繁重,数据统计工作复杂,且由于人为因素,数据测量不准确基于上述原因,在中国市场上目前对具有自主知识产权的柴油发电机智能检测系统的需求十分迫切,该设备对于实时检测柴油发电机的输出参数,提高产品竞争力,提高市场消费需求具有巨大的实际作用和意义本课题的研究对提高柴油发电机测试系统生产品质、效率具有极高的实用价值另一方面,随着计算机技术和嵌入式技术发展,出现了计算机检测技术在现代工业制造业对机电输出参数测量的高精度、高效率要求的驱动下,自动测试系统以经济实效、快速、非接触、精确以及自动化程度高等特点赢得了广泛的__,本课题利用单片技术对柴油发电机测试系统进行了深入地探讨与研究具有重大意义,同时可以__到其它相关领域
1.2国内外发展概况及发展趋势回顾国内柴油发电机测控系统的发展,大概可以划分为四个阶段
1、以时间继电器和中间继电器为主构成的自动化控制系统,这种模式当时在同行业中非常普遍,而且也以相当的批量投向市场,突出的弱点是功能简单、结构复杂、维护调试困难、可靠性差,最终没有得到用户的认可
2、用分离电子元器件组成延时电路和逻辑判断电路来实现的自动化系统,这种模式相对于第一种模式,有了很大的进步,如果精心设计,提高工艺水平,应该能取得很好的效果但是,在那个企业大而全的年代,每个企业各自为战,造成批量小、工艺__、质量无法保证,所以这个阶段延续时间也较短
3、随着__开放,国外各种新鲜器件纷纷出现在国人面前,PLC(可编程序控制器)以性能稳定、方便灵活的优势迅速成为机组自动化控制领域的主力,时至今日仍有企业在应用这种模式的优点相对于前两种较为明显,但也逐步显露出一些缺陷,如__电路复杂,需配置转速、电压等判断电路及供电电源、端口扩展继电器等器件;造价相对较高(带AD转换的PLC动辄上万元)PLC是很可靠的,但它毕竟不是专门为我们这个行业而设计的,所以以PLC为核心构成的柴油发电机组自动化控制系统注定是一个匆匆的过客,随着技术的飞速发展很快失去了优势
4、控制系统功能模块化思路的出现,__解决了困扰发电机组控制领域的难题,这即是以专用控制器为核心构成的自动化系统,这些专用控制器为发电机组量身打造,集多种功能于一身,甩掉了复杂的__电路,使自动化控制系统一下子变得简单了这些专用控制器大多采用了先进的微处理器及控制技术,可靠性和环境适应能力较PLC大大提高,同时,很多参数可以根据实际情况而设定,使用起来非常灵活目前,我们已经处在第四个阶段十余年了,这种模式的生命力,随着技术的发展显示了越来越强大的生命力,可以说这种控制系统功能模块化就是柴油发电机组自动化测控的现状
1.3本课题的研究意义目前,随着我国工业的高速发展,大量的发电机在冶金、能源、化工、制造业、交通等行业得到了极为广泛的应用但相应地发电机测试的工作量也不断增加,尤其对于一些80年代建设的大型国有企业,随着设备的才华,各类型的发电机的检修测试需要更是与日俱增结合国家十五计划中提出其的“以信息化带动工业化”的战略决策,__一种采用先进的信息技术的发电机自动测试系统势在必行,设计可靠,安全,便捷柴油发电机测试系统具有极大地现实必要性为此,本论文进行了柴油发电机测试系统的研究与实现本论文的柴油发电机测试系统有很多现实意义
1、系统硬件组成灵活方便,易于功能扩展;
2、实现程序控制,监视测试过程;
3、自动存储、整理并分析测试结果,即将测得的数据进行分析处理,最后以数字显示;
4、有一定的经济效益
1.4论文结构论文主要包括以下七个部分第一章,概括讲述了柴油发电机测试系统研究的背景意义,发展状况,课题研究的目的、意义及背景;第二章,介绍了柴油发电机的硬件设计、详细的说明了柴油发电机测试系统的系统组成结构及分析;第三章,;第四章,叙述了本系统软件整体结构的设计,详细说明了各功能模块的设计;第五章,进行个人总结第二章系统组成结构与分析
2.1系统组成框图本系统采用STC12C54系列单片机为主的微控制处理器作为柴油发电机测试系统的控制核模块,能够对输出电压,电流频率进行测量;能通过3位LED交替显示测量的电压、电流、频率,且能通过键盘锁定以上3个被测量单独显示;具有__功能,通过不同标识显示__内容;能通过键盘设置各种参数,包括门限电压、电流、频率、功率在保证测试系统可靠运行的前提下,电路的设计尽可能的简洁紧凑,减轻系统负载,同时坚持充分发挥创新原则,以简洁但功能__为出发点,并以稳定性为首要前提,实现测试的快速运行系统总设计方案如图所示图2-1系统框图
2.2微处理器的选择根据技术指标要求,系统采用内带A/D,D/A接口的STC12C5410AD单片机作为主控CPU和传统的8051单片机相比,STC12C5410AD具有如下优点
(1)内带一个12位的A/D转换器,且可以通过内部模拟开头外接8个A/D转换输入端
(2)指令完全兼容传统8051,但速度快10-12倍,针对电机控制,强干扰场合
(3)内部集成专用复位电路,4路PWM,有6个16位的计数器
2.2输入模拟__处理本系统要求采样并计算发电机组输出电压、电流的大小根据指标要求,拟选用的传感器分别为精度为01%的电压互感器、精度为01%的电流互感器,采用CPU内部的12位A/D作为模数转换器根据输入__的特点,系统采用交流采样的方式测量电压、电流值交流采样的原理是三个周期内对输入__进行等间隔的N个点采样,并同这些采样值计算__的有效值设这N个点的采样值分别是X1,X2,……,Xi……,Xn则该周期__的有效值Y为为测量__的周期,系统需提供一个测频电路,把周期性的交流__转变为方波__
2.3人机接口设计系统的键盘与显示面板如图2-2所示图中LED1~LED3代表电压、电流、频率显示标识当LED1亮时,数码管显示测量的电压值;当LED2亮时,数码管显示测量的电流值;当LED3亮时,数码管显示测量的频率值一般情况下,电压、电流、频率交替显示当需要单独显示某一测量值时,可通过按键功能进行切换,同时LED1对应电压__显示,LED2对应电流__显示,LED3对应频率__显示图2-2人机接口面板
2.4硬件系统的结构综上所述,基于单片机的测控系统的系统结构如图
2.3所示图2-3硬件系统结构图
2.5数据和状态显示根据指标要求,系统要求除了显示电压、电流、频率测量值外,还要显示各种__值信息表2—1是各种__信息显示内容表2-1__信息显示码含义显示信息含义显示信息含义U—H输出电压过高I—H输出电流过高U—L输出电压过低F—E频率超限P—H输出功率过高
2.6键盘功能划分本系统键盘要实现的功能有__门限值设置系统键盘个数共有KEY
1、KEY
2、KEY3共3个,每个键盘都具有多种功能图2-4按“倒数”结构罗列了系统键盘功能由于键盘个数较少,因此采用二级下拉式菜单方式编写键盘程序系统按功能不同把键盘划7页(Page0—Page6)每页允许按键个数和各键功能各不相同如第1页可按2个键,而第1页可按3个键第0页为第1级,其它为第2级第2级的第1页利用4个按键完成过压门限值的设置KEY1的功能是在设置数值时,实现数字按0~9顺序徨切换;KEY2的功能是实现设置数值位数循环向前__;KEY3的功能是设置确认,并使菜单回到第1级(Page=0)表2-2列出了各页功能图2-4系统键盘结构图表2-2各页及按键功能页号功能说明页号功能说明0主界面KEY1页号加1;KEY3页号确认按下该键进入相应页面菜单4超频门限值设置KEY1~KEY3功能同上1过压门限值设置KEY1数字加1;KEY2数字位前移;KEY3按下后保存过压门限值并返回初始页面5功率超限值设置KEY1~KEY3功能同上2欠压门限值设置KEY1~KEY3功能同上6主显示页面KEY1按下只显示电压、再按下只显示电流、再按只显示频率,以此循环;KEY3返回初始界面3过流门限值设置KEY1~KEY3功能同上
2.7软件功能划分系统软件主要功能有键盘处理、数据采集、数据处理、数据或状态显示等根据模块化编程思想,软件系统可以分为系统初始化模块、键盘处理模块、显示处理模块、数据采集模块、数据处理模块、检测__模块系统初始化模块主要完成显示缓冲、串行行接口、特殊功能寄存器、数据缓冲区及变量的初始化、使系统复位后进入安全、确定的状态键盘处理模块主要完成键盘扫描、各按键功能的处理等功能显示处理模块主要完成显示器硬件驱动、按键显示、__显示和采样电压、电流、频率的显示等功能数据采集模块主要完成电压、电流采样和频率的测量等功能数据处理模块主要是实现电压、电流有效值的计算,通过PID控制算法计算出控制量并通过D/A输出,实现输出电压的稳定检测__模块主要是检测输出电压、电流、频率等是否超限,当出现超限时,通过数码管显示__信息,同时关闭油机第三章系统的硬件设计硬件是整个系统正常工作的基础通过上文的介绍,由系统的组成框图可知,本系统硬件电路主要由单片机最小系统、人机接口电路、电源电路、模拟输入模块电路组成以及关油门电路,其各部分详细设计如下
3.1单片机最小系统单片机最小系统或者称为最小应用系统是指用最少的元件组成的单片机可以工作的系统.对STC12系列单片机来说最小系统一般应该包括:单片机、晶振电路、复位电路、程序下载电路.STC12C5410AD是片内有ROM/EPROM的单片机,因此,这种芯片构成的最小系统简单﹑可靠用STC12C5410AD单片机构成最小应用系统时,只要将单片机接上时钟电路和复位电路即可由于集成度的限制,最小应用系统只能用作一些小型的控制单元其应用特点1有可供用户使用的大量I/O口线2内部存储器容量有限3应用系统__具有特殊性单片机最小系统的结构单片机要正常运行,必须具备一定的硬件条件,其中最主要的就是三个基本条件电源正常;时钟正常;复位正常具体的最小系统原理图如图3-1所示图3-1单片机最小系统
3.2人机接口电路键盘和显示接口是测试系统中的重要组成部分,一方面通过键盘输入参数值,而显示器则可以监视参数输入状态,另一方面,通过显示器显示测量结果和运行的状态本次设计的显示器采用3连体的共阴数码管,数码管采用串转并芯片74LS164进行驱动人机接口电路如图3-2所示,CPU和端口__连接如表3-1所示关于数码管的选择问题
1、如果数码管采用静态显示方式,若选用3个__的数码管,则势必需要用到3个74LS164芯片进行驱动,如此一来,增加硬件电路空间和产品成本
2、若数码管采用动态显示方式,则需选用一个3连体数码管,而它只需一片74LS164芯片驱动,不仅节约芯片,硬件电路还更简单,占用空间缩小,而软件编程也不会很复杂因此,综合以上两种考虑,选择方案2更好表3—1CPU和端口__连接端口功能端口功能P
3.0输出:74LS164的数据输入端P
2.1~P
2.3输出:3连体数码管位选端P
3.1输出:74LS164的数据输入端P
1.6~P
2.0输出:电压、电流、频率指示灯P
2.4输出:关油机控制端P
1.3~P
1.5输入:键盘图3-2人机接口电路关于键盘的抖动问题本次键盘采用机械式键盘,由于机械开关的撞击作用,开关在闭合或断开时开关会产生抖动,抖动时间约5ms~10ms抖动波形如图3-3所示,为了保证系统对按键做出可靠的响应,应消除抖动的影响,消除抖动影响的方法主要有硬件消抖法和软件消抖法由于硬件消抖法每一个按键都需要相应的消抖电路来支持,如RC滤波器或双稳消抖电路等在按键较多时,将使整个电路复杂、庞大因此在带微处理器的系统中很少采用,而主要采用软件消抖法本次设计中使用的是1X3矩阵式机械键盘,它们都是直接接到单片机的P1口,通过编写判断键盘按下、软件消抖以及执行键盘散转程序来执行相应操作,将在
4.
3.2章节做详细介绍
3.3电源电路
3.
3.1稳压电路原理图稳压电路在实际应用电路中应用非常广泛如我们平常常用的78或79系列三端稳压器也是属于它的一种整流滤波后的电压是不稳定的电压,在电网电压或负载变化时,该电压都会产生变化,而且纹波电压又大所以,整流滤波后,还须经过稳压电路,才能使输出电压在一定的范围内稳定不变本次设计直接在输入端加入电压,再对其进行稳压电源电路为总个系统提供5V的工作电压,电源电路的稳定性直接影响到总个系统的稳定性,5V电源电路如图
3.13所示直流稳压电源的输出电压是由220V交流电转换而来,其输出电压会因电网电压的变化有所波动,为了得到稳定的5V直流电源,可将直流电源输出的12V进行整流,将整流后的电压输出到三端稳压器LM7805输出5V直流电,外加一些滤波电容后输出的5V直流电趋于稳定,杂波较小,通过接口输出到测量控制电路中,为单片机系统、显示和谐振电路等供电图3-4稳压电路
3.
3.2+
2.5V直流稳压电源将整流后的5V电压通过芯片TL431,使输出端输出为
3.3V,为电压、电流调理电路提供
2.5V电源
2.5V直流电路如图3-5所示图3-
52.5V直流稳压电源电路图
3.4模拟输入模块电路单片机用与检测系统时,总要有与被测对象相__的前向通道而这个所谓的前向通道在本设计中可称为模拟输入__的处理电路前向通道与被测对象的状态、特征、所处环境密切相关在前向通道设计时要考虑到传感器或敏感元件选择、通道结构、__调节、电源配置、抗干扰设计等在通道电路设计中还涉及到模拟电路诸多问题当将单片机用作检测系统时,系统中总要有被测__输入通道,有计算机拾取必要的输入信息作为检测系统,对被测对象拾取必要的原始参量__是系统的核心任务,对控制系统来说,对被控对象状态的测试以及对控制条件的监测也是不可缺少的环节对被测对象的__的拾取其主要任务就是最忠实地反映被测对象的真实状态,它包括实时性与测量精度同时使这些测量__能满足计算机输入接口的电平要求
3.
4.1电压、电流输入__处理电路电压、电流输入__处理电路如图3-1所示图中,输入电压先由电流型电压互感器把电压__转变为电流__,再由高精度电阻取样,把电流__转变为电压__Vin.图3-6电压、电流输入__处理电路STC12C5410AD的基准为5V,设计时取抬升电压为
2.5V,则可保证输出电压的值大于0V电流处理电路和电压处理电路类似处理后的电流__AD_I和电流__AD_U接入STC12C5410AD的两个模拟输入端,供CPU采样
3.
4.2频率测量电路频率测量电路主要功能是把交流电压__整形变为方波__(图3-2)整形后的方波__接入CPU的INT0,供测频用图3-7交流__转变为方波
3.5关油门电路采样电压、电流经过数据分析处理后的值可能会超过系统所设门限值,这时CPU需向外界发送__信息,而光显示报__信息是不安全的,因为此时的柴油发电机仍在运转,如果不采取相应措施,发电机可能会造成无法修复的故障因此必须采取应急措施,即关闭油门而这个关油门的__是经CPU分析后,由P
2.4口发出的,当P
2.4口发送一个低电平时,图中继电器断开,后续电路也即开路了,达到关油门的功能图3-8关油门电路第四章系统的软件设计系统软件采用C语言,在WindowsXP环境下采用KeiluVision2进行编写,对STC12X5410AD单片机进行编程以实现各项功能C语言是模块化的高级语言,它的程序可读性和可移植性都强于汇编语言,充分利用原来积累的编程知识和一些典型子程序,并采用模块化、结构化的设计思想,具有易读性,易于移植,功能模块可以很容易的扩展;用C语言编写的硬件控制程序实时性好,编译效率也高,适用于编写柴油发电机测试系统这样软硬结合的系统在本次设计中,系统通过C语言编写程序,来实现系统软件的功能系统软件__工具使用单片机专用KeiluVision2,程序烧写使用STC_ISP_V479KeiluVision2支持C51编程,是一款良好的软件__环境
4.1系统软件总体结构及整体设计思路根据本次设计的硬件电路和要求达到的功能,系统软件结构如下图4-1柴油发电机测试系统软件结构图为了使软件设计条理清楚,方便调试和使用,采用依照系统功能模块规划及分析中所划分的功能模块进行相应的设计而同时在各个模块中可以按照它所要实现的功能将一个模块划分为几个模块进行设计本次软件系统设计主要分为三个部分人机接口部分、AD采样、数据处理部分,本设计采用的总体思路如下通过单片机的定时器0和计数器1对外部产生的频率__进行定时计数,得出外部__的频率,进而单片机根据相关的计算公式处理计算出相应的频率,在在得到__的频率后,算出其周期,再用周期除以32,将这个时间作为PCA模块0的定时值,对外部__进行每个周期的32点采样,通过相应的算法将__的电压、电流值算出,送数码管显示,键盘的功能主要是实现__门限值的设定
4.2主程序设计主程序是整个系统软件的运行主体,各个子系统软件都必须经过它的调度,才能运行得当根据设计项目的功能要求,主程序对系统主要进行了一下工作
一、系统初始化,相关模块的初始化工作;
二、进入主程序循环主程序循环就是监控子程序,管理子程序,实现系统功能
4.
2.1系统初始化系统初始化主要完成显示模式的初始化、键盘页面初始化、STC12C5410AD的PCA定时模块初始化、定时器0外部中断0的初始化、AD采样模块初始化
(1)、显示模式初始化系统的显示模式共有3种,一是电流、电压、频率的循环显示或单独显示,二是键盘设定值的显示,三是__信息的显示由全局变量DispMode的值控制系统显示模式,系统上电后的初始显示模式为电压、电流、频率循环交替显示,因此DispMode=0;
(2)、键盘页面初始化键盘页面值由值由全局变量Page决定,系统上电后的初始键盘页面Page为0
(3)、PCA模块的初始化主要是对其工作模式寄存器、控制寄存器、捕获寄存器、中断允许寄存器进行初始化
(4)、定时器
0、1,外部中断0的初始化T0做定时器,T1做计数器,二者都工作在16位的计数方式;外部中断0的触发方式是下降沿触发,允许定时器0和外部中断0的中断请求
(5)、AD采样模块初始化主要是将单片机P1口采样通道的输入方式配置寄存器、控制寄存器,数据结果寄存器、相应的中断允许位初始化
4.
2.1主程序流程图主程序的设计思路为上电后,先调用初始化,接着调用AD采样模块程序对经过调理后的电压、电流进行采样,将采样值经过处理后调显示子程序送数码管显示,同时把采样值与限定值进行比较,进行判断,当采样值超过限定值时,则会出现显示器__信息,同时CPU发出关油门__等一些操作;当没超过时,显示器正常显示测得的电压、电流、频率值当有键盘按下时,先读取它的键值,找到它是哪个页面的键值,再去处理这个页面的键值对应的函数操作键盘扫描是每隔10ms扫描一次,数码管是每隔
0.5S显示一次图4-2主程序流程图
4.3显示模块模块设计显示模块是人机接口模块中的一部分显示模块的软件设计的主要内容是将采样值信息、__信息送数码管显示,同时相应的LED灯会点亮其流程图如图4-3所示,显示模块包括数据拆分,74LS164串转并、送显、循环显示与单独显示、设定值显示等函数
4.
3.1数据拆分要把一个整型数据送三位数码管显示,首先这个数不能大于999,否则就把它为是999;其次,这个整形据在计算机中是以二进制的形式存储的,必然要用三个存储单元来存储它拆成三位后的值,在本次设计中,用一个全局变量的数组DispBuf
[3]来存储一个整形数据拆分成十进后的百、
十、个位,将二进制数转换为十进制数的拆分函数为voidDataSeparateuintInDatauchar*OutData图4-3显示模块流程图
4.
3.274LS164串转并74LS164是一个串转并的并的芯片,数据串行输入,8位并行输出,这不仅为数码管提供8bit数据,同时也是作为一个数码管驱动芯片工作着本设计中,可有两种方法编写该转串并函数voidShift164ucharIn
(1)、利用串口方式编写该函数,设已经设置好了串行工作于方式0(SCON=0)本软件设计的数据输出采用串行输出的方式,用单片机的RXD作为数据线,TXD作为时钟__线,分别接到74LS164的数据端和时钟端
(2)、用模拟74LS164时序来编写该函数其中要数据位循环移入74LS164的寄存器
4.
3.3查找字形码程序要使数码管能正确显示所需的数字或字母,需要给每个要显示的字符找到其相应的字型码全局变量ShapeBuf[]为存放DispBuf[]对应的字型码数组函数voidFindShapeuchar*disp_bufuchar*shape_bufuchardot_pos主要负责把DispBuf[]数组中的3位数找到其字型码其中disp_buf要显示的3个数字的存放位置;shape_buf,对应数字字形码存放位置;dot_pos,要显示小数点的位置小数点位置从左到右依次为0,1,2,最后一位不显示小数点,当Dot的值大于等于2时,不显示小数
4.
3.4送显子程序要显示的字符找到字型码之后,就可以通过74LS164把数据送数码管显示了因此该函数包括74LS164的串转并函数由于3连体数码管工作在动态显示方式,因此每个数码管点亮一段时间后要有一小段短暂的延时,由于人眼的视觉延缓的作用,看起来三个数码管像是同时亮着,因此该函数也应包括延时程序该函数的函数名为voidSendDispuchar*shape_buf
4.
3.5电压、电流、频率显示子程序数码管可以单独显示电压、电流、频率中的某一个参数,也可以循环显示三个参数,这是可以依用户的需要而通过键盘功能进行设定的而决定这三个参数是循环显示、还是只单独显示某个参数,是由全局变量Hold及WhoHold决定的Hold=0时,WhoHold失去作用,此时三个参数循环显示Hold=
1、WhoHold=0时,单独显示电压;Hold=
1、WhoHold=10时,单独显示电流;Hold=
1、WhoHold=20时,单独显示频率
4.
3.6按键时设定值的显示子程序系统初始化后,默认的键盘页面为0页面,电压、电流、频率在交替显示当有KEY1和KEY3按下时,显示器首先显示“d-0”字样,这几个字符是放在全局变量SetBuf[]数组中的当再次按下KEY3即Enter键后,数码管显示过压门限值,这是软件程序里设定的初始值,可以通过键盘进行改变,而这个子程序正是显示正在改变的门限设定值当进入门限值的设定的显示时,处于设定位的数码管会闪烁
4.
3.7PCA模块0作为定时器STC12C5410AD系列单片机集成了4路可编程计数器阵列(PCA)模块,可用于软件定时器、外部脉冲的捕捉、高速输出以及脉宽调制(PWM)输出,本设计的PCA模块用于定时与PCA有关的特殊功能寄存器如下666666本系统PCA模块初始化程序如下sfrCH=0XF9;sfrCL=0XE9;sfrCCON=0XD8;sfrCMOD=0XD9;sfrCCAP0H=0XFA;sfrCCAP0L=0XEA;sfrCCAPM0=0XDA;__itEPCA_LVD=IE^6;__itEADC_SPI=IE^5;__itCR=CCON^6;//__itCF=CCON^7;__itCCF0=CCON^0;voidPCA_Initiate{CMOD=0X80;CCON=0x00;CL=0;//PCA计数值初始化CH=0;CCAP0L=C_1MSCount%256;//1ms的定时值,CCAP0H=C_1MSCount/256;CCAPM0=0X49;//PCA模块1工作于16位计数器EPCA_LVD=1;//允许PCA模块中断EA=1;CR=1;//定时器开始运行}以下为PCA模块0的中断服务程序voidPCA_Interruptvoidinterrupt6{CL=0;CH=0;//计数值清0Ticks++;//时间滴答加1CCF0=0;//清中断标志CCAPM0=0x49;//PCA模块0工作于16位计数器}全局变量Ticks记录时间中断次数(以后称为时间滴答),记录的最大个数为65535个,也即65535ms一个循环bitTimeOutuint*OldTicksuintTimeMs{unsignedintdiff;diff=Ticks-*OldTicks;if!TimeMs||diff=TimeMs{*OldTicks=Ticks;return1;}return0;}在这个函数中,首先时间滴答Ticks在中断的作用下,会不间断地向前计数假设X时刻diff=TimeMs此时,X时刻的时间滴答Ticks送到*OldTicks保存(通过指针变量*OldTicks保存)过了一段时间(设Y时刻),再调用该函数,则函数计算X到Y时刻经历的时间diff=Ticks-*OldTicks;如果经历的时间diff大于设定时间TimeMs则返回1,同时又开始新的计时,保存Y时刻的时间滴答*OldTicks=Ticks;因此,该函数完成了连续判断是否超时的功能,即从某时刻开始计时,一段时间后,如果经历的时间大于设定的时间TimeMs则返回1,并进入下一轮判断如果没有超时,返回0函数也提供了立即记录当前的时间滴答的功能只要在调用该函数时,把TimeMs对应的实参设置为0即可
4.
3.8系统显示函数系统显示是根据显示模式实现主界面显示(显示电压、电流、频率),设定状态显示,__显示该函数由全局变量DispMode决定DispMode=0,主界面显示;DispMode=1,设定值显示;DispMode=2,__界面显示该函数每隔
0.5S显示一次程序如下voidSysDisp{ifDispMode==0//显示模式为0UIFCycleDispHoldWhoHold;//显示测量值elseifDispMode==1//显示模式为1DispSetDataSetPosDotDotPos;//显示设定值elseifDispMode==2//显示模式为2SendDispShapeBuf;//显示__值}
4.
3.9系统显示任务该函数每隔
0.5S进行一次系统显示voidSysDispTaskvoid{ifTimeOutDispTime500//
0.5S显示一次SysDisp;}
4.4键盘处理模块按照从最底层到顶层的顺序,键盘处理模块设计总体框图如图4-4所赤键盘处理模块的设计又可以分为几个子程序,包括键盘扫描程序,读键值子程序,键盘处理程序图4-4键盘处理模块总体框图
4.
4.1读键值子程序一般来说,每个键盘都会有一个键值,单片机测得键值后,就可以知道是哪个键盘按下了,进而处理相关程序本文__3个键盘,即有3个键值,KEY1键值是0x80KEY2是0x81KEY3是0x82程序首先定义一个位结构体类型Key_GPIO用来保存3个按键值typedefstruct{ucharKey1:1;ucharKey2:1;ucharKey3:1;ucharReserve:5;}Key_GPIO;同时也定义了一个联合体类型,在该类型中字符成员InKey和KeyGPIO共用一个存储单元,因此通过判断InKey是否为0就可以知道有无键按下typedefunion{ucharInKey;Key_GPIOKeyGPIO;}Mix_In_Key;程序中,如果某键按下但尚未处理,则键值的最高位置1,键盘功能处理完后,其最高位清
04.
4.2键盘扫描程序键盘扫描程序可包含下列步骤首先判断有无键按下,如果有键按下,进行去抖处理方法是10ms后再读键值看是否变化,如无变化说明不是抖动然后分析键盘是否释放,如果释放了则进行相应的键盘处理
4.
4.3键盘处理子程序该函数主要完成按键处理功能为了实现这个函数,定义了一个结构体Page_KeyFun这个结构体中成员KeyNo表示哪个键按下了,成员(*Fun)是指针函数,它指向按下该键所要执行的函数从前面的介绍可知,本系统键盘分为7页,每页可按的键也不一样例如第0页可按Key1和Key3键设按Key1后执行的函数为Page0Key1Fun,按Key3后执行的函数为Page0Key3Fun,则可用一个Page_KeyFun结构体数组表示它们这样键盘处理函数可按下列方法执行
(1)找到某一页对应的结构体数组
(1)查找这一页哪个键按下
(1)由结构体数组,找出执行按下该键对应的函数入口地址(函数名),执行相应程序函数原型如下
4.
4.4键盘任务子程序本系统每隔10ms进行1次键盘扫描,即每隔10ms调用一次键盘处理子程序
4.5AD采样模块AD采样模块包括频率测量模块和电压、电流采样模块
4.
5.1频率测量模块电压、电流的正弦波__经过波形变换后成为一个50Hz的方波__将该__与单片机外部中断0引脚相连,当CPU检测到外部中断0引脚上出现下隆沿时执行外部中断0的中断服务程序在该程序中,通过定时器T1的计数值可换算出电压、电流的频率,如果硬件电路误差不大的话,这个频率值就是50Hz
4.
5.2电压、电流采样模块测到__的频率后,就可以启动定时器0进行电压、电流的循环采样了在外部中断0中断服务程序中启动定时器T1进行计数时的同时,以T(__周期)/32的定时时间隔启动T0中断;在外部中断0关闭定时器T1的同时,才关闭定时器T0,这样,在一个__周期内,就会出现32次定时器T0中断另外,在对电压、电流进行采样前,还要分析前面采样的数据是否处理完了只有前面采样的数据处理完了,才允许当前的采样;否则关定时器T0,取消该次采样
4.5数据处理模块得到了采样值,接下来就是数据处理了数据处理模块主要是实现对采样电压、电流有效值的计算以及设置__信息在计算电压、电流有效值时,需要注意的是要先判断采样数据是否已计算过,如果已计算过就没必要再计算计算完有效值后,要置计算完标识,以使采样程序知道可以采样新的数据程序给每个参数都设置__标识,当32个采样值中有好几个都超过门限值,说明柴油机输出不正常,则置__标识为1当程序检查到某个参数的__信息为1时,显示模式立即变为2,即此时显示模式为__信息显示模式,同时,CPU发出关油门__,关闭油门第5章系统调试
5.1系统显示子程序的调试在Proteus仿真软件中,系统显示完全正常,但是放到硬件上数码管却完全显示乱码,不过LED指示标志灯却是正常亮与灭,既然程序在硬件上能运行,说明硬件电路没什么问题,有可能是字形码的设置问题,或数据的传送是否颠倒最后锁定为数据位权高低有问题按照我们的习惯,我们认为数码管的A,B,C,D,E,F,G,Dp等段的位权是从低到高的,而通过实验现象的观察分析发现,这些位权其实是从低到高,即A段是最高位,因此,修改相应字形码后显示正常了在用Proteus进行仿真时还碰到一个问题,那就是3连体数码管虽然能同时亮,但还是能发现各个数码管之间的点亮有短暂的先后视觉效应,而且亮的时间都非常短,感觉像是一闪而过然后就猜想有这个先后视觉效应是正常的,毕竟动态显示的数码点亮都需要延时,而这个一闪而过的现象是否可以改变,让它亮的时间持久一些,于是,在送显子程序中加了一个别for循环,用于多次点亮数码管,使它亮的时间长了一些,而之后的先后视觉效应也就消除了,看起来三个数码管是一起点亮的,达到预期效果
5.2键盘处理调试在硬件电路板还没有制出来之前,一直是使用Proteus仿真软件对系统软件进行调试,由于仿真软件的仿真是在理想的环境下运行的,没有外界的干扰,也没有所谓的键盘抖动因此程序中键盘处理这一模块中的每10ms调用一次键盘任务在仿真软件上行不通,因为在Proteus中,键盘一按下,没有所谓抖动,这个时刻应立即读取它的值,否则不可能读到键盘值然而在实际的硬件电路板上,程序运行时,则必须是10ms调用一次键盘任务子程序
5.3频率测量的调试在用Proteus进行仿真时,一直测不到__的频率,它总显示为0,经过反复的思考后仍然发现不了程序中有任何错误之处,最后,经同学帮忙,发现可能是数据溢出的问题,因为一个整型数据的最大值是65535,而那个子程序里面的一个整型数据j的值为_____00,数值溢出了,因此才使得后续产生错误的结果,然后把它修改为long型数据后,就能没到频率值50Hz了而这里,其实只是一个纯粹的C语言问题,就看自己考虑是否周全____
[1].张友德,等.单片微型机原理、应用与实践.__复旦大学出版社2003
[2].蔡美琴等.MCS-51系列单片机系统及其应用2版.北京:高等教育出版社2004
[3].苏家健,等.单片机原理及应用技术.北京:高等教育出版社2004
[4].王质朴,等.MCS-51单片机原理接口及应用.北京:北京理工大学出版社2009
[5].何宏,等.单片机厨师民接口技术.北京:国防工业出版社2006
[6].张道德,等.单片机接口技术(C51)版)北京中国水利水电出版社2007
[7].李全利,等.单片机原理及应用技术北京高等教育出版社2001
[8].李群芳,黄建.单片微型计算机与接口技术.北京电子工业出版社2001
[9]__刚,等.新编MCS-51单片机应用设计.哈尔滨哈尔滨工业大学出版社2003
[10].张先庭,向瑛等.单片机原理、接口与C51应用程序设计多点温度测试系统.北京国防工业出版社2011附录A硬件系统原理图附录B硬件电路板实物图附录C程序代码“Time
0.h”文件#includereg
51.h#include__th.h//文件包含#includePage.h//文件包含#includeintrins.h//文件包含#defineC_SampleFreq32//宏定义ucharAcUSampleValue
[32];//全局变量ucharAcISampleValue
[32];ucharDispBuf
[3];ucharShapeBuf
[3];ucharbCalUFin;uintFValue;uintUValue;uintSampTimeH;uintSampTimeL;uintxy;uintDispTime;ucharch=0;ucharC_ACVRef=0;ucharC_ACIRef=0;#defineADC_Power_On_Channal00xe0;//P
1.0为A/D输入#defineADC_Power_On_Channal10xe1;//P
1.1为A/D输入sfrAUXR=0x8e;sfrADC_CONTR=0xC5;sfrADC_DATA=0xC6;sfrADC_LOW2=0xBE;sfrP1M0=0x91;sfrP1M1=0x92;#defineADC_POWER0x80//宏定义#defineADC_FLAG0x10#defineADC_START0x08#defineADC_SPEEDLL0x00#defineADC_SPEEDL0x20#defineADC_SPEEDH0x40#defineADC_SPEEDHH0x60sfrCH=0XF9;//寄存器定义sfrCL=0XE9;sfrCCON=0XD8;sfrCMOD=0XD9;sfrCCAP0H=0XFA;sfrCCAP0L=0XEA;sfrCCAPM0=0XDA;__itEPCA_LVD=IE^6;//PCA模块中断允许位定义__itEADC_SPI=IE^5;//AD采样模块中断允许位定义__itCR=CCON^6;//__itCF=CCON^7;__itCCF0=CCON^0;voidAdDelayuintn{uintx;whilen--{x=5000;whilex--;}}voidInitADC//ADC采样初始化{P1=P1M0=P1M1=0xff;//P1口全部设置为开漏模式ADC_DATA=0;//转换结果寄存器清0ADC_CONTR=ADC_POWER|ADC_SPEEDLL;//开ADC工作电源,540个时钟周期//转换一次AdDelay2;//初次打开模拟电源,需适当延时}ucharGetADCResult//得到ADC采样值{ucharbaishigetemp;ADC_CONTR=ADC_POWER|ADC_SPEEDLL|ADC_START|ch;_nop_;_nop_;_nop_;_nop_;while!ADC_CONTRADC_FLAG;//等待转换完成ADC_CONTR=~ADC_FLAG;//关闭ADTemp=ADC_DATA;bai=temp*100/51/100%10+10;shi=temp*100/51/10%10;ge=temp*100/51%10;temp=bai*100+shi*10+ge;returntemp;voidPCA_Initiate{CMOD=0X80;CCON=0x00;CL=0;//PCA计数值初始化CH=0;CCAP0L=C_1MSCount%256;//1ms的定时值,CCAP0H=C_1MSCount/256;CCAPM0=0X49;//PCA模块1工作于16位计数器EPCA_LVD=1;//允许PCA模块中断EA=1;CR=1;//定时器开始运行}//******************以下为PCA模块0的中断服务程序**************//voidPCA_Interruptvoidinterrupt6{CL=0;CH=0;//计数值清0Ticks++;//时间滴答加1CCF0=0;//清中断标志CCAPM0=0x49;//PCA模块0工作于16位计数器}voidTimerInt_Initvoid//外部中断0与定时器
0、1的初始化{TMOD=0x11;//定时器
0、1都工作在16位计数器TH1=TL1=0;//定时器1计数初值清0EX0=ET0=1;//开外部中断0和定时器0IT0=1;//外部中断0的触发方式为下降沿触发}voidEx0_ISRvoidinterrupt0using1{staticbitStartPluse=0;//静态位变量,用来记录下降沿位置staticbitIsFreqGet=0;//在还没测到周期时为0为启动T0,否则启//动T0uinti;unsignedlongj;ifStartPluse==0//第一次,启动T1{TR1=1;//初次出现下降沿启动定时器1,开始计时ifIsFreqGet==1//如果前面已测到频率了,则可以启动定时器T0了{TH0=SampTimeH;TL0=SampTimeL;TR0=1;}}else//第二次,关T1{TR1=0;//第二次出现下降,一个完整的周期出现了,关定时器TR0=0;i=TH1*256+TL1;//计算T1的计数值j=C_SYSCLK/12;FValue=j/i;//测得频率i/=32;SampTimeH=0xffff-i/256;SampTimeL=0xffff-i%256;//计算定时器T0初始值TH1=TL1=0;IsFreqGet=1;//已测到周期}StartPluse=!StartPluse;}voidTime0_ISRvoidinterrupt1using2{staticucharSampleCount=0;//采样次数,最大32次staticbitSampleStep=0;//采样电压,Step=1采样电流TH0=SampTimeH;TL0|=SampTimeL;//定时器0重新赋初始值//*******************以下是电压采样阶段**********************//ifSampleStep==0{ifbCalUFin==0//如果上次采样数据没处理完,关定时器T0,不采样TR0=0;else{AcUSampleValue[SampleCount]=GetADCResult;/采样电压值保存SampleCount++;//采样次数加1ifSampleCount=C_SampleFreq//如果32点采样完{bUISelect1;//模拟开关接电流端bCalUFin=0;//置电压采样数据尚未处理标识SampleCount=0;//初始化下次采样的计数器SampleStep=1;TR0=0;//关采样,当下一个沿到来时,由外部中断0启动}//下一轮的采样}}//********************以下为电流采样阶段**********************//else{ifbCalUFin==0//如果上次采样数据没处理完,关定时器T0,不采样TR0=0;else{AcISampleValue[SampleCount]=GetADCResult;//采样电流保存SampleCount++;//采样次数加1ifSampleCount=C_SampleFreq//如果32点采样完{bUISelect0;//模拟开关接电压端bCalIFin=0;//置电流采样数据尚未处理标识SampleCount=0;//初始化下次采样的计数器SampleStep=0;//关采样,当下一个沿到来时,由外部中断0启动TR0=0;//下一轮的采样}}}}void__in{InitADC;TimerInt_Init;PCA_Initiate;DispMode=0;Hold=0;Page=0;while1{SysDispTask;KeyTask;}}//******************以下为”Disp.h”文件*****************************//#defineuintunsignedint#defineucharunsignedchar#defineC_SYSCLK11059260#defineC_1MSCountC_SYSCLK*1/1000/12ucharShapeCode
[16]={0xfc0x600xda0xf20x660xb60xbe0xe00xfe0xf60x7a0x020x7c0xee0x8e0x__};//字型码//d-UAFPuintTicks;__its1=P2^1;__its2=P2^2;__its3=P2^3;voiddelayuinti{ucharj;forj=0;j50;j--whilei--;}//***********以下为拆分函数********************************////InData为拆分前数值,OutData拆分后的数字存放位置,OutData
[0]存百位,OutData
[1]存十位,OutData
[1]存个位{voidDataSeparateuintInDatauchar*OutDataifInData999InData=999;*OutData++=InData/100;InData=InData%100;*OutData++=InData/10;*OutData=InData%10;}//***********查找字型码函数************////disp_buf要显示的3个数字的存放位置//shape_buf,对应数字字形码存放位置//dot_pos,要显示小数点的位置,小数点位置从左到右依次为0,1,2,最后一位不显示小数点,当Dot的值大于等于2时,不显示小数点voidFindShapeuchar*disp_bufuchar*shape_bufuchardot_pos{shape_buf
[0]=ShapeCode[disp_buf
[0]];shape_buf
[1]=ShapeCode[disp_buf
[1]];shape_buf
[2]=ShapeCode[disp_buf
[2]];ifdot_pos2shape_buf[dot_pos]|=0X01;}//******************74LS164串转并函数****************************//voidShift164ucharIn{__UF=In;whileTI==0;TI=0;}//***************************送显子程序***************************//voidSendDispuchar*shape_buf{uchari;fori=0;i200;i++{s3=1;Shift164shape_buf
[2];delay300;s3=0;s2=1;Shift164shape_buf
[1];delay300;s2=0;s1=1;Shift164shape_buf
[0];delay300;s1=0;}}bitTimeOutuint*OldTicksuintTimeMs{unsignedintdiff;diff=Ticks-*OldTicks;if!TimeMs||diff=TimeMs{*OldTicks=Ticks;return1;}return0;}//*********************************以下为UIFDisp.__件************************//#includeDisp.h#defineC_DispOFF0x00ucharDispBuf
[3];ucharShapeBuf
[3];ucharSetBuf
[3];uintDispTime;ucharDispMode;ucharDotPos;ucharHold=0;ucharWhoHold=0;bitDot;ucharDotPos;ucharSetPos;uintGetAd;uintUValue=230;uintIValue=250;uintFValue=500;__itLED1=P1^6;__itLED2=P1^7;__itLED3=P2^0;//__itselectui=P2^3;#defineC_On0#defineC_Off1#defineLEDVOn{LED1=C_On;LED2=C_Off;LED3=C_Off;}#defineLEDIOn{LED1=C_Off;LED2=C_On;LED3=C_Off;}#defineLEDFOn{LED1=C_Off;LED2=C_Off;LED3=C_On;}voidUIFDispcharWhoDisp{ifWhoDisp==0{DataSeparateUValueDispBuf;FindShapeDispBufShapeBuf0;LEDVOn;}elseifWhoDisp==1{DataSeparateIValueDispBuf;FindShapeDispBufShapeBuf0;LEDIOn}elseifWhoDisp==2{DataSeparateFValueDispBuf;FindShapeDispBufShapeBuf2;LEDFOn}SendDispShapeBuf;}voidUIFCycleDispbitHolducharWhoHold{staticcharStep=0;ifHold==1{ifWhoHold2WhoHold=0;Step=WhoHold;UIFDispStep;}else{UIFDispStep++;Step%=3;}}voidDispSetDatacharSetPosbitDotcharDotPos{staticcharStep;ifDot==1FindShapeSetBufShapeBufDotPos;elseFindShapeSetBufShapeBuf3;ifStep==1ShapeBuf[SetPos]=C_DispOFF;SendDispShapeBuf;Step++;Step%=2;}voidSysDisp{ifDispMode==0UIFCycleDispHoldWhoHold;elseifDispMode==1DispSetDataSetPosDotDotPos;elseifDispMode==2SendDispShapeBuf;}voidSysDispTaskvoid{//RdAd;ifTimeOutDispTime500SysDisp;}//**************************以下为Page.__件***********************//#includeUIFDisp.hucharPage;__itKey1=P1^3;__itKey2=P1^4;__itKey3=P1^5;#defineC_d10#defineC_Line11#defineC_Key10x80#defineC_Key20x81#defineC_Key30x82#defineC_FirstScan0#defineC_KeyShake1#defineC_WaitRelase2#defineC_Keys3ucharKeyValue;ucharPageTemp=0;uintKeyTime;uintSet__xU=265;uintSetMinU=195;uintSet__xI=250;uintSet__xF=550;uintSet__xP=100;typedefstruct{ucharKey1:1;ucharKey2:1;ucharKey3:1;ucharReserve:5;}Key_GPIO;typedefunion{ucharInKey;Key_GPIOKeyGPIO;}Mix_In_Key;Mix_In_KeyMixInKey;typedefstruct{ucharKeyNo;void*Fun;}Page_KeyFun;voidGetKey//读键盘函数,它把读到的键盘对应的端口值保存在MixInKey变量中{MixInKey.KeyGPIO.Key1=!Key1;//Key1保存,键按下为0,取反后变1MixInKey.KeyGPIO.Key2=!Key2;//Key2保存,键按下为0,取反后变1MixInKey.KeyGPIO.Key3=!Key3;//Key1保存,键按下为0,取反后变1MixInKey.KeyGPIO.Reserve=0;//Key1保存,键按下为0,取反后变1}//**************键盘扫描程序,它是按照前述的状态********************//voidKeyScanvoid{staticucharstate=C_FirstScan;staticucharOldKey;GetKey;switchstate{caseC_FirstScan:ifMixInKey.InKey!=0//有键按下,转C_KeyShake态state=C_KeyShake;//否则自环break;caseC_KeyShake:ifOldKey==MixInKey.InKey//去抖动状态,如果前后值相等state=C_WaitRelase;//说明不是抖动,转C_WaitRelas态elsestate=C_FirstScan;break;//如是抖动,转初始态caseC_WaitRelase:ifMixInKey.InKey==0//等待释放状态,如果释放了{uchark;KeyValue=0x80;//这时,键盘尚未处理最高位置1fork=0;kC_Keys;k++{ifOldKey0x01==0x01//查找是哪个键按下{KeyValue+=k;break;}//求出键值,找到退出elseOldKey=1;//否则看是否为下一个键按下}state=C_FirstScan;}default:break;}OldKey=MixInKey.InKey;//记录刚读的键值}//**********第0页对应两个按键(KEY1,KEY3)对应的函数**********//Page0Key1Fun{PageTemp++;//与此同时Page一样,是个全局变量PageTemp%=7;//最大是第6页SetBuf
[0]=C_d;SetBuf
[1]=C_Line;//前面2位显示“d-”SetBuf
[2]=PageTemp;//后面1位显示页号SetPos=2;//第3位闪烁Dot=0;//不显示小数点DispMode=1;//显示模式为设定值显示}voidPage0Key3Fun{Page=PageTemp;ifPage==6//如果是主显页面,显示电压、电流、频率等{DispMode=0;//显示模式0Hold=0;//刚开始不固定某一变量显示}elseifPage==0{DispMode=0;Hold=0;}elseifPage==1//否则进入设定页面显示{DataSeparateSet__xUDispBuf;//将门限值抓分SetBuf
[0]=DispBuf
[0];SetBuf
[1]=DispBuf
[1];SetBuf
[2]=DispBuf
[2];SetPos=0;DotPos=0;Dot=0;}elseifPage==2{DataSeparateSetMinUDispBuf;SetBuf
[0]=DispBuf
[0];SetBuf
[1]=DispBuf
[1];SetBuf
[2]=DispBuf
[2];SetPos=0;DotPos=0;Dot=0;}elseifPage==3//I{DataSeparateSet__xIDispBuf;SetBuf
[0]=DispBuf
[0];SetBuf
[1]=DispBuf
[1];SetBuf
[2]=DispBuf
[2];SetPos=0;DotPos=1;Dot=1;}elseifPage==4//F{DataSeparateSet__xFDispBuf;SetBuf
[0]=DispBuf
[0];SetBuf
[1]=DispBuf
[1];SetBuf
[2]=DispBuf
[2];SetPos=0;DotPos=1;Dot=1;}else//P{DataSeparateSet__xPDispBuf;SetBuf
[0]=DispBuf
[0];SetBuf
[1]=DispBuf
[1];SetBuf
[2]=DispBuf
[2];SetPos=0;Dot=0;}}//****************以下是第1页3个按键对应的3个函数介绍,该页面实现高压门限电压Set__xV的设定***********//voidPage1Key1Fun{SetBuf[SetPos]++;SetBuf[SetPos]%=10;//当前设置位数字(0~9)加1}voidPage1Key2Fun{SetPos++;SetPos%=3;//设定位置(0~2)前移}voidPage1Key3Fun{uintTemp0;Temp0+=SetBuf
[0]*100+SetBuf
[1]*10+SetBuf
[2];Set__xU=Temp0;//最高电压门限值设定好了送Set__xU保存Page=PageTemp=0;//切换到初始页面,并进行初始页面初始化SetBuf
[0]=C_d;SetBuf
[1]=C_Line;//前面2位显示“d-”SetBuf
[2]=0;//后面1位显示“0”SetPos=2;Dot=0;//不显示小数点DispMode=1;//显示模式为设定值显示}//*******以下第2页第5页的功能原理与第1页相似,不再叙述***********//voidPage2Key1Fun{SetBuf[SetPos]++;SetBuf[SetPos]%=10;}voidPage2Key2Fun{SetPos++;SetPos%=3;}voidPage2Key3Fun{uintTemp0;Temp0+=SetBuf
[0]*100+SetBuf
[1]*10+SetBuf
[2];SetMinU=Temp0;//WriteEERomSetHighVC_SetVHigh_Addr;Page=PageTemp=0;SetBuf
[0]=C_d;SetBuf
[1]=C_Line;SetBuf
[2]=0;SetPos=2;Dot=0;DispMode=1;}voidPage3Key1Fun{SetBuf[SetPos]++;SetBuf[SetPos]%=10;}voidPage3Key2Fun{SetPos++;SetPos%=3;}voidPage3Key3Fun{uintTemp0;Temp0+=SetBuf
[0]*100+SetBuf
[1]*10+SetBuf
[2];Set__xI=Temp0;//WriteEERomSetHighVC_SetVHigh_Addr;Page=PageTemp=0;SetBuf
[0]=C_d;SetBuf
[1]=C_Line;SetBuf
[2]=0;SetPos=2;Dot=0;DispMode=1;}voidPage4Key1Fun{SetBuf[SetPos]++;SetBuf[SetPos]%=10;}voidPage4Key2Fun{SetPos++;SetPos%=3;}voidPage4Key3Fun{uintTemp0;Temp0+=SetBuf
[0]*100+SetBuf
[1]*10+SetBuf
[2];Set__xF=Temp0;//WriteEERomSetHighVC_SetVHigh_Addr;Page=PageTemp=0;SetBuf
[0]=C_d;SetBuf
[1]=C_Line;SetBuf
[2]=0;SetPos=2;Dot=0;DispMode=1;}voidPage5Key1Fun{SetBuf[SetPos]++;SetBuf[SetPos]%=10;}voidPage5Key2Fun{SetPos++;SetPos%=3;}voidPage5Key3Fun{uintTemp0;Temp0+=SetBuf
[0]*100+SetBuf
[1]*10+SetBuf
[2];Set__xP=Temp0;//WriteEERomSetHighVC_SetVHigh_Addr;Page=PageTemp=0;SetBuf
[0]=C_d;SetBuf
[1]=C_Line;SetBuf
[2]=0;SetPos=2;Dot=0;DispMode=1;}下面是第6页2个按键对应的函数介绍,该页面主要实现单独显示和循环显示的切换voidPage6Key1Fun{staticcycletemp=0;//该静态变量的值决定单独显示哪个变量ifcycletemp==0{WhoHold=0;Hold=1;}//等于0,固定显示电压ifcycletemp==1{WhoHold=1;Hold=1;}//等于1,固定显示电流ifcycletemp==2{WhoHold=2;Hold=1;}//等于2,固定显示频率cycletemp++;DispMode=0;cycletemp%=3;}voidPage6Key3Fun//按下该键进入循环显示界面{Page=PageTemp=0;Dot=0;Hold=0;DispMode=0;}codePage_KeyFunPage0KeyFun
[2]={{C_Key1Page0Key1Fun}{C_Key3Page0Key3Fun}};codePage_KeyFunPage1KeyFun
[3]={{C_Key1Page1Key1Fun}{C_Key2Page1Key2Fun}{C_Key3Page1Key3Fun}};//Set__xFcodePage_KeyFunPage2KeyFun
[3]={{C_Key1Page2Key1Fun}{C_Key2Page2Key2Fun}{C_Key3Page2Key3Fun}};//SetMinFcodePage_KeyFunPage3KeyFun
[3]={{C_Key1Page3Key1Fun}{C_Key2Page3Key2Fun}{C_Key3Page3Key3Fun}};//SetIcodePage_KeyFunPage4KeyFun
[3]={{C_Key1Page4Key1Fun}{C_Key2Page4Key2Fun}{C_Key3Page4Key3Fun}};//Set__xFcodePage_KeyFunPage5KeyFun
[3]={{C_Key1Page5Key1Fun}{C_Key2Page5Key2Fun}{C_Key3Page5Key3Fun}};//Set__xPcodePage_KeyFunPage6KeyFun
[3]={{C_Key1Page6Key1Fun}{C_Key3Page6Key3Fun}};//CycleorSingle//Page_Keyfun指针数组codePage_KeyFun*PageKeyAddr
[7]={Page0KeyFunPage1KeyFunPage2KeyFunPage3KeyFunPage4KeyFunPage5KeyFunPage6KeyFun};ucharcodePageEnKeys
[7]={2333332};voidPageKeyPro__ssucharPage//加下拉{uchari;Page_KeyFun*FirstKey;FirstKey=Page_KeyFun*PageKeyAddr[Page];//找到某页对应结构体//数组首地址fori=0;iPageEnKeys[Page];i++//查找该页中是哪个键按下{ifFirstKey-KeyNo==KeyValue//找到了{FirstKey-Fun;//处理该键对应的函数KeyValue=KeyValue0x7f;//键值最高位清0,表示该//键已处理了break;}FirstKey++;}}voidKeyTask{ifTimeOutKeyTime10{KeyScan;//键盘扫描PageKeyPro__ssPage;//键盘处理}}单片机__模块键盘模块__处理模块驱动、显示模块频率测量模块__采样模块单片机测频电路X3LED电压互感器74LS164驱动3连体数码管理体制光电耦合电路调理电路电流互感器I/V变换X3按键关油机电路图3-3按键抖动__柴油发电机测试系统人机接口模块AD采样模块数据处理模块数码管显示模块键盘处理模块频率测量模块电压电流采样模块数据有效值计算__信息设置模块开始初始化A/D采样调显示子程序调数据处理子程序调键盘处理子程序。