版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第2章全自动电加热锅炉控制器设计
2.1引言2.2全自动电加热锅炉控制器设计任务书2.3设计方案2.4硬件电路设计2.5软件设计2.6程序清单2.1引言电加热锅炉具有清洁、高效等优点,可实现采暖供热、供应热水等功能。具有自动控制功能的电加热锅炉被广泛应用于家庭及宾馆等场所的供热及热水供应,因此开发自动化程度高、操作方便、安全可靠的电加热锅炉具有实际的应用价值。2.2全自动电加热锅炉控制器设计任务书
1.设计任务设计一个全自动电加热锅炉控制器,该控制器能够按照设定的温度在设定的时间段内自动运行,并控制加热器及水泵使锅炉输出的热水水温保持在设定值,从而实现全自动的加热控制。用户可以通过键盘设定温度、运行时间段及系统时间等信息,系统的运行温度、设定温度及时间信息通过LCD显示器显示。系统要求具有过热及缺水的报警功能。
2.设计要求
(1)温度的设定功能。通过键盘设定运行时的温度,温度的设定范围为5~90˚C。
(2)定时功能。系统运行时可以在一天时间内最多设定4个运行的时间段,运行时间段通过键盘进行设定,系统启动运行时只在设定的时间段内运行,其他时间段内系统处于待机状态。
(3)运行控制功能。通过键盘实现系统的运行与停止控制功能。一旦系统投入运行,控制器自动控制加热器和水泵的启停,使锅炉出水的温度为设定的温度,并显示运行温度与当前时间等运行信息。
(4)温度测量、控制与报警功能。系统投入运行后,自动测量水温,使炉内水温在设定的范围内运行,当温度低于设定温度时加热器运行,当温度高于设定温度时水泵运行,加热器停止运行。
(5)显示功能。系统要求能够显示时间、温度以及运行时的相关信息。
(6)时间的记忆功能。当出现停电或断电情况时,系统能够保存当前运行的相关设定值,重新上电后系统可以按照原来的设定值运行。
(7)故障报警功能。当系统在运行过程中出现过热或者缺水干烧现象时,系统进入过热保护状态,加热器停止运行,并发出运行报警信号。2.3设计方案依据设计任务书所提出的各项要求进行分析,可以得出该控制器必须具备以下的功能电路模块或相关的接口电路:键盘及其接口电路、LCD接口电路、温度测量电路、加热器与水泵控制接口电路、报警指示电路、时钟电路及ROM存储器电路等。当然,要把这些单元电路组合在一起还离不开主处理器或CPU。由此可以得出全自动电加热锅炉控制器的结构框图,如图2-1所示。图2-1控制器结构框图考虑到该控制器的主要控制任务及其接口设备的情况,该控制器的主CPU还是以单片机作为主处理器较为合适。对于该控制器而言并没有实时性能特别高的控制要求,也没有大量的、复杂的控制算法,接口设备主要是键盘、LCD显示器、时钟芯片及加热、水泵的控制接口,对于这些控制要求及相关的设备接口实现采用单片机完全可以达到要求,并且实现起来方案简单,灵活、成本低廉。根据以上的分析,本设计采用了以W78E58B为主处理器的设计方案。该处理器具有与51系列单片机完全兼容的指令系统,开发平台及开发手段丰富;内置有36 KB的程序存储器,方便用来存放大量的程序代码;丰富的I/O接口等资源,方便用来连接外围的接口设备等。2.4硬件电路设计该系统的主要外围硬件有键盘、LCD显示器、时钟芯片、串行口ROM、温度测量电路、加热器和水泵控制电路及故障检测电路等。在此系统的设计中对这些外围接口电路的设计与应用是该系统设计成败的关键,下面就针对这些接口电路的设计分别加以介绍。2.4.1键盘接口设计该系统中键盘的主要功能为设置运行的相关参数及输入操作命令,为了便于操作,这里设置了8个按键来输入相关的键盘命令。为了设计的简化,这里的键盘电路采用了独立式键盘接口,按键的个数为8个,正好可以用一个8位的I/O口来连接键盘。在该系统的设计中由于要连接LCD显示器,因此CPU的引脚数目不够分配,为简化设计的硬件,这里采用了复用技术以减少I/O引脚的需求。具体来说就是把键盘接口和LCD的数据端口进行了复用,由于这里键盘接口对于CPU来说为输入接口,而LCD的数据口对CPU来说为一个输出口,因此可以把这两个端口进行复用,以达到节约I/O引脚的目的。图2-2为键盘接口电路图。其中图2-2(a)为键盘接口板的电路图,图2-2(b)为键盘接口板与主控制器的连接电路图。也就是说,控制系统被分成了两个电路板来实现,键盘和状态指示灯被单独布置在一块电路板上,主处理器及其他电路被布置在一块电路板上,这样便于电路系统的安装。因此图2-2(a)中所示的键盘与主控制器之间通过JP_KEY接口相连。还可以看出,键盘接口信号连接到主控制器板后并不是直接连接到P0口,而是通过一片74LS244进行缓冲之后才连接到P0口的。在此要特别指出的是,此处P0口被用作一般I/O口,因此需外部上拉。当CPU要进行键盘扫描时,通过I/O口线控制74LS244的数据传输使能信号,即标号为_KEY的信号变低有效就可以实现键盘状态的读取了,而当_KEY信号为高电平时,键盘接口为高阻,此时可以通过P0口进行LCD的相关操作,以实现P0口的复用。通过JP_KEY接口把3个LED指示灯和1个蜂鸣器控制信号引到键盘接口板,这样就可以把状态指示与蜂鸣器都安装在键盘接口板上了。图2-2键盘接口电路图2.4.2LCD接口设计在这个系统中需要显示的信息较多,包括温度设定值和实际运行的温度值,运行时间段的设定值,运行过程中的实时时间值等信息。由于显示的信息较多,内容较复杂,采用LED数码管显示很难达到现实要求,因此这里采用了LCD显示模块来实现各种信息的显示。
LCD显示模块的种类繁多,在单片机作为控制器的系统中常采用的液晶显示模块有字符式LCD显示模块和图形式LCD显示模块,字符式LCD显示模块通常只能显示字符库中定义的西文或中文字符,不支持图形的显示,因此显示的灵活性受到限制。图形式LCD显示模块既可以显示中文、西文字符,也可以显示点阵图形,因此应用灵活,是目前电子系统中常用的显示手段。本设计中采用了图形式LCD显示模块。图形式LCD显示模块的种类也非常多,选用时应主要查看以下参数:首先要选择合适尺寸和面积的LCD模块,不同生产厂商生产的LCD模块其尺寸不一,不同点数的LCD模块尺寸通常不同,即使同样点数的LCD模块因为单个点的大小不同也可能不同,在实际应用中应选择满足要求尺寸的LCD模块;其次要注意LCD模块所采用控制器的型号,控制器不同会使外部操作的方法有差异;其次还要注意LCD模块的外部接口形式,有些采用了并行接口,而有些采用了串行接口。此次设计中采用了TOPWAY公司的图形式LCD模块LM6029,LM6029与单片机之间的接口如图2-3所示。图2-3LM6029与单片机之间的接口2.4.3时钟芯片接口设计该系统要实现定时控制功能,系统启动投入运行后能够在每天设定的时间段内自动运行,因此必须要有实时的系统时钟用于计时,要实现这一功能最简单的办法就是采用时钟芯片进行计时。如果给时钟芯片配以后备电池供电则可以实现连续不断的计时,不管系统断电还是上电。时钟芯片计时时间将作为控制器运行的基准时间,控制器获取该时间与设定的运行时间进行比较就可以控制电锅炉是否运行了。时钟芯片的种类也较多,这里选用的时钟芯片为DS1302,这是DALLAS公司生产的串行接口的时钟芯片,该芯片的主要功能如下:
(1)可以实时地计数秒、分、小时、日、月及年,并且可以进行闰年的补偿,可以计时到2100年。
(2)具有31个采用后备电池供电的非易失性RAM字节单元。
(3)通过串行接口实现了最简的I/O接口。
(4)操作电压范围为2.0~5.0V。
(5) 2.0V时消耗的电流小于200nA。
(6)可通过猝发模式读写地址连续的时钟单元或RAM。
(7)采用8脚的DIP封装或便于表面贴装的8脚SOIC封装。
(8)简单的3线接口。
(9) TTL信号兼容(VCC=5V)。
(10)优化的工业级工作温度范围:-40~+85℃。图2-4是DS1302的封装图。图2-4DS1302封装图
DS1302是具有实时时钟功能并带有31B静态RAM的时钟芯片,该芯片可以很方便地通过串行口与微处理器进行通信,芯片内的实时时钟可以提供秒、分、时、日、月及年等时间信息,并且可以在实时计时的过程中按照每月不超过31天来调整每月的天数以及对闰年进行自动的修正。时钟计时可以通过AM/PM标志位设定为24小时制或12小时制。
DS1302与微处理器之间的接口通过同步串行口来实现,仅需3根信号线就可以实现通信,这些信号线分别为复位信号、SCLK同步时钟信号及I/O串行数据的输入/输出信号。数据输入/输出时可以一次传输1B,也可以通过猝发方式一次传输最多31B。DS1302工作时的功耗很小,在其保持数据并维持内部时钟运行的情况下消耗的功耗小于1mW。
DS1302的内部结构主要包括输入移位寄存器、实时时钟、振荡分频电路、控制逻辑及31B的RAM,其内结构见图2-5。图2-5DS1302内部结构图
DS1302的引脚功能介绍如下:
VCC1、VCC2:VCC2为芯片供电的主电源,当VCC2有主电源输入时,芯片的电源供给由该端来提供,并且可以向连接在VCC1端的后备电池充电。也就是说,VCC1端为后备电源输入端,用于连接后备电池,在系统主电源缺失的情况下由该后备电池向芯片提供电源以维持内部实时时钟的工作和内部RAM中数据的安全。具体地,只要VCC2<VCC1+0.2V,则芯片的供电即由VCC1来承担。
SCLK:同步时钟信号输入端,用于串行口数据的同步输入/输出,该引脚的内部有一个40kΩ的内部上拉电阻。
I/O:同步数据的输入/输出端,该段内部也有40kΩ的内部上拉电阻。
:复位信号输入端,在正常的读/写操作中该端子必须设置为高电平。该引脚内部同样通过40kΩ的上拉电阻上拉。
X1、X2:外部晶振的连接端,通过这两个引脚在芯片的外部连接一个32.768kHz的晶振,晶振与内部的振荡电路组成完整的振荡电路,振荡信号经过分频产生实时时钟的计时脉冲信号。
1.DS1302的命令寄存器
DS1302的命令寄存器的结构如图2-6所示。对DS1302的任何数据传输操作都须通过命令寄存器来实现,在进行命令操作时必须使命令字的最高位为1,否则该命令将被DS1302忽略。命令寄存器的第6位用来设定访问的是DS1302内部的RAM还是实时时钟,当该位为0时访问内部实时时钟,当该位为1时访问DS1302内部的RAM。第5位到第1位用来指定被访问的寄存器的地址。最低位用来指定当前操作的性质:设置为0表示写操作,设置为1表示读操作。图2-6命令寄存器的结构
2.复位与时钟操作信号提供了两个方面的功能:
(1)当该信号为高电平时,打开DS1302内部移位寄存器,使能外部微处理器的访问。
(2)当该信号为低电平时,中断当前的数据传输操作,不管当前正在进行的是单字节的传输还是多字节的猝发传输。
SCLK信号用来同步数据的输入/输出操作,当信号为高电平输入数据时,输入数据必须在时钟信号的上升沿来到之前有效;而当输出数据时,数据是在时钟的下降沿被同步输出的。在数据输入/输出的过程中,信号变低,则当前的数据传输被中断取消,I/O信号线变为高阻状态。
3.数据的输入操作在8个SCLK信号的同步之下先输入一个字节的命令字,随后在另外8个时钟信号的同步下输入要输入的数据,多余的时钟信号将被忽略。数据的输入是从最低位开始传送的。
4.数据的输出操作要从DS1302读取数据必须先输入读命令,在SCLK信号的同步下,8位的命令字被输入后,即可从I/O端口得到要读出的数据。这里要注意读出的第一个数据是在输入命令最后一位被输入后的第一个时钟下降沿送出的。当一个字节被读出之后,如果还有SCLK信号送给DS1302,则DS1302将会送出下一个字节,并且一直持续到信号被拉低才结束数据输出。图2-7是DS1302的读/写操作时序图。图2-7DS1302读/写操作时序
5.猝发传送通过寻址地址号为31的单元可以实现DS1302内部时钟单元和RAM存储空间的猝发读/写访问(即当传送命令字时使命令字的1~5位全为高电平)。如同进行单字节的操作一样,命令字的第6位用来指定是对时钟还是对RAM进行访问,而第0位用来指定是进行读访问还是写访问。通过猝发方式访问时钟单元地址为9~31的寄存器单元是不存在的,当然也就不具有数据的存放能力了,对于RAM地址为31的单元也是没有数据存放能力的。猝发读/写时总是从地址号为0的单元的第0位开始进行操作的。当通过猝发方式对时钟单元进行写入时,前8个字节单元的数据必须按照顺序依次写入,而当写RAM单元时并没有必要一定把所有的31个字节数据都写入,每一个写入RAM单元的数据均对应存入RAM单元,不管是否写满31个字节。
6.时钟/日期单元时钟/日期单元由7个可读/写的寄存器组成,如图2-8所示。时钟/日期单元寄存器内的数据格式为BCD码格式。
7.时钟停止标志秒(SEC)寄存器的第7位(CH)被定义为时钟停止标志。当该位被设置为1时,时钟振荡器停止工作且DS1302将工作于低功耗的维持状态,消耗的电流小于100nA;当该位被设置为0时,时钟将开始工作。图2-8时钟/日期寄存器的结构示意图
8.AM-PM/12-24模式设定小时(HR)寄存器单元的第7位用来指定当前时钟是工作于12小时模式还是24小时模式。当该位为1时设定为12小时模式,此时小时寄存器单元的第5位用来设置AM/PM标志;当该位为1时表示PM,否则为AM。在24小时模式下,第5位用来表示小时值十进制位的第2个数字位。
9.写保护位控制寄存器(ControlRegister)的第7位为写保护位WP,控制寄存器的低7位,即第0位到第6位必须为0,读出时也始终为0。如果需要进行时钟寄存器或RAM单元的写入操作,则必须使控制寄存器各位均为0。当WP为高电平时,将阻止对任何DS1302的任何写入操作,因此如果要对DS1302进行写入操作,则必须使WP位设置为0。10.涓流充电控制寄存器(TrickleChargeRegister)涓流充电寄存器用来控制DS1302的涓流充电特性。图2-9是涓流充电电路的结构框图。涓流充电控制寄存器的高4位为充电状态选择位,为了防止意外的使能涓流充电,只有设置这4位为1010b时才使能涓流充电功能,而所有其他组合状态将禁止涓流充电功能。DS1302上电后的默认状态是禁止涓流充电功能的。控制寄存器的第3位、第2位用来选择充电二极管,当这两位的组合为01时,一个二极管被选择用来实现VCC2到VCC1之间的涓流充电;当这两位的组合为10时,两个二极管被选择用来实现VCC2到VCC1之间的涓流充电;当这两位的状态组合为00和11时,涓流充电功能也会被禁止。控制寄存器的最低两位用来实现充电限流电阻的选择,选择关系见表2-1。图2-9涓流充电电路结构图表2-1选择关系由表可知,当最低两位设置为00时没有电阻被选中,此时涓流充电功能同样也是被禁止的。通过充电电阻和充电二极管的选择可以控制涓流充电的最大电流。假如VCC2=5V,并且通过涓流充电寄存器设定通过一个二极管进行充电,充电限流电阻选择4kΩ,则最大的充电电流为以上内容是就DS1302的基本操作情况所做的基本介绍。下面给出设计中DS1302与单片机之间的接口电路,如图2-10所示。图2-10DS1320与单片机之间的接口图2-10中,VCC1外接备用电池B1,也可以通过JP_B插座引入后备供电电池。SCLK、D_IO、为DS1302与单片机之间的连接信号,单片机通过这三根信号线实现对DS1302的读/写操作。X1、X2引脚需要外接32.768kHz的标准晶振,其与内部电路共同组成完整的振荡信号。2.4.4串行E2PROM接口设计在该控制器的设计任务中,要求当系统断电之后,系统设定的运行信息能够继续保存,当系统重新上电之后,系统可以直接按照上次断电之前的设置信息运行,为了实现该项功能就必须设法保证设置信息在断电时不丢失。能够实现这一功能的措施有多种,可以采用SRAM+ 后备供电电池的方法、铁电存储器的方法或采用E2PROM来实现。这里考虑实际存储的数据量大小及成本等因素采用了串口E2PROM来存储设置信息,以及选择了24系列E2PROM存储器芯片AT24C02,这是一个具有2048位(256×8)的存储芯片,该芯片与单片机之间的接口电路如图2-11所示。图2-11AT24C02与单片机之间的接口下面以ATMEL公司的产品为例简要介绍24系列串行E2PROM的特征、结构、接口及操作情况。
1.24系列串行E2PROM的特征
(1)支持低电压和标准电压操作,最低操作电压低至1.8V。
(2)与I2C兼容的两线串行总线接口。
(3)施密特触发器输入以抑制噪声。
(4)兼容100kHz(1.8V)和400kHz(不小于2.5V)两种传输速率。
(5)自定时擦/写周期(包括自动擦除)。
(6) 8B或16B页写入缓冲器。
(7)具有硬件写保护功能。
(8)擦写次数1000000次以上。
(9)数据保存器100年。
(10) ESD保护电压>3000V。
(11)提供8引脚PDIP、SOIC、TSSOP和MSOP封装。
2.24系列存储器的内部结构
24系列存储器的内部结构主要由串行口控制逻辑、器件地址比较逻辑、总线操作启停逻辑、内部定时计数逻辑及E2PROM存储阵列等部分组成。当对器件进行操作时,控制逻辑对串行总线送来的信号进行解释执行,也可从存储阵列中读取数据,或者向指定的单元写入数据。
3.24系列串行E2PROM存储器的引脚
SCL:串行时钟信号。该信号用于串行数据输入/输出的同步,对于24系列器件该信号为输入信号。
SDA:串行数据引脚。该引脚为双向,用于把数据和地址输入/输出器件。该引脚为开漏输出,在使用时需外部接上拉电阻,当操作频率为100kHz时,外接电阻通常选10kΩ;当操作频率为400kHz时,外接电阻选2kΩ。
A2、A1、A0:器件/页地址输入端。在一个由I2C总线系统构成的E2PROM存储系统中,可以通过I2C总线连接多个存储器芯片,各个芯片分别编配不同的地址,访问时,主器件可以通过器件的地址对各器件进行寻址并访问。对于AT24C01A和AT24C02,可以在一个I2C系统中最多连接8个芯片,每个器件的地址编号由其A2、A1、A0的硬件连接来决定,比如A2A1A0=001B,则该器件的地址编号为001B,当主器件在访问发送器件编号为001B的器件时,该器件响应并给主器件做出应答。对于AT24C04,只用A2和A1作为器件的编址引脚,A0不用。对于AT24C08,只用A2作为器件的地址编码,A1和A0不用连接。对于AT24C16,地址编码引脚A2、A1、A0均不用,在一个系统中只能连接一片这样的器件。
WP:写保护引脚。该引脚接地则允许对器件进行正常的读/写操作,当该引脚接VCC时,AT24C01A、AT24C02、AT24C04将进入写保护功能,禁止外部数据的写入,但器件仍可以正常读出。AT24C08的写保护功能无效,AT24C16的写保护功能只对高地址8K位有效。
4.I2C操作协议
24系列器件的操作完全兼容I2C总线的操作规范,因此这里介绍的24系列器件的接口操作实际上就是I2C总线的操作。I2C总线信号有两个,即SCL和SDA信号。在I2C总线系统中进行数据操作的基本过程为:主器件先在总线上发送起始条件,随后主器件发送从器件的地址,被寻址的从器件做出应答,然后进行数据的读/写操作,数据读/写操作结束后主器件产生停止条件并结束总线操作。
I2C总线协议规定只有在总线空闲时才可以进行数据传输,并且在数据传输期间,在时钟线为高电平时,无论何时,数据线都必须保持稳定。时钟线为高电平时改变数据线将视为总线起始或停止条件。数据线和时钟线同为高电平被视为总线空闲状态。当时钟线SCL为高电平时,数据线SDA从高电平变为低电平表示总线操作起始条件,起始条件必须先于所有命令产生。当SCL线为高电平时,SDA从低电平变为高电平表示总线停止条件,所有总线操作必须在停止条件之前完成。图2-12为I2C总线操作起始条件和结束条件示意图。
I2C总线的数据传送格式是:在I2C总线开始传送信号后,送出的第一个字节数据是用来选择从器件地址的,其中前7位为地址码,第8位为方向位(R/W)。方向位为“0”表示发送,即主器件把信息写入所选择的从器件;方向位为“1”表示主器件将从从器件读信息。开始传送信号后,系统中的各个器件将自己的地址(即通过A2A1A0的外部连接所确定的地址)和主器件送到总线上的地址进行比较,如果与主器件发送到总线上的地址一致,则该器件即为被主器件寻址的器件,其用来接收信息还是发送信息则由第8位(R/W)确定。图2-12I2C总线操作起始条件和结束条件示意图在I2C总线上每次传送的数据字节数不限,但每一个字节必须为8位,而且每个传送的字节后面必须跟一个认可位(第9位),也叫应答位(ACK)。每次都是先传最高位,通常从器件在接收到每个字节后都会做出响应,即释放SCL线返回高电平,准备接收下一个数据字节,主器件可继续传送。如果从器件正在处理一个实时事件而不能接收数据(例如正在处理一个内部中断,在这个中断处理完之前就不能接收I2C总线上的数据字节),则可以使时钟SCL线保持低电平,从器件必须使SDA保持高电平,此时主器件产生1个结束信号,使传送异常结束,迫使主器件处于等待状态。当从器件处理完毕时将释放SCL线,主器件继续传送。当主器件发送完一个字节的数据后,接着发出对应于SCL线上的一个时钟(ACK)认可位,在此时钟内主器件释放SDA线,一个字节传送结束,而从器件的响应信号将SDA线拉成低电平,使SDA在该时钟的高电平期间为稳定的低电平。从器件的响应信号结束后,SDA线返回高电平,进入下一个传送周期。
5.AT24系列读/写操作
24系列E2PROM的读/写操作在起始条件之后,首先由主器件发送要访问的从器件的地址,不同型号的器件其地址的表示方法不同,具体的地址分配如图2-13所示。图2-1324系列E2PROM器件地址分配图对于AT24C01A/02,A2A1A0均表示从器件的地址,因此在一个I2C总线系统中,最多可以连接8个这样的器件。对于AT24C04,只有A2A1用来表示器件地址,P0用来表示器件的内部单元地址,原因是AT24C04的容量为4kb,对应的字节单元为512个,要表示这512个字节单元地址位数需要9位,因此P0实际就用来表示器件内部单元地址的第8位,此时系统中如果连接AT24C04,则最多可以连接4片。对于AT24C08/16也是同样的道理,这里不再赘述。
24系列器件的写操作可以分为按字节写操作和按页写操作两种情况。图2-14是按字节写操作的时序图。图2-14按字节写操作时序从图2-14可以看出,在进行字节写操作时,总线上先产生起始条件,随后主器件发送要访问的从器件地址,并给出读/写命令,被选中的从器件做出应答并发送ACK信号到总线上,主器件继续发送被选中器件的内部字节地址,并由从器件应答,之后主器件写入一个字节到被选中的单元并由从器件做出应答,这些操作完成之后,总线产生停止条件,整个写操作过程结束。图2-15为按页进行写操作的时序图。在该操作模式下,首先由主器件发送从器件的地址及从器件中要写入的第一个字节单元的地址,随后向选中的地址单元中可以连续写入最多一页数据,不同的器件一页数据对应的字节数不同,对于AT24C01A/02,一页数据对应的字节数为8,而对于AT24C04/08/16,每页数据对应的字节数为16。当进行页写入操作时,写入的字节数超过了一页的最大字节数则数据会发生卷绕,多出来的数据又会重新从被选中的第一个字节单元开始写入,从而覆盖原来写入的数据。同单字节写入相同,每次写入一个字节,从器件都会做出相应的应答。按页写操作同样以总线停止条件结束。图2-15按页写操作时序
AT24CXX系列器件的读操作可以分为三种情况,即当前地址读操作、随机读操作和连续读操作。在进行读操时涉及到当前地址的概念。所谓当前地址,是指器件在上次写或者读操作时最后操作过的字节单元地址+1,AT24XX系列器件内部的字节地址计数器就是用来保存当前地址的。当读/写的单元地址为器件末页的最后一个单元地址时,当前地址会发生卷绕,即当前读/写操作的地址为器件的最后一个字节地址时,内部字节地址寄存器中的地址会卷回到器件的首个单元地址。图2-16为当前字节读操作时序示意图。主器件产生起始条件后发送器件地址并使R/W位置1,被寻址的从器件做出应答,随后从器件就向总线送出当前字节内的8位数据,主器件接收到数据后并不做出应答,但随后就产生停止条件结束当前的总线操作。图2-16当前字节读操作时序随机读操作的时序如图2-17所示。在读操作之前,先要进行一次假写操作,通过该操作来选定操作的器件和器件中的字节单元地址。在假读操作之后,主器件立刻产生一次读操作读取从器件送出的数据,主器件在接收到数据之后不进行应答,随后产生停止条件结束整个总线操作。图2-17随机读操作时序以当前字节读操作或随机读操作为先导,都可以引起一次连续读操作。例如进行一次当前字节单元的读操作,在从器件送出第一个数据之后,如果主器件对从器件做出应答,则从器件会接着送出下一个字节数据,主器件对接收到的数据再进行应答,则从器件会再送出下一个字节单元的数据并一直这样循环下去,直到主器件接收到数据后不再应答,从器件将停止向主器件发送数据,最后主器件产生停止条件结束当前总线操作。随机读操作同样也可以引起一次连续读操作。图2-18为连续读操作的时序图。关于24系列器件还有许多大容量的器件,其操作方法与16kb以下的器件的操作方法还存在着不同,这里对这些器件的操作不再赘述,如果需要可以查阅相关资料。图2-18连续读操作时序2.4.5温度测量电路设计温度测量电路采用的传感器为PT100,这种传感器具有测温范围宽、精度高、可靠性高等优点。温度测量电路的核心是对有传感器输出的信号进行放大和调理,然后对该温度信号进行A/D转换,使单片机识别。为了降低成本,这里采用了廉价的运放LM324作为温度信号的放大和调理,其输出的信号由A/D转换芯片TLC549转换为数字信号。这里选用的A/D转换芯片为8位串行接口的A/D转换器,转换的精度虽然不高,但完全可以满足设计的需要。图2-19是温度测量电路原理图。图2-19温度测量电路原理图在该电路中,JP_SEN用来连接温度传感器PT100,这里采用了三线制的连接方法,用以减少引线造成的误差。PT100的信号是通过电桥电路输出的,为了提高电桥电路工作的精度,其供电电源采用高精度的2.5V稳定电源,该电源由TL431提供,同时这里还采用了高精度的电阻来构成电桥电路。这里需要测量的温度信号实际上是有着特定范围的,加热器的温度在通常情况下是正的温度而不会是负的或者零下温度,因此这里主要要解决的问题是如何测量零度以上正的温度。为了实现这样的目的并且简化电路的设计,这里采用了单电源给LM324供电的方式来实现信号的放大及调理。在此把从电桥电路输出的信号先通过两个信号跟随器,由于用单电源供电,因此运放的最小输入电压不能太小,电桥的两个桥臂输出的电压信号是2.5V的基准信号经过分压得到的,其幅值在0.25V附近变化,可以满足信号跟随器的要求。由于通常情况下加热器的水温高于零摄氏度,因此可以看出从接有传感器PT100的桥臂输出的信号大小总是高于固定桥臂输出的信号。经过两个电压跟随器后的信号再送入一个减法器进行比较,从而检测出温度信号,该温度信号经过最后一级的调理放大即可送入A/D转换器进行转换了。该电路看上去和仪用放大电路非常相似,但其实并不相同,在仪用放大器电路中通常要采用正负电源供电,这里只采用了单电源供电,此外,放大器的连接方法也有较大的区别。从TL431输出的2.5V基准信号既作为电桥电路的电源也作为A/D转换器TLC549的参考电压。从TLC549转换输出的数字信号由单片机读取进行处理。
TLC549是由德州仪器公司(TI)生产的8位CMOSA/D转换器,其主要特点如下:
(1)具有8位分辨率。
(2)支持差分参考电压输入。
(3)最小转换时间为17
s。
(4)转换频率可达到40kHz。
(5)具有编程控制的采样保持功能。
(6)带有片内时钟系统,典型操作频率为4MHz。
(7)宽电压工作范围为3~6V。
(8)最大功耗为15mW。
(9)采用CMOS工艺。
(10)采用串行接口,方便与处理器进行连接。
TLC549的芯片引脚图如图2-20所示,共有8个引脚,这些引脚的功能简述如下:
REF+、REF-:参考电压输入端。TLC549的参考电压输入支持单端输入,也支持差分电压输入。当采用单端输入时,REF+端的电压应高于2.5V,REF-端的电压应低于2.5V,并且REF+与REF-之间的电压差应该高于1V;当REF+和REF-作为差分电压输入时,这两个输入端的电压差不应低于4.75V,否则A/D转换器的不可调整误差将增加。
ANALOGIN:模拟信号输入端。待转化的模拟信号从该端子输入到A/D转换器。
I/OCLOCK:输入/输出时钟信号。其最高操作频率达到1.1MHz。
DATAOUT:数据输出端。该引脚输出A/D转化的结果。:片选信号。该信号与I/OCLOCK和DATAOUT共同配合实现外部处理器对TLC549的读/写操作。图2-20TLC549引脚图
TLC549的操作规则为:当为高电平时,DATAOUT引脚呈现高阻状态,I/OCLOCK信号无效,此时对TLC549的操作无效。当为低电平时,可以通过I/OCLOCK和DATAOUT引脚对TLC549进行操作,读取前一次的转换结果,并启动当前一次的A/D转换。具体来说,引脚变低之后,DATAOUT立刻输出前一次A/D转换结果的最高位A7,随后I/OCLOCK引脚每输入一个时钟的负跳沿,上次的转换结果就向DATAOUT移出一位,经过7个脉冲负跳沿,前次转换结果就全部输出到DATAOUT数据线上。之后I/OCLOCK引脚还需要输入一个负跳沿,当这些操作都完成之后,应被重新上拉为高电平,对TLC549的一次操作就完成了。这样的一次操作实际上完成了两件事情,其一是通过上述操作从TLC549内部读取了前一次A/D转换的结果,其二是启动了当前一次的A/D转换。TLC549内置了系统操作时钟,该操作时钟与I/OCLOCK引脚的时钟频率没有同步关系,这样就方便了用户的软、硬件设计。每次对TLC549进行操作时除读取前一次的转换结果之外,实际上也实现了新的一次A/D转换的采样,并启动当前转换,转换启动之后是在内部时钟的作用下自动完成的。对于TLC549来讲,从采样开始到转换完成所需要的总时间为25
s,因此TLC549的转换频率可以达到40kHz。图2-21是TLC549的操作时序图。图2-21TLC549操作时序图2.4.6加热器和水泵控制电路设计加热器和水泵均采用220V的市电供电,为了避免市电对主控制器的弱电系统造成干扰,这里采用了光电隔离措施来提高系统的抗干扰性能,来自于单片机的控制信号HEATER和PUMP信号分别用来控制加热器和水泵的运行与停止。经过光电隔离之后的信号用来控制两个24V的继电器,这两个继电器所提供的干接点在此用于220V加热器和水泵的控制。这里采用的光电隔离器为TLP521-2,内部含有两路光电通道,由于对速度没有特别的要求,因此在使用时主要考虑光电隔离器的驱动电流和电压要适当。为了可靠驱动继电器的线包,从光电耦合器输出的信号再经过三极管驱动去控制继电器工作。除了上述主要电路之外,该系统还包含缺水检测电路和电源电路。当加热器工作时,缺水检测电路检测系统是否缺水,以防止加热器缺水干烧造成事故。电源电路微系统提供+5V和 +24V两种工作电压,+5V电压为控制器弱电系统提供工作电源,+24V为系统继电器部分提供电源。图2-22为加热器和水泵控制电路。图2-22加热器和水泵控制电路2.5软件设计该系统软件设计的主要任务并不在于控制加热器及水泵的程序本身,这部分的程序并不复杂,程序编写量也不大,而主要的程序任务集中在显示与键盘相关的人机界面程序设计上。为了减少编程任务,提高编程的效率,这里采用C语言进行编程。下面对主要程序模块的编程进行必要的说明。2.5.1键盘扫描程序设计系统中键盘扫描程序的使用是非常频繁的,系统日期和时间的设定、运行温度的设定、运行时间段的设定及系统的启动停止控制都需要使用键盘扫描程序。系统中共设置了8个按键,每次进行键扫描都会带回一个键值,该键值反映当前有无键被按下,按下的键为哪一个。当键盘中仅有一个键被按下时,带回的键值为01H~08H,当有多个键同时被按下或无键被按下时,扫描程序带回的键值均为0FFH。由于键盘接口与LCD的数据接口共用单片机的P0口,因此在操作时必须进行必要的控制切换。键盘扫描程序如下:
unsignedcharKey_Scan(void)
{
uchartemp,key;
_CS1=1;
_CS_KEY=0;
P0=0xff;
_nop_();
_nop_();
_nop_();
_nop_();
temp=P0;
if((~temp)==0x00){_CS_KEY=1;_CS1=0;key=0xff;return(key);}Delay_10ms();temp=P0;if((~temp)==0x00){_CS_KEY=1;_CS1=0;key=0xff;return(key);}temp=~temp;switch(temp){case0x01:key=0x01;break;case0x02:key=0x02;break;case0x04:key=0x03;break;case0x08:key=0x04;break;
case0x10:key=0x05;break;case0x20:key=0x06;break;case0x40:key=0x07;break;case0x80:key=0x08;break;default:key=0xff;}
_FMQ=ON;for(;;){temp=P0;if((~temp)==0x00)break;}_FMQ=OFF;_CS_KEY=1;_CS1=0;return(key);}2.5.2LCD显示程序设计在此系统中LCD显示器被用来显示日期、时间及温度等信息,只有编写出基本的LCD操作程序才能更进一步编写各种更复杂的信息显示程序。LCD模块要正常使用,首先必须进行正常的初始化操作,这是对LCD进行操作的前提。现在的LCD模块一般都提供完整的初始化操作程序样例,用户只需按照厂家提供的初始化例程去操作一般都可以顺利实现正常初始化,在完成初始化操作之后就可以在LCD模块上显示信息了。这里选用的LCD模块为图形点阵模块,所显示的字符信息实际上要用字模生成软件生成,并存储在单片机系统的ROM中。LCD要显示这些字符信息,首先必须设定字符信息在LCD屏上的坐标位置,随后由单片机控制把要显示的字符点阵数据传送到LCD模块的显示存储器中进行显示。LCD显示模块内部带有显示控制器,该控制器负责接收外部处理器的命令和数据,进行各种操作和显示,这样就大大降低了单片机的控制难度,因此这里单片机只需向LCD模块传送正确的命令和数据即可。设计中选用的LCD模块为LM6029,关于该模块的详细操作命令可以参考其使用手册,下面就LCD显示的几个关键子程序作一介绍。
A/LCD初始化函数Initialize():该函数主要完成LCD模块上电之后的基本初始化操作,为正常使用做准备。该函数的定义如下:voidInitialize(){_CS1=0;_RES=0;Delay(1000);_RES=1;LcdCommand(0xa0);LcdCommand(0xc8);LcdCommand(0xa2);LcdCommand(0x2f);
LcdCommand(0x81);LcdCommand(0x29);LcdCommand(0x40);
LcdCommand(0xaf);}
B/LCD写命令函数:该命令把一个命令字节写入LCD模块,命令的执行由模块内部的控制器完成。该函数的定义如下:
voidLcdCommand(ucharCom)
{
_CS_KEY=1;
_RS=0;
LcdDataPort=Com;
_nop_();_nop_();_nop_();
_WR=0;
_nop_();_nop_();_nop_();
_WR=1;
}
C/LCD写数据函数:该函数负责把显示数据写入LCD的显示缓存,并由模块内部的控制器控制显示。该函数的定义如下:
voidLcdDataWrite(ucharData)
{
_RS=1;
LcdDataPort=Data;
_nop_();_nop_();_nop_();
_WR=0;
_nop_();_nop_();_nop_();
_WR=1;
}
D/设置LCD显示位置的函数:用于显示位置设置的函数有两个,函数SetPage(ucharPage)用来设置显示位置的Y轴坐标,函数SetColumn(ucharColumn)用来设置X轴的坐标。这两个函数的定义如下:
voidSetPage(ucharPage) //设置页地址函数
{
Page=Page&0x0f;
Page=Page|0xb0;
LcdCommand(Page);
}voidSetColumn(ucharColumn) //设置列地址函数{uchartemp;temp=Column;Column=Column&0x0f;Column=Column|0x00;LcdCommand(Column);temp=temp>>4;Column=temp&0x0f;Column=Column|0x10;LcdCommand(Column);}
E/显示子函数:在此次设计中需要显示数字、符号及不同规格的中文字符,根据这些显示需要编写了显示8×16点阵的函数DisplayPic(ucharPage,ucharColumn,uchar*PicKu,bitFlag)、显示16×16汉字点阵的函数Displaywz(ucharPage,ucharColumn,uchar*PicKu,bitFlag)及显示24×24汉字点阵的函数Display24(ucharPage,ucharColumn,uchar*PicKu)。数字和符号使用DisplayPic函数显示,使用时需给出显示的地址坐标Page和Column,待显示的点阵字符存放的指针PicKu、位标志FLAG用来设置是否实现反色显示。16×16的汉字点阵显示与8×16的点阵显示原理相同,也可以通过FLAG标志实现反色显示。24×24的汉字点阵显示无反色显示功能。这几个函数的定义如下://显示8×16点阵的函数,可实现反色显示voidDisplayPic(ucharPage,ucharColumn,uchar*PicKu,bitFlag){uchari,j;
for(j=0;j<2;j++){SetPage(Page+j);
SetColumn(Column);for(i=0;i<8;i++){if(Flag==1) //反色显示
LcdDataWrite(~PicKu[i*2+j]);else //正常显示
LcdDataWrite(PicKu[i*2+j]);}}}//显示16×16汉字点阵的函数voidDisplaywz(ucharPage,ucharColumn,uchar*PicKu,bitFlag){uchari,j;for(j=0;j<2;j++){SetPage(Page+j);SetColumn(Column);for(i=0;i<16;i++){if(Flag==1)//反色显示
LcdDataWrite(~PicKu[i*2+j]);elseLcdDataWrite(PicKu[i*2+j]);}}}//显示24×24汉字点阵的函数voidDisplay24(ucharPage,ucharColumn,uchar*PicKu){uchari,j;for(j=0;j<3;j++){SetPage(Page+j);SetColumn(Column);for(i=0;i<24;i++){LcdDataWrite(PicKu[i*3+j]);}}}
F/LCD清屏函数:该函数用来清除CLD屏上以前显示的所有内容。其定义如下:
voidClearScr()
{
uchari,j;
for(i=0;i<8;i++)
{
SetColumn(0);
SetPage(i);
for(j=0;j<128;j++)
{LcdDataWrite(0x00);}
}
}2.5.3DS1302操作程序设计对于DS1302的操作主要分为两方面,一个为读操作,一个为写操作,其中读操作主要为获取时钟芯片的计时值,写操作主要是为了进行日期时间的调整。函数的定义如下:
//写时钟芯片函数
voidWr_DS1302(ucharaddress,ucharwbyte)
{
uchartemp;
uchari;
temp=address;
_SCLK=0;
_nop_();
_nop_();
_nop_();
_nop_();_nRST=1;_nop_();_nop_();
_nop_();_nop_();for(i=0;i<8;i++){if((temp>>i)&0x01)_D_IO=1;else_D_IO=0;_nop_();
_nop_();_nop_();_nop_();
_SCLK=1;_nop_();_nop_();_nop_();_nop_();_nop_();_SCLK=0;
//temp=address;}_nop_();_nop_();_nop_();
_nop_();temp=wbyte;
for(i=0;i<8;i++){if((temp>>i)&0x01)_D_IO=1;else_D_IO=0;_nop_();_nop_();_nop_();_nop_();_SCLK=1;_nop_();_nop_();_nop_();
_nop_();_SCLK=0;//temp=wbyte;}_nop_();_nop_();_nop_();_nop_();_nRST=0;}//读时钟芯片函数ucharRd_DS1302(ucharaddress){uchartemp;uchari;
temp=address+0x01;_SCLK=0;_nop_();_nop_();_nop_();_nop_();_nRST=1;_nop_();_nop_();_nop_();
_nop_();for(i=0;i<8;i++)
{if((temp>>i)&0x01)_D_IO=1;else_D_IO=0;_nop_();
_nop_();_nop_();_nop_();_SCLK=1;_nop_();
_nop_();_nop_();_nop_();_SCLK=0;//temp=address;}_nop_();_nop_();_nop_();_nop_();for(i=0;i<7;i++){temp=temp>>1;if(_D_IO==1)temp=temp+0x80;
_nop_();_nop_();_nop_();_nop_();_SCLK=1;_nop_();_nop_();
_nop_();_nop_();_SCLK=0;_nop_();_nop_();_nop_();_nop_();}temp=temp>>1;
if(_D_IO==1)temp=temp+0x80;
_nop_();_nop_();_nRST=0;
_nop_();
_nop_();
_nop_();
_nop_();
return(temp);
}2.5.4AT24C02操作程序设计串行E2PROM芯片的主要功能是存储运行时段的设定值及运行温度的设定值,对其进行的操作主要分为读和写。根据所采用的器件及每次读/写的字节数不同,串行E2PROM器件的操作子函数也较多,这里采用的器件为AT24C02。该器件具有器件地址又具有字节地址,因此这里主要考虑对它的读/写操作。
I2C总线操作函数具体见程序清单。2.5.5TLC549操作程序设计
A/D转换器TLC549的操作指启动下一次的A/D转换,读取前一次的转换结果,其定义如下:
ucharAD_Con(void)
{
uchartemp;
uchari;
_AD_nCS=0;
_nop_();
_nop_();
_nop_();
_nop_();
for(i=0;i<8;i++)
{temp=temp<<1;if(_AD_DATA==1)temp=temp+0x01;_AD_CLK=1;_nop_();_nop_();
_nop_();_AD_CLK=0;_nop_();_nop_();
_nop_();}
_nop_();_nop_();_nop_();_AD_nCS=1;for(i=0;i<20;i++)
{_nop_();}return(temp);}2.5.6整体程序设计方案整体程序的结构框图如图2-23所示,可以看出主程序的基本结构为一个循环程序结构。系统上电后,系统先进行初始化处理,在初始化处理程序中设置各相关接口的逻辑状态,从而初始化LCD模块。循环程序主体为键盘驱动下的分支处理程序,在这些分支处理程序中主键1和主键2的处理程序最为重要。当主键1按下时,系统进入日期和时间设置程序,在该程序里可以通过键盘和LCD显示设置正确的日期和当前时间,该时间作为系统运行的参考时钟。当主键2按下时系统进入运行温度和运行时间段设置程序,在该程序内完成热水器运行时的温度设定和运行时间段设置。运行时间段可以设置四个,有效的运行时间段应该是起始时间小于终止时间,采用24小时/天制。上面两个处理过程涉及到键盘、LCD模块、DS1302和AT24C02的操作,界面相对较复杂,是程序设计的难点。在主循环里按下主键3和主键4,分别对应启动热水器和停止热水器的操作,其实这两个键按下只是用来设置相应的运行标志,具体的运行控制操作并不在此处进行。主键5、6的功能被定义为LCD背光的开启或关闭。在键盘的分支处理程序之后所进行的操作为主界面LCD显示,用来显示当前的日期、星期、时间和热水器的温度。加热器和水泵的运行处理程序是程序设计的重点和难点,加热器和水泵是否运行取决于多种条件,程序设计过程中必须理清这些关系,这样才能设计出功能完善的程序。关于各部分程序模块的设计这里不再赘述,有兴趣的读者可以详细阅读程序清单。图2-23主程序结构框图2.6程序清单
//
//文件名:dgl.h
//功能:在该文件中主要定义了控制器的端口、存储结构及显示的点阵数据等
//作者:hadaqu
//日期:2009-02-10
//
#defineucharunsignedchar
#defineuintunsignedint
#defineLcdDataPortP0
sbit_WR=P2^1;
sbit_RD=P2^0;sbit_RS=P2^2;sbit_RES=P2^3;sbit_CS1=P2^4;sbit_BLA=P2^5;sbit_CS_KEY=P2^6;sbit_FMQ=P2^7;///*24C02端口定义*/sbit_SDA=P1^6; /*模拟I2C数据传送位*/sbit_SCL=P1^5; /*模拟I2C时钟控制位*//*AD端口定义*/sbit_AD_CLK=P3^0;sbit_AD_nCS=P3^1;sbit_AD_DATA=P3^4;/*指示灯定义*/sbit_LED1=P3^5;sbit_LED2=P3^6;sbit_LED3=P3^7;/*加热器与水泵端口定义*/sbit_HEATER=P1^0;sbit_PUMP=P1^1;/*DS1302时钟芯片端口定义*/sbit_SCLK=P1^2;sbit_D_IO=P1^3;sbit_nRST=P1^4;/*水位检测端口定义*/sbit_WATER=P1^7;/*状态标志*/bit_ack;//定义时间存储结构structtime_str{ucharSecond;ucharMinute;ucharHour;ucharDay;ucharDate;ucharMonth;ucharYear;};structtime_strTime_new,Time_old;//DS1302端口地址定义#defineSec_Address0x80 //秒单元地址#defineMin_Address0x82 //分单元地址#defineHour_Address0x84 //时单元地址#defineDate_Address0x86 //日期单元地址#defineMonth_Address0x88 //月份单元地址#defineDay_Address0x8a //星期单元地址#defineYear_Address0x8c //年份单元地址#defineControl_Address0x8e //控制单元地址#defineTrickle_Address0x90 //涓流充电控制单元地址#defineClockb_Address0xbe //时钟单元猝发读控制单元地址#defineRam_Address0xc0 //RAM单元首地址#defineRamb_Address0xfe //RAM单元猝发读控制单元地址/////////////////////////////////////////////////////////////////////////////////////////////////////////24C02存储器空间的分配与使用///////////////////////////////////////////////////////////////////////////////////////////////////////#defineTemp_Address0x00 //设定温度单元地址//运行时间段——参数存储单元#defineSett1_Address0x08//运行时间段——参数存储单元#defineSett2_Address0x10//运行时间段——参数存储单元#defineSett3_Address0x18//运行时间段——参数存储单元#defineSett4_Address0x20//定义开关状态#defineON0#defineOFF1/////////////////////////////////////////////////////////////////////////////////////显示用数码及符号字模,8×16点阵////////////////////////////////////////////////////////////////////////////////////*"0",0*/unsignedcharcodeMSZ0[]={0x00,0x00,0xE0,0x0F,0xF0,0x1F,0x18,0x30,
0x08,0x20,0x18,0x30,0xF0,0x1F,0xE0,0x0F};/*"1",1*/unsignedcharcodeMSZ1[]={0x00,0x00,0x10,0x20,0x10,0x20,0xF8,0x3F,0xF8,0x3F,0x00,0x20,0x00,0x20,0x00,0x00};/*"2",2*/unsignedcharcodeMSZ2[]={0x00,0x00,0x70,0x30,
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 物联网技术在城市管理中的应用方案设计
- 智能家电产品供应及安装协议
- 医疗机构托管与合作经营合同
- 产品研发与技术创新过程管理制度
- 港口码头建设运营合同
- 狐狸的故事解读
- 2025年河南货运资格证考试题
- 提升农产品质量的智能种植管理技术应用推广方案
- 黑猫警长经典情节读后感
- 2025年安庆货运资格证考试有哪些项目
- 2024年01月北京房山沪农商村镇银行2024招考笔试历年参考题库附带答案详解
- 2024年南京市第一医院高层次卫技人才招聘笔试历年参考题库频考点附带答案
- 2024年度宠物用品销售代理合同范本3篇
- 湖南2025年湖南生物机电职业技术学院招聘35人历年参考题库(频考版)含答案解析
- 部队物业服务投标方案
- 2024北京海淀五年级(上)期末英语(教师版)
- 2024年民营医院医生与医院合作协议
- 销售单 代合同范例
- 2024年3月天津第一次高考英语试卷真题答案解析(精校打印)
- 室内设计CAD制图(海南工商职业学院)知到智慧树答案
- 2024-2025学年语文二年级上册 部编版期末测试卷(含答案)
评论
0/150
提交评论