智能温度、电压监测系统

摘  要:文中提出了一个智能温度和电压监测系统的设计方案,该方案用的单片机为CPU来实现的,将采集到的信号输入单片机系统,通过软件的控制,将电压对应于温度的数值通过查表的方式得出结果。功能是实现温度和电压的连续监测,并通过两个数码管分别显示,如超限则报警。它的按键电路实现设置温度及电压的上限值,并将设置的值保存到EEPROM;当采集到的温度或电压超过用户设的上限值时,报警电路发出报警信号;整个电路采用USB供电。并提供了与PC机的串行通信接口,上位机采用VB编程实现了时刻温度检测值的监测记录。

关键词:温度监测,电压监测,A/D转换,EEPROM,报警,串行通信

Abstract: The paper presents an intelligent monitoring system temperature and voltage of the design program, which used to achieve single-chip as CPU, and will be collected from single-chip microcomputer system of the signal input through the software control, the voltage values corresponding to the temperature through the search the results tables. Function of temperature and voltage to achieve the continuous monitoring and control, respectively, through two digital display, such as the alarm is exceeded. It set up the key circuit on temperature and voltage limits, and set the value saved to the EEPROM; collected when temperature or voltage exceeds the upper limit of the user set up, the police issued a warning signal circuit; USB power supply the whole circuit.And provided with the PC-Serial communication interface PC using VB programming time to achieve a detection value of the temperature monitoring records.

Keywords: Temperature monitoring, voltage monitoring, A/D converter, EEPROM, alarm, serial communication


目 录

1 前言... 1

2 整体方案设计... 2

2.1 方案论证... 2

2.2 方案比较... 3

3 单元模块设计... 4

3.1 各单元模块功能介绍及电路设计... 4

3.2元器件的选择... 9

3.3 特殊器件的介绍... 10

3.3.1  DS18B20. 10

3.3.2 ADC0832. 12

3.3.3  24LC02. 14

4 软件设计... 16

4.1软件设计原理及设计工具... 16

4.2软件设计主程序结构图... 17

4.3主要软件设计流程框图... 17

5 系统制作与调试... 24

5.1  系统制作... 24

5.2系统调试... 24

5.2.1 硬件调试... 24

5.2.2 软件调试... 24

6 系统功能... 27

7.结论... 28

8 总结与体会... 29

9 参考文献... 30

附录1:电路总图... 31

附录2:软件代码... 33


1 前言

温度监测系统是比较常见的和典型的过程系统,温度是工业生产过程中重要的被控参数之一,在冶金、机械、食品、化工等各类工业生产过程中广泛使用的各种加热炉、热处理炉、反应炉,对工件的处理温度等均需要对温度严格测量控制。当今计算机控制技术在这方面的应用,已使温度监测系统达到自动化、智能化。

在半导体技术的支持下,温度监测器件发展迅速。而温度传感器是五花八门的各种传感器中最为常用的一种,现代的温度传感器外形非常得小,这样更加让它广泛应用在生产实践的各个领域中,也为我们的生活提供了无数的便利和功能。进入21世纪后,智能温度传感器正朝着高精度、多功能、总线标准化、高可靠性及安全性、开发虚拟传感器和网络传感器、研制单片测温系统等高科技的方向迅速发展。

智能温度、电压监测系统实现温度和电压的连续监测,并通过两个数码管分别显示,如超限则报警。它的按键电路实现设置温度及A/D转换的上限值,并将设置的值保存到EEPROM;当采集到的温度或信号超过用户设的上限值时,报警电路发出报警信号;整个电路采用USB供电。并提供了与PC机的串行通信接口,上位机采用VB编程实现了时刻温度检测值的监测记录。设计系统包括温度检测模块、A/D转换模块、按键模块、数据存储模块、供电电路模块、串口通信模块、报警电路模块、显示电路和单片机最小系统模块九个部分。本设计综合性较强,文中对每个部分功能、实现过程作了详细介绍。整个系统的核心是进行温度测量。本次设计重点对测温硬件、软件的组成进行了分项、模块化逐步分析设计,对各部分的电路进行了一一介绍,最终实现了该系统的硬件电路,并绘制了电路原理总图,完成了硬件调试。根据硬件的设计和测控仪所要实现的功能,本次设计对软件也进行了一一设计,并经过反复的模拟运行、调试,修改简化了软件系统,最后形成了一套完整的程序系统。

2 整体方案设计

本设计的整体思路是:利用流过集成温度传感器电流随温度线性变化的关系,将电流的变化转换为电压的变化,即0℃时输出电压为0V显示在数码管上的数字为000.0。当100℃时输出电压为100mV通过AD转换器输出显示在数码管上的数字为100.0。即温度在0℃~100℃时电压的变化就对应于温度的变化。数码管上输出的数字就是对应于所测量的实际温度。

2.1 方案论证

设计中采用了两个方案,具体的方案见方案一和方案二。

方案一:电桥测温方案

采用铂电阻温度传感器的电阻与温度的关系是非线性的,用电桥实现温度升高引起的电阻变化对应于电压的变化。经A/D转换器后,送入锁存器锁存,在经译码器输出后,再在数码管上显示,由于74LS373具有锁存功能就能实现四位的温度显示。由于铂电阻与温度的关系是非线性的,因此输出的结果不能达到我们所要求的精度。

电桥测温电路

放大电路

A/D转换电路

锁存器74LS373

译码器7448

LED数码显示

图2.1  测温整体方案一框图

方案二:单片机设计方案

整个系统由温度检测电路、A/D转换电路、按键电路、EEPROM存储电路、供电电路、串口RS232、数码管显示电路、报警电路和单片机最小系统组成,整个电路采用USB供电。它可将输入信号进行A/D转换;利用集成温度传感器的电流与温度的变化为线性,将采集到的信号输入单片机系统,通过软件的控制,将电压对应于温度的数值通过查表的方式得出结果,在LED上显示出来,并通过RS232串口传送到计算机;按键电路实现对上限值和显示值的设置,并将设置的值保存到EEPROM;当采集到的温度或信号超过用户所设的上限值时,报警电路发出报警信号。其整体框图如图2.2所示

单片机

计算机

温度检测

按键电路

串口

RS

232

串口调试助手

进行监测值显示

数码管显示电路1

数码管显示电路2

A

/

D

转换

Vin

供电电路

EEPROM

存储电路

报警

电路

图2.2  单片机设计整体方案二框图

2.2 方案比较

由于方案一涉及的电路相对较多,消耗的功率相对较大,而且单片机采集数据更加方便,便于处理,而且单片机已经成为主流产品。单片机在电路上相对比较简单,而且消耗的功率相对较少,调试也较方便,因此设计采用了方案二。

 

3 单元模块设计

智能温度、电压监测系统主要以52单片机为CPU,包含AD转换电路、温度检测电路、键盘电路、数码管显示电路、EEPROM存储器电路、报警电路、RS232串口电路和供电电路组成。本节就各单元模块进行详细的描述。

3.1 各单元模块功能介绍及电路设计

集成温度传感器实际上是一种半导体集成电路,它是利用晶体管的b-e结压降的不饱和值Vbe与热力学温度T和通过。

(1) 温度监测电路

如图3.1所示,温度检测采用基于单总线的DS1820。数据输入输出端口DQ接P3.6,用于温度的采集及数据的输出。

图3.1  温度监测电路原理图

(2)A/D转换电路

A/D转换电路采用芯片ADC0832,如图3.1.2所示。本实验只用到了通道0,将输入的5V电压,通过一个滑动电阻送通道0,作为A/D采集的输入信号。片选使能CS接P1.0, 当ADC0832未工作时其CS输入端应为高电平,此时芯片禁用。数据信号输入DI接P1.2,数据信号输出DO接P1.2,由于DO端与DI端在通信时并未同时有效并与单片机的接口是双向的,所以电路设计时可以将DO和DI并联在一根数据线上使用.时钟脉冲CLK接P1.1。CLK和DO/DI的电平可任意。当要进行A/D转换时,须先将CS使能端置于低电平并且保持低电平直到转换完全结束。此时芯片开始转换工作,同时由处理器向芯片时钟输入端CLK输入时钟脉冲,DO/DI端则DI端输入通道功能选择的数据信号。在使用此芯片时将J13用冒线短接,给芯片提供电源。

图3.2  A/D转换电路原理图

(3)按键电路

按键电路定义了8个键,分别是“右移(S2)” 、“左移(S6)”、“+(S3)”、“-(S7)”、 “设温度上限状态(S8)”、“设电压上限状态(S4)”、“确定(S5)”、“启动/停止(S9)”。P1.1、P1.5、P1.6、P1.7作行线,P3.2、P3.7作列线。原理图如图3.3所示。

行线初始状态全为“1”。先让列线全部为低电平“0”,如果没有键按下,行线全部为高电平“1”状态, 若有任何一个键按下,行线上为非全“1”状态。在有键按下后,通过列线逐个送“0”,然后逐行检查哪根行线为“0”状态,即可查出是哪个按键。

图3.3  按键电路

(4)EEPROM存储电路

EEPROM采用24LC02存储器,修改后的门限报警值可用24LC02来完成。电路中串行时钟SCL接P3.4,串行数据输入输出端SDA接P3.5,地址输入端A0~A2默认接地。在使用此芯片时将J14用冒线短接,给芯片提供电源。电路如图3.4所示。

图3.4  EEPROM存储电路

(5)供电电路

电源采用USB供电,通过按S1键实现电源的通断。电路如下图所示。

图3.5  供电电路

(6)RS232串口电路

图3.6  RS232串口

RS232串口通信通过CPU发送控制信号控制232的发送和接收。可将结果显示到计算机上。定时器1工作在方式2产生波特率,串口通道工作在方式1,本实验只用来发送数据到PC。在发送完8位数据后,由硬件置TI为“1”,向CPU申请发送中断,CPU响应中断后,必须用软件清“0”,所以在中断子程序中要手动将发送中断标志位TI设为“0”。

(7)报警电路

报警电路由一个三极管接一个发光二极管实现。CPU发送一个控制信号控制发光二极管亮。其中发光二极管也可由蜂鸣器代替,报警时 蜂鸣器响。下图是其电路原理图。

图3.7  报警电路

(8)数码管显示电路

数码管显示电路采用共阳极数码管,P0作位选,P2作段选。

图3.8  数码管显示电路

(9)单片机最小系统

CPU选择STC89C52芯片。单片机最小系统里面包括了复位电路、时钟电路。复位电路采用的是按键复位方式,按键S22实现电路的复位;时钟电路使用外部时钟方式实现的,通过使用晶振来实现时间的控制,晶振的振荡频率范围通常是在1.2MHz~12MHz之间,此次芯片使用11.0592M晶振。INT1和INT0接VCC表示这两个端口是做IO口用,不用来做外部中断; P0口接10Kx8上拉排阻。CPU电路如图3.9所示:

图3.9  单片机最小系统

3.2元器件的选择

器件清单:

表3.1  器件清单表

型号

器件

封装

1K

R10 R15 R22

RES3

10K

R21 R24 R25 R19 R20

RES3

10K

W3

W2

5.1K

R23

RES3

100

R8 R7 R3 R2 R1 R5 R4 R6

RES3

4K7

R11 R12 R9 R14 R16 R13 R18 R17

RES3

10uF

C7

RB1

30pF

C19 C20

RAD1

22uF/16V

C15 C11

RB1

47uF/16V

C10

RB1

100uF/16V

C4

RB2

104

C2 C17 C1 C5 C3 C14 C18 C6 C13

RAD1

4.7uF

C16

RB1

1N4007

D1

DIODE3

LED1

D2 D8 D10 D9 D7 D4 D3 D6 D5

LED0.1

9012

T1 T2 T4 T3 T7 T6 T5 T8 Q1

9014

续表3.1

型号

器件

封装

4LED

LED2 LED1

420363

510 X 8

RP1

SIP9

10k X 8

RP2

SIP9

11.0592MHz

CY2

SIP3

1602

J10

SIP16

CON2

J2

POWER4.2

CON2

J14 J13

SIP2

DB9

J1

DB9FLE

CON8

J5

SIP8

DS18b20

J15

SIP3

20PIN

J9

SIP20

23

S1

KEY3

24LC02

IC6

DIP8

89C5X

IC3

DIP40

93C46

IC4

DIP8

ADC0832

IC5

DIP8

DS1302

IC2

DIP8

MAX232

IC1

DIP16

KEY4

S7 S4 S3 S5 S6 S2 S8 S9 S22

KEY0.2'

3.3 特殊器件的介绍

3.3.1  DS18B20

(1)DS18B20简介

DS18B20可以程序设定9~12位的分辨率,测量温度范围为-55℃~125℃,在­-10℃~85℃范围内,精度为±0.5℃。温度读书以16位、符号扩展的二进制补码读数形式提供。表3.1说明输出数据对测量温度的对应关系。数据在单线接口上串行发送。在DS18B20中,温度是以0.5℃LSB(最低有效位)形式表示时,产生以下9位格式:

最高位有效(符号)位被复制到存储器由两字节的温度寄存器中较高MSB的所有位,这种“符号扩展”产生了如表3-2所示的16位温度读数。

DS18B20芯片的引脚如图3.10所示。

图3.10  DS18B20引脚图

表3.2  温度/数据关系表

温度℃

数据输出(二进制)

数据输出(十六进制)

+125

00000000  11111010

00FAh

+25

00000000  00110010

0032h

+0.5

00000000  00000001

0001h

+0

00000000  00000000

0000h

-0.5

11111111  11111111

FFFFh

-25

11111111  11001110

FFCEh

-55

11111111  10010010

FF92Hh

(2)DS18B20工作原理

DS18B20通过一种片上温度测量技术来测量温度,图3.11示出了温度测量电路的方框图。

其工作原理为:用一个高温度系数的振荡器确定一个门周期,内部计数器在这个门周期内对一个低温度系数的振荡器的脉冲进行计数来得温度值。计数器被预置到对应于-55℃的一个值。如果计数器在门周期结束前到达0,则温度寄存器(同样被预置到-55℃)的值增加,表明所测温度大于-55℃。

图3.11 温度测量电路方框图

3.3.2 ADC0832

(1)八位串行A/D转换器ADC0832简介

ADC0832 是美国国家半导体公司生产的一种8 位分辨率、双通道A/D转换芯片。由于它体积小,兼容性强,性价比高而深受单片机爱好者及企业欢迎,其目前已经有很高的普及率。图3.12为ADC0832的引脚图。

图3.12 ADC0832的引脚图

芯片接口说明:

· CS 片选使能,低电平芯片使能。

· CH0 模拟输入通道0,或作为IN+/-使用。

· CH1 模拟输入通道1,或作为IN+/-使用。

· GND 芯片参考零电位(地)。

· DI 数据信号输入,选择通道控制。

· DO 数据信号输出,转换数据输出。

· CLK 芯片时钟输入。

· Vcc/REF 电源输入及参考电压输入(复用)

8位分辨率A/D转换芯片ADC0832,其最高分辨可达256级。其内部电源输入与参考电压的复用,使得芯片的模拟电压输入在0~5V之间,8位分辨率时的电压精度为19.53mV。芯片转换时间仅为32us。通过Dl数据输入端,可以轻易的实现通道功能的选择。

(2)ADC0832工作原理

ADC0832的控制原理:正常情况下ADC0832与单片机的接口应为4条数据库线,分别是CS、CLK、DO、DI。但由于DO端与DI端在通信时并未同时有效并与单片机的接口是双向的,所以电路设计时可以将DO和DI并联在一根数据线上使用。当ADC0832未工作时其CS输入端应为高电平,此时芯片禁用,CLK和DO/DI的电平可任意。当要进行A/D转换时,须先将CS使能端置于低电平并且保持低电平直到转换完全结束。此时芯片开始转换工作,同时由处理器向芯片时钟输入端CLK输入时钟脉冲,DO/DI端则DI端输入通道功能选择的数据信号。在第1个时钟脉冲的下沉之前DI端必须是高电平,表示起始信号。在第2、3个脉冲下沉之前DI端应输入2位数据用于选择通道功能,其功能项见表3.3。

表3.3  通道选择功能表

差分模式

单端模式

通道选择

通道

通道选择

通道

SGL/DIF

ODD/SIGN

0

1

SGL/DIF

ODD/SIGN

0

1

0

0

+

1

0

+

0

1

+

1

1

+

如表所示,当此2位数据为“1”、“0”时,只对CH0进行单通道转换。当2位数据为“1”、“1”时,只对CH1进行单通道转换。当2位数据为“0”、“0”时,将CH0作为正输入端IN+,CH1作为负输入端IN-时行输入。当2位数据为“0”、“1”时,将CH0作为负输入端IN-,CH1作为正输入端IN+时行输入。

到第3个脉冲的下沉之后DI端的输入电平就失去输入作用,此后DO/DI端则开始利用数据输出DO时行转换数据的读取。从第4个脉冲下沉开始由DO端输出转换数据最高位DATA7,随后每一个脉冲下沉DO端输出下一位数据。直到第11个脉冲时发出最低位数据DATA0,一个字节的数据输出完成。也正是从此位开始输出下一个相反字节的数据,即从第11个字节的下沉输出DATD0.随后输出8位数据,互第19个脉冲时数据输出完成,也标志着一次A/D转换的结束。最后将CS置高电平禁用芯片,直接将转换后的数据进行处理就可以了。图3.6为ADC0832的时序图。从图中可看出ADC0832具有双数据输出,可作为数据校验,以减少数据误差。

图3.13 ADC0832时序图

3.3.3  24LC02

(1)24LC02简介

24LC02是基于IIC总线的存储器,具有8脚的芯片,引脚及内部结构如下图。

图3.14  24LC02引脚及内部结构

引脚介绍:

表3.4  24LC02引脚功能

引脚

符号

功能

电压/V

引脚

符号

功能

电压/V

1

A0

地址输入端0

0

5

SDA

串行数据输入/输出端

4.4

2

A1

地址输入端1

0

6

SCL

串行时钟信号输入端

4.4

3

A2

地址输入端2

0

7

WP

写保护信号输入端

0

4

GND

接地端

0

8

VCC

电源端

5

(2)24LC02的工作原理

1

0

1

0

A2

A1

A0

R/W

24LC02传送的设备地址为:

第8位的设备地址是读/写操作选择位。如果这个位为高读操作启动,如果此位低写操作开始。如果设备地址比较成功,电可擦除只读存储器将输出一个零在应答位。如果不是,芯片将返回到待机状态。下图为24LC02总时序图。

图3.15  24LC02总时序

注:写周期时间tWR是指时间从一个写入序列的有效的停止条件开始到顺序命令的有效启动条件结束。

4 软件设计

针对各模块的硬件功能,对各模块设定子程序,通过主程序对这些子程序模块的调用,完成软件设计。

4.1软件设计原理及设计工具

主程序主要实现初始化及对各子程序模块的调用。首先初始化报警标志位,关报警信号。然后初始化EEPROM,将EEPROM全部填充“0”,这个只须执行一次,执行过一次后将其注释,防止每次上电后对EEPROM初始化。通过设定时器1工作在方式2产生9600波特率,并开串口中断,实现串口通讯。在允许定时器计数后,开始进行键盘扫描,判断是否有键按下,如有键按下则执行按键程序。按键程序定义了8个按键,分别是“+”、“-”、“左移”、“右移”、“确定”、“设温度上限状态”、“设电压上限状态”、“启动/停止”。“启动/停止”用来控制是进行AD采集还是温度采集。当在“启动”状态且没有在设置状态时,执行AD转换子程序,进行AD转换,并调报警子程序对采集的数据进行比较,判断是否超出用户设置的上限值,如超过则报警。当在“停止”状态且没有在设置状态时,调温度采集子程序,进行温度采集,并调报警子程序。按下“设温度上限状态”则进入设置状态,用于设温度上限值。按下“设电压上限状态”则进入设置状态,用于设电压上限值。其中“+”、“-”、“左移”、“右移”只在设置状态有效,用来设置温度或电压的值,并通过数码管显示出当前设置值。在设置完上限值后按“确定”键,实现将设定的上限值保存到EEPROM,并退出设定状态。此次我们用的设计软件是keil uVision2。

4.2软件设计主程序结构图

初始化报警标志及P1口

初始化EEPROM

设定时器1工作在方式2用于产生波特率

允许串口中断并设定时器初值产生9600波特率

允许定时器开始定数并开中断总允许

执行键盘扫描子程序

执行AD采集程序

执行报警程序

执行温度采集程序

执行报警程序

图4.1  主程序结构图

4.3主要软件设计流程框图

(1)温度采集子程序设计

温度采集子程序在主程序中的调用流程:

温度采集子程序

端口定义

开始

图4.2  温度采集子程序调用

通过单线总线端口访问DS1820的协议如下:

·初始化:        由复位脉冲组成;

·ROM操作命令: CCH表示允许总线控制器不用提供64位ROM编码就使用存储器操作命令,即跳过ROM;

·存储器操作命令:BEH表示读取暂存器的内容;

·执行/数据:      44H表示开始温度转换。

温度转化后得到的数据,存储在18B20的两个8比特的RAM中,二进制中的前面1位是符号位,如果测得的温度大于0,这位为0,只要将测到的数值乘于0.0625即可得到实际温度;如果温度小于0,这位为1,测到的数值需要取反加1再乘于0.0625即可得到实际 温度。例如+125℃的数字输出为07D0H,+25.0625℃的数字输出为0191H,-25.0625℃的数字输出为FF6FH,-55℃的数字输出为FC90H 。本实验没有考虑温度小于0的情况,为了方便后面程序的编写,这里乘的是0.625,处理时只要在显示程序中加入小数点即可。

调写字节子程序

读取暂存器内容

调读字节子程序

将温度低字节读出

调读字节子程序

将温度高字节读出

计算温度值并取整

aaa=(tem2*256+tem1)*0.625

取温度值各位

调复位子程序

调写字节子程序

执行温度转换

延时

显示温度值

调写字节子程序

执行跳过ROM

调复位子程序

调写字节子程序

执行跳过ROM

图4.3  温度采集子程序流程图

以下为温度采集子程序中包含的程序进行说明。

复位子程序:

St=1

DQ=1

St==1?

返回

Y

N

N

Y

DQ从0到1

DQ==1?

延时

St=0复位成功

St=1

图4.4  复位子程序流程图

写一个字节: 数据线从高电平到低电平产生写起始信号,15ms之内将所需写的位送到数据线。下图为写字节子程序流程图:

DQ=1

i=8

i>0

Y

返回

N

该位数是否为1

DQ=0

取一位数

数据右移一位

i--

DQ=1

延时

DQ=1

图4.5  写字节子程序流程图

读一个字节:数据线先从高拉到低电平1us以上,再使数据线升为高电平,从而产生读信号。下图为读字节子程序流程图。

i=8

i>0

DQ==1?

DQ=1并延时

DQ=0并延时

DQ=1并延时

数据右移一位

延时并i--

该位数据为1

返回读出的数据

图4.6  读字节子程序流程图

(2)AD转换子程序设计

AD转换子程序在主程序中的调用流程:

调写AD转换子程序

采通道0的电压值

电压值转换

temp=getdata*1.0/256*500

取电压值的各位

并将P0口作位选

P2口作段选

显示转换的电压值

开始

端口定义

图4.7  AD转换子程序调用

由于AD转换最大量程为5V,AD精度为8位则转换器的输出数据可以用28个二进制数进行量化,所以可以利用以下公式算出实际输入电压。

在程序中乘上500表示输出三位整数,乘上5000表示输出四位整数,方便下面显示程序的编写。图4.8是AD转换子程序的流程图。

判断输入通道

起始信号ADD=1

ADCS=0芯片使能

在ADCLK第二和第三个

下降沿输入通道数

ADDI=1控制命令结束

在ADCLK第12~19个下降

沿输出第二个字节转换

数据(第一位为最低位)

AD转换结束,ADCS=1

ADCLK=0

ADD0=1回到初始状态

返回AD转换的2个字节

图4.8  AD转换子程序流程图

(3)按键程序设计

键盘处理程序的任务是:确定有无键按下,判断哪一个键按下,键的功能是什么;还要削除按键在闭合或断开时的抖动。两个并行口中,一个输出扫描码,使按键逐行动态接地,另一个并行口输入按键状态,由行扫描值和回馈信号共同形成键编码而识别按键,通过软件查表,查出该键的功能。

每个按键有它的行值和列值,行值和列值的组合就是识别这个按键的编码。矩阵的行线和列线分别通过两并行接口和CPU通信。每个按键的状态同样需变成数字量“0”和“1”,开关的一端(列线)通过电阻接VCC,而接地是通过程序输出数字“0”实现的。

本实验选用P1.1、 P1.5、 P1.6、 P1.7作行线,P3.2 、P3.7作列线。行线初始状态全为“1”。先让列线全部为低电平“0”,如果没有键按下,行线全部为高电平“1”状态, 若有任何一个键按下,行线上为非全“1”状态。在有键按下后,通过列线逐个送“0”,然后逐行检查哪根行线为“0”状态,即可查出是哪个按键。

图4.9为按键程序设计流程图。

按键的行值设为

1,列值设为0

是否有键按下

延时去抖动

确认是否按下

进行列扫描

第一列为0

该列是否有

键按下

Y

第二列为0

判断键值并执

行相应功能

Y

N

该列是否有

键按下

判断键值并执

行相应功能

判断键是否松开,直

到松开按键才返回

Y

N

N

N

Y

图4.9 按键程序设计流程图

(4)EEPROM电路子程序设计

存储器24C02端口定义:器件地址以及读取操作OP_READ=0xa1,器件地址以及写入操作OP_WRITE= 0xa0,时钟SCL接P3.4,数据线SDA接P3.5。开始传送数据的条件是SCL=1,SDA由高到低。停止传送数据的条件是SCL=1,SDA由低到高。串行传送数据,先传最高位。下图是写数据子程序在主程序中的调用流程。

开始

端口定义

SDA=1

SCL=1

调写字节子程序写

显示代码到AT2402

图4.10  EEPROM电路子程序调用

写数据到2402时,SCL下降沿时将数据写入2402,写完后SDA=1读取应答,SCL下降沿时将应答值保存并返回应答位。流程图如下所示。

开始传送数据

SCL=1

SDA产生下降沿

SCL=0

写数据到2402

将写入操作命令送2402

写数据到2402

将数据写入2402

即在指定地址写入数据

停止传送数据

SCL=1

SDA产生上升沿

写数据到2402

将指定地址送2402

延时10ms

图4.11  写位子程序流程

(5)串口通讯子程序设计

串口通道工作在方式1,本实验只用来发送数据到PC,在发送完8位数据后,由硬件置TI为“1”,向CPU申请发送中断,CPU响应中断后,必须用软件清“0”,所以在中断子程序中要手动将发送中断标志位TI设为“0”。以下为串口通讯子程序执行流程。

在主程序中设定

时器1工作在方式1

产生9600波特率

开串口中断

在需串口通讯的

子程序中写SBUF

TI==1?

TI=0

返回

图4.12  串口通讯子程序执行流程

(6)报警子程序设计

读EEPROM内容,对当前显示的电压或温度值进行判断,判断是否大于用户设定的上限值,如大于则发出报警信号。流程图如下:

发光二极管不发光

若最高位相等,次高位

是否大于设定值次高位

调用2402子程序

将存储内容读出

温度或电压最高位是

否大于设定值最高位

若次高位相等,最低位

是否大于设定值最低位

发光二极管发光

图4.13  报警子程序流程图

5 系统制作与调试

5.1  系统制作

首先我们需要先明确我们的设计要实现的功能,在此基础上在设计原理图,先设计单片机的最小系统,并将最小系统调试正确再加上我们所要用到的可以实现我们功能的芯片及相关电路。在整体电路完全设计出来后我们接下来的工作就是要用protel99se软件工具将我们的图画下来,并设置好参数,在检查图正确无误的情况下就可以将其转换成PCB板的图,在这里需要注意的是电路图的个个器件的封装要和PCB板里面对应器件的封装完全一致才能正确的转换成PCB板。画PCB板是一个工作量相当大的工程,并且一定要仔细,否则很容易画错。在PCB画好后就可以用来制作我们的电路板了。电路板做出来后就是焊接的工作。接下来我们做的工作就是软件的设计。根据我们设计的功能实现来编辑程序,用keil C来设计程序。

5.2系统调试

5.2.1 硬件调试

在电路板焊接工作完成后,我们对其进行检验,发现电路工作不是很稳定,在一番检查后发现板子在焊接的时候由于不小心出现了几个虚焊导致我们的系统工作不稳定,解决的办法就是将虚焊的地方重新焊接一遍,以保证它能正常工作。

图5.1   完成后的硬件图

5.2.2 软件调试

我们最开始编写的程序是用一个数码管显示数据,另一个数码管显示单位,而我们是需要的两个数码管同时分别显示温度和压力值,所以我们需要把四位显示数据改为三位,这样我们就需要改温度采集程序里面的内容,将aaa=(tem2*256+tem1)*6.25改为aaa=(tem2*256+tem1)*0.625;并将AD转换里面的temp=getdata*1.0/256*5000;改为temp=getdata*1.0/256*500;这样就实现了四位变三位的要求。其次我们需要正确的将三位显示出来还要改变数码管显示函数,我们第一个数码管显示的是压力, dispbuf[3]、dispbuf[2] 、 dispbuf[1]    ,所以显示压力的数码管显示扫描范围为k=3;k>=1,第二个数码管显示的是温度值,定义的百位、十位、个位分别为  a[4]、a[5]、a[6] ,所以显示温度的扫描范围为k=6;k>=4。现在数据显示基本上是正确的了,最后还得显示单位,P2=0xc6    P0=0x7f;显示的是温度的单位,P2=0xc1;       P0=0xf7;显示的是压力的单位。要使温度电压同时显示车来还需要修改主程序,将原来主程序里面的if……else的结构去掉,直接在里面调用子程序就可以了。在这些都修改完成后就有下图的显示出来了。

图5.2  两个数码管同时显示的压力值和温度值

还进行了上限值的设定的修改,也是分两个数码管分别显示,但不是同时显示的。设定上限值的示意图如下。

图5.3  温度上限值的设定

图5.4  电压上限值的设定

在原来的程序里面没有掉电保护的功能,我们这次要实现的功能还有要掉电保护的工能,只需在主程序中去掉fill_byte(0)这个子程序就可以了。

对于在调试串口的时候,只需要调整一下程序里面的一些延时和VB程序里面的显示位的调整就可以了。下图是串口显示调试成功后的显示。

图5.5   串口显示

6 系统功能

将主程序下载到单片机后并进行USB供电,可在数码管1上显示电压值、数码管2上显示温度值,同时实现连续检测功能;8个按键分别是“右移(S2)” 、“左移(S6)”、“+(S3)”、“-(S7)”、 “设温度上限状态(S8)”、“设电压上限状态(S4)”、“确定(S5)”、“启动/停止(S9)”。可以设定电压、温度的上限值,并能掉电保存设定值,超过上限则发光二级管亮报警;可通过RS232串口通信接口将所监测的温度、电压值传到计算机中,由自编VB程序进行同步显示。

7.结论

本设计的价值也是显而易见的,它能随时监测我们的温度值和电压值,并且能有报警功能,在紧要关头能够及时提供给我们信息,让我们知道危险的来临,及时做好防护准备。

设计主要就是要完成的功能是将主程序下载到单片机后并进行USB供电,可在数码管1上显示电压值、数码管2上显示温度值,同时实现连续检测功能;8个按键可以设定电压、温度的上限值,并能掉电保存设定值,超过上限则发光二级管亮报警;可通过RS232串口通信接口将所监测的温度、电压值传到计算机中,由自编VB程序进行同步显示。我们这次设计与老师给我们示范的程序是有一定改进的,之前我们写得那个程序只能用一个数码管显示数据,并且温度和电压不能同时显示。我们现在最终设计的结果是让两个数码管同时显示温度和电压的值,并且同时设置他们的上限值。在串口显示的时候也能同时将温度和电压的值送到计算机上显示。在本次设计中我们进行了上限值的设定与保存,完成的效果还是基本上达到了我们预期的效果。在此次设计中唯一让我们遗憾的是没能实现左右移时的闪烁功能,这是我们这次设计存在的主要问题也是我们以后需要改进的地方。

8 总结与体会

单片机开发过程是一个非常严谨,复杂,科学,周密和细致,及技术性和综合性都相当高的过程,它要求你必须具备相当扎实的专业基础和理论知识,较强的实践专业操作技能。能以细致和科学的头脑去考察、分析和解决问题。同时在设计中必须要有足够的耐心,持之以恒的毅力,坚强的意志以及实是求是,一丝不苟的精神,才能开发出理想的产品出来。

本次设计,从拿到题目到设计完成,期间经过了充分的积累资料、认真的研究课题要求以及老师的精心指导,在此,首先向指导老师表示衷心的感谢!

本设计中,是以温度采集及AD转换为总目标,以80C52单片机最小应用系统为总控制中心,辅助设计有温度采样电路、A/D转换单元、LED数码管显示电路等。在设计过程中,遇到了许多问题,如设计初重点不明确,思绪混乱,经过认真思考和老师的指导,才使自己思路明确,抓住重点,不懂就问,在很短的时间内系统有序的完成。了解到温度控制的重要性,使自己在设计过程中,更加有兴趣和动力,在软件设计方面,遇到了一些实际问题,由于我们以前没有学过C语言,所以这次我们软件设计的最大困难就是对语言的不熟悉,我们这次设计的另一个隐藏任务就是得熟悉C语言,不说要完全搞懂,但至少会改动程序,知道程序的结构及实现功能的方式,不过,在同学的帮助和自己的努力下都能一一解决,使自己学到了许多新的知识和经验。

老师的指导和在自己到图书馆、网上收集的资料给了我们很大的帮助,我们的思维也从刚开始拿到这个题目时候的茫然逐步的走向了清晰。设计的整个过程包括画图、电路板焊接、软件调试,每一个环节都亲历亲为让我这次学到的东西非常多而且非常实在,对我们以后找工作也起到了一定的帮助。这次课程设计是我们目前为止做得最大的设计,也是用时最多,用心最多的设计,通过这次设计我学到了很多,把以前学到的东西得到了系统化。这次设计的成功完成最需要感谢的就是我们的指导老师,同学也是我们感谢的重点,在实验室里有很多自己不懂的地方同学们都会很耐心的给我们讲解。

总的来说,这次设计对于我们学生来说是很实在的东西。学校应该多开展这样的设计,多给学生提供这样锻炼的机会,学生大多数是有点懒惰性的,需要老师的督促和指导。在这样有任务的情况下,学生们就会很主动的去学习,去找自己需要的,就会有很明确的目标。

9 参考文献

[1] 万福君、潘松峰.单片微机原理系统设计与应用(第二版)[M]. 合肥:中国科学技术大学出版社,2001.

[2] 胡汉才.单片机原理及其接口技术[M]. 北京:清华大学出版社,2004.

[3] 蔡美琴、张为民.MCS-51 系列单片机系统及其应用(第二版)[M]. 北京:高等教育出版社,2004.

[4] 杨振江、杜铁军.流行单片机实用子程序及应用实例[M].西安电子科技大学出版社,2002.

[5] 张培仁.基于 C 语言编程 MCS-51 单片机原理与应用[M]. 北京:清华大学出版社,2003.

[6] 李群林.基于多路传感器的温湿度检测系统[J]. 中国仪器仪表,2006(11),38—40

[7] 孙环.基于SHT11单片集成传感器温湿度检测模块设计[J]. 国外电子测量技术,2006(6),43—48

[8] 沙占友.集成化智能传感器原理与应用[M].北京:电子工业出版社,2004:119-127.

[9] 孟臣、李敏、李爱传. I2C总线数字式温湿度传感器SHT11及其在单片机系统的应用[J].国外电子元器件,2004(3):50-54

[10] 刘迎春、叶湘滨.现代新型传感器原理与应用[M]. 北京:国防工业出版社,1998.

[11] 何希才.传感器及其应用电路[M]. 北京:电子工业出版社,2001.

[12] 沙占友.智能化集成温度传感器原理与应用[M]. 北京:机械工业出版社,2002.

[13] 赵继文.传感器与应用电路设计[M]. 北京:科学出版社,2002.

[14] 丁镇生.传感器及传感技术应用[M]. 北京:电子工业出版社,1998.

[15] 张洪润、刘秀英、张亚凡等.单片机应用设计200例[M].北京:航空航天大学出版社,2006.

[16] Nordic VLSI ASA. nRF24E1 and nRF24E2 RF layouts[P]. Application Note, ordercode: 200503-nAN24-0.2003.

附录1:电路总图

图1  原理图

图2  PCB图

附录2:软件代码

(一)   主程序

#include<reg52.h>

#include <intrins.h>

#define  uchar  unsigned  char

#define  uint   unsigned  int

#define  nop()   _nop_()

//ADC0832的引脚

sbit ADCS =P1^3;   //ADC0832 chip seclect

sbit ADDI =P1^4;    //ADC0832 k in

sbit ADDO =P1^4;   //ADC0832 k out

sbit ADCLK =P1^0;  //ADC0832 clock signal

unsigned char dispbitcode[8]={0xf7,0xfb,0xfd,0xfe,0xef,0xdf,0xbf,0x7f};           //位扫描

unsigned char dispcode[11]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xff};  //共阳数码管字段码

unsigned char dispbuf[8];

uint  temp;

uchar getdata;      //获取ADC转换回来的值

unsigned int Adc0832(unsigned char channel);

void display(void) ;

void ad_tem();//ds18B20

sbit     DQ=P3^6;

/*uchar code table[]={

0xc0,0xf9,0xa4,0xb0,

0x99,0x92,0x82,0xf8,

0x80,0x90,0x88,0x83,

0xc6,0xa1,0x84,0x8e,0xaa};

uchar  table1[]={

0x40,0x79,0x24,0x30,

0x19,0x12,0x02,0x78,

0x00,0x10,0x08,0x03,

0x46,0x21,0x04,0x0e,0x2a};//带小数点的段码  */

uint temper;

uchar a[6];//1,a2,a3,a4;

void delay(uint x);

void TempDelay(uchar us);

void write_byte(uchar date);

void disp();//uchar num1,uchar num2,uchar num3,uchar num4);

uchar read_byte();

void get_tem();//24C02

#define OP_READ 0xa1 //器件地址以及读取操作

#define OP_WRITE 0xa0 //器件地址及写入操作

#define MAX_ADDR 0x7f    // AT24C02最大地址

sbit SCL = P3^4; //T1

sbit SDA = P3^5; //T0

void start();

void stop();

unsigned char shin();

bit shout(unsigned char write_data);

unsigned char read_random(unsigned char random_addr);

void writeiic_byte( unsigned char addr, unsigned char write_data);

void fill_byte(unsigned char fill_data);

void delayms(unsigned char ms);

void  iic_tem(uint k);//键盘

void displys(void);

uint num[]={0,0,0,0,0,0,0,0};

uint max_c=0;   //温度最大值标识符

uint max_v=0;         //电压最大值标识符

uint start_stop=1;   //开始停止标识符

uint sure=0;    //确定标识符

uint s=0;

void Getch(void) ;  //报警

void arm(void);

uint arm_flat[8]={0,0,0,0,0,0,0,0,};

sbit speaker = P3^3; //T0//串口通信

void main()

{     SDA = 1;

SCL = 1;

/*fill_byte(0);        初始化EEPROM全部填充  ,此子程序只执行一次,下一次就必须将其注释,防止每次上电都被初始化。*/ 

speaker=1;//报警标志

TMOD=0x20;                    /*键盘中断扫描及串口通信定时器T1,在方式中断产生波特率*/

ES=1;        //允许串口中断

PCON &= 0x00;                /* 波特率不倍增PCON=0x00;   SMOD=0*/

SCON=0x40;

TH1=0xfd;    //波特率设置为

TL1=0xfd;

TR1=1;       //开定时器T1运行控制位*/

EA=1;            //开中断

P1=0x0;

while(1)

{   Getch();

if(//start_stop==1 &&

max_c==0&& max_v==0)

{     ad_tem();arm();//     //AD子程序

// }

// else if(start_stop==0 && max_c==0&& max_v==0)

//{  get_tem();  arm(); ///温度采集子程序

}

else

displys();

}

}

void serial() interrupt 4

{     if(TI) TI=0;

}

void arm()

{     uint i;

for(i=0;i<8;i++)

{  arm_flat[i]=read_random(i);

}

if(a[4]<arm_flat[6] || dispbuf[3]>arm_flat[3])

{     speaker=0;

}

else if((a[4]==arm_flat[6]&&a[5]<arm_flat[5]) ||(dispbuf[3]==arm_flat[3]&& dispbuf[2]>arm_flat[2]))

{              speaker=0;

}

else  if((a[4]==arm_flat[6]&&a[5]==arm_flat[5]&&a[6]<arm_flat[4]) ||(dispbuf[3]==arm_flat[3]&& dispbuf[2]==arm_flat[2]&& dispbuf[1]>arm_flat[1]))

{              speaker=0;

}

else

speaker=1;

}

void Getch()

{     unsigned char x,y;

P1=P1|0xE2;   //P1.1 P1.5 P1.6 P1.7作行扫描

y=P1&0xe2;

P3=0x7b;//P3.2  P3.7作列扫描

if(y!=0Xe2)  { //判断是否有键按下//

delayms(15);    //软件延时//

if(y!=0Xe2) //确认是否按下//

{      P3 = 0XFB;

x=P1&0xe2;

if(x!=0xe2){

switch(x)  //判断键值//

{  case 0xe0:if(s>0) --s;break;// if(num[s]==9){num[s]=0;break;} num[s]=num[s]+1; break;   //对按键附值//

case 0xc2: if(num[s]==9){num[s]=0;break;} num[s]=num[s]+1; break;// if(num[s]==0){       num[s]=9;break;}num[s]=num[s]-1;break;

case 0xa2:max_v=0;max_c=1;num[3]=arm_flat[3];num[2]=arm_flat[2];num[1]=arm_flat[1];num[0]=arm_flat[0];  break; //if(s<7) ++s;break;

case 0x62: sure=1;

if(max_c==1)

{    max_c=0; iic_tem(1);}

else if(max_v==1)

{    iic_tem(2); max_v=0;}

break;   //对按键附值//  //if(s>0) --s;break;

}}

else{

P3 = 0X7F;

x=P1&0xe2;

if(x!=0xe2){

switch(x) {  //判断键值//

case 0xe0:if(s<7) ++s;break;/* sure=1;

if(max_c==1)

{max_c=0; iic_tem(1);}

else if(max_v==1)

{iic_tem(2); max_v=0;}

break;   //对按键附值// */

case 0xc2:if(num[s]==0){       num[s]=9;break;}num[s]=num[s]-1;break;   //max_c=1;max_v=0; num[3]=arm_flat[3];num[2]=arm_flat[2];num[1]=arm_flat[1];num[0]=arm_flat[0];break;

case 0xa2:max_c=0;max_v=1; num[3]=arm_flat[4];num[2]=arm_flat[5];num[1]=arm_flat[6];num[0]=arm_flat[7]; break;// max_v=1;max_c=0; num[3]=arm_flat[7];num[2]=arm_flat[6];num[1]=arm_flat[5];num[0]=arm_flat[4]; break;

case 0x62: start_stop=!start_stop;break;

} }}} }

while((P1&0xe2)!=0xe2);}

void displys()

{    if(max_v==0)

{     char k;

for(k=1;k<=3;k++){

P0 = dispbitcode[k];

P2 = dispcode[num[k]];

delay(2);

if(k==3)   //加上数码管的dp小数点

P2&=0x7f;

delay(2);

P0=0xff;          //消影

}

P2=0xc1;//    显示字符"U"

P0=0xf7;

delay(2);

}

if(max_c==0)

{     char k;

for(k=4;k<=6;k++){

P0 = dispbitcode[k];

P2 = dispcode[num[k]];

delay(2);

if(k==5)   //加上数码管的dp小数点

P2&=0x7f;

delay(2);

P0=0xff;          //消影

}

P2=0xc6;//      显示字符"C"

P0=0x7f;

delay(2);

}  }

void reset()

{     uchar st=1;

DQ=1;

nop();

nop();

while(st)

{     DQ=0;

TempDelay(112);//750

DQ=1;

TempDelay(8);//70

if(DQ==1)

st=1;

else

st=0;

TempDelay(74);//500

}

}

void write_byte(uchar date)

{     uchar i,temp;

DQ=1;

nop();nop();

for(i=8;i>0;i--){

temp=date&0x01;//01010101

DQ=0;

TempDelay(1);//20

if(temp==1)

DQ=1;

TempDelay(5);//45

DQ=1;

ate=date>>1;//00101010

}}

uchar read_byte(){

uchar i,date;

static bit j;

for(i=8;i>0;i--){

date=date>>1;

DQ=1;

nop();nop();

DQ=0;

nop();nop();nop();nop();nop();nop();

DQ=1;

nop();nop();nop();nop();

j=DQ;

if(j==1)

date=date|0x80;//1000 0000

TempDelay(2);//30

}

return (date);

}

void get_tem()

{     uchar tem1,tem2,num;

float aaa;

reset();  //复位

write_byte(0xCC);//跳过ROM

write_byte(0x44);//温度转换

for(num=100;num>0;num--);

disp();//a1,a2,a3,a4);

reset();

write_byte(0xCC);

write_byte(0xBE);

tem1=read_byte();

tem2=read_byte();

aaa=(tem2*256+tem1)*0.625;

temper=(int)aaa;

a[4]=temper%1000/100;                //百位

a[5]=temper%100/10;            //十位

a[6]=temper%10;                   //个位

}

void TempDelay(uchar us)

{     while(us--);

}

void delay(uint x)

{     uint a,b;

for(a=x;a>0;a--)

for(b=011;b>0;b--);

}

void disp()//uchar num1,uchar num2,uchar num3,uchar num4)

{     char h;

SBUF=1;

delay(2);  //用于上传到PC作标志位  

for(h=6;h>=4;h--)

{     P0 = dispbitcode[h];

P2 = dispcode[a[h]];

delay(5);

SBUF=a[h];

delay(5);

if(h==5)     //加上数码管的dp小数点

P2&=0x7f;

delay(5);

P0=0xff;          //消影

}

P2=0xc6;//      显示字符"C"

P0=0x7f;

delay(2);

P0=0xff;

}

void ad_tem(void)

{        getdata=Adc0832(0);

temp=getdata*1.0/256*500;  //电压值转换,V做为参考电压,分成份,

//乖以显示三位数,若乖以则显示四位数,并且要在dispbuf[]中增加千位

dispbuf[3]=temp%1000/100;    //百位

dispbuf[2]=temp%100/10;     //十位

dispbuf[1]=temp%10;           //个位

display();

}

void display(void)        //数码管显示函数

{  char k;

SBUF=0;    //用于上传到PC作标志位  

delay(4);

for(k=3;k>=1;k--){

P0 = dispbitcode[k];

P2 = dispcode[dispbuf[k]];

delay(4);

SBUF=dispbuf[k];

delay(4);

if(k==3)      //加上数码管的dp小数点

P2&=0x7f;

delay(4);

P0=0xff;          //消影

}

P2=0xc1;//      显示字符"U"

P0=0xf7;

delay(4);

P0=0xff;

}

unsigned int Adc0832(unsigned char channel)     //AD转换,返回结果               

{     uchar i=0;

uchar j;

uchar dat=0;

uchar ndat=0; //1初始化操作 

if(channel==0) //通道选择,选择通道的单端模式 

channel=2;

if(channel==1)       //选择通道的单端模式 

channel=3;//2 写操作,将通道数写入ADC0832

ADDI=1;    //启始信号

_nop_();

_nop_();

ADCS=0;     //拉低CS端,能使DAC0832

_nop_();

_nop_();

ADCLK=1;    //拉高CLK端,DI端的数据移入DAC0832内部的多路移位寄存器

_nop_();

_nop_();

ADCLK=0; //拉低CLK端,形成下降沿,第一个时钟周期开始

_nop_();

_nop_();

ADCLK=1;    //拉高CLK端,在第一个时钟//周期内,DI为高,表示启动位,

//紧接着输入两位配置位即进行通道选择 

ADDI=channel&0x1;    //channel=2,ADDI=0 输入通道数低位

_nop_();

_nop_();

ADCLK=0;  //拉低CLK端,形成下降沿,第二个时钟周期开始

_nop_();

_nop_();

ADCLK=1;    //拉高CLK端

ADDI=(channel>>1)&0x1;  //ADDI=1                      //输入通道数高位

_nop_();

_nop_();

ADCLK=0;    //拉低CLK端,形成下降沿

ADDI=1;     //控制命令结束

_nop_();

_nop_();

dat=0;//3读操作,将AD转换的数从DO口输出 

for(i=0;i<8;i++)

{     dat|=ADDO;  //收数据."|"位或,如果两位中有一个为,则结果为,否则为

ADCLK=1;

_nop_();

_nop_();

ADCLK=0;      //形成一次时钟脉冲

_nop_();

_nop_();

dat<<=1;

if(i==7)

dat|=ADDO;

}

for(i=0;i<8;i++)       //CLK每来一个下降沿输出一位数,先输出低位

{     j=0;

j=j|ADDO;     //收数据

ADCLK=1;

_nop_();

_nop_();

ADCLK=0;      //形成一次时钟脉冲

_nop_();

_nop_();

j=j<<7;

ndat=ndat|j;

if(i<7)

ndat>>=1;

} //4 结束AD转换 ,并返回转换的数

ADCS=1;          //拉低CS端

ADCLK=0;         //拉低CLK端

ADDO=1;      //拉高数据端,回到初始状态

if(dat==ndat)

{     return(dat);  }  //return ad k

}

void  iic_tem(uint k)

{    unsigned char i;

for(i = 0 ; i < 4; i++)//写入显示代码到AT24Cxx

{  if(k==1)

writeiic_byte(i, num[i]);//存放温度值

else

writeiic_byte(i+4, num[i]);//存放电压值

}

}

void start()// 开始位

{     SDA = 1;

SCL = 1;

_nop_();

_nop_();

SDA = 0;

_nop_();

_nop_();

_nop_();

_nop_();

SCL = 0;

}

void stop()// 停止位

{     SDA = 0;

_nop_();

_nop_();

SCL = 1;

_nop_();

_nop_();

_nop_();

_nop_();

SDA = 1;

}

unsigned char shin()

// 从AT24Cxx移入数据到MCU

{     unsigned char i,read_data;

for(i = 0; i < 8; i++)

{     SCL = 1;

read_data <<= 1;

read_data |= (unsigned char)SDA;

SCL = 0;

}

return(read_data);

}

bit shout(unsigned char write_data)

// 从MCU移出数据到AT24Cxx

{     unsigned char i;

bit ack_bit;

for(i = 0; i < 8; i++)             // 循环移入个位

{     SDA = (bit)(write_data & 0x80);

_nop_();

SCL = 1;

_nop_();

_nop_();

SCL = 0;

write_data <<= 1;

}

SDA = 1;               // 读取应答

_nop_();

_nop_();

SCL = 1;

_nop_();

_nop_();

_nop_();

_nop_();

ack_bit = SDA;

SCL = 0;

return ack_bit;              // 返回AT24Cxx应答位

}

void fill_byte(unsigned char fill_data)

// 填充数据fill_data到EEPROM内

{     unsigned char i;

for(i = 0; i < MAX_ADDR; i++)

{     writeiic_byte(i, fill_data);

}

}

void writeiic_byte(unsigned char addr, unsigned char write_data) // 在指定地址addr处写入数据write_data

{     start();

shout(OP_WRITE);

shout(addr);

shout(write_data);

stop();

delayms(10);          // 写入周期

}

unsigned char read_current() // 在当前地址读取

{     unsigned char read_data;

start();

shout(OP_READ);

read_data = shin();

stop();

return read_data;

}

unsigned char read_random(unsigned char random_addr)   // 在指定地址读取

{     start();

shout(OP_WRITE);

shout(random_addr);

return(read_current());

}

void delayms(unsigned char ms)   // 延时子程序

{     unsigned char i;

while(ms--)

{     for(i = 0; i < 120; i++);

}

}

(二)   VB程序

Private Sub Command1_Click()

Select Case Combo1.Text

Case "COM1"

aRs232.port = 1

Case "COM2"

aRs232.port = 2

Case "COM3"

aRs232.port = 3

End Select

MSComm1.CommPort = aRs232.port '设置串口1

MSComm1.Settings = "9600,n,8,1" '波特率9600bit/s,无效验,8位数据,1位停止位

MSComm1.InputLen = 0 '读取接收缓冲区的所有字符

MSComm1.InBufferSize = 1024 '设置接收缓冲区为1024字节

MSComm1.OutBufferSize = 1024 '设置发送缓冲区为512字节

MSComm1.PortOpen = True '打开串口

If MSComm1.PortOpen = True Then

Shape1.FillColor = &HFF00&

End If

MSComm1.SThreshold = 0 '不触发事件

MSComm1.RThreshold = 8 '每4个字节到接收缓冲区都触发接收事件

MSComm1.InBufferCount = 0 '清除发送区的数据

MSComm1.OutBufferCount = 0 '清除接收区的缓冲区数据

MSComm1.InputMode = comInputModeBinary '设置接收的为二进制数据流

End Sub

Private Sub Form_Activate()

Command1.SetFocus

End Sub

Private Sub MSComm1_OnComm()

Select Case MSComm1.CommEvent '检验串口事件

'错误处理

Case comEvReceive  '接收缓冲区有数据

Dim rec() As Byte

rec = MSComm1.Input  '从接收队列中读入字符串

If rec(0) = 0 Then

Text1.Text = Str(rec(3)) & "." & Str(rec(1)) & Str(rec(2))

Label6.Caption = "V"

Label7.Caption = "当前电压值:"

'读出字符串送显压力值

Else

Text2.Text = Str(rec(2)) & Str(rec(1)) & "." & Str(rec(3))

Label9.Caption = "℃"

Label8.Caption = "当前温度值:"

'读出字符串送显压力值

End If

End Select

End Sub

智能温度、电压监测系统相关推荐

  1. 基于物联网的智能厨房安全监测系统-下位机程序

    CSDN话题挑战赛第2期 参赛话题:学习笔记 最近遇到一个基于TCP/IP网络的远程智能物联网系统,采用Arduino Uno控制器作为下位机,采用LabVIEW作为远程监控软件,两者通过网络实现通信 ...

  2. 用c语言编声光报警子程序,C语言编程的智能火灾报警监测系统

    用C语言来编写程序的火灾报警系统 智能火灾报警监测系统 [摘 要]本系统由检测装置烟雾传感器SS-168.光电传感器ST-178和温度传感器DS18B20,显示装置LCD和声光报警装置组成,并由单片机 ...

  3. 故障报警系统C语言编程,C语言编程的智能火灾报警监测系统.doc

    智能火灾报警监测系统 [摘 要]本系统由检测装置烟雾传感器SS-168.光电传感器ST-178和温度传感器DS18B20,显示装置LCD和声光报警装置组成,并由单片机AT89S51来控制.单片机巡回检 ...

  4. arduino读取水位传感器的数据显示在基于i2c的1602a上_构建Arduino的LoRa远程智能空气质量监测系统...

    背景知识视频教程 Arduino分步指南:完整指南 - 国外课栈​viadean.com Arduino微控制器:学习Arduino制作项目 - 国外课栈​viadean.com 通过构建实际应用程序 ...

  5. 智能货架安全监测系统

    货架作为一种日常存储货物的媒介,很多情况下都用于工业类产品.食品和饮料的中转站或者长期的存放.货架有托盘式货架.搁板货架.驶入式货架.悬臂式货架.重力式货架.移动式货架等多种. 每年由于仓库隐患引发的 ...

  6. 浅谈高压配电柜温度在线监测系统的设计及选型

    王兰 安科瑞电气股份有限公司 上海嘉定 201801 摘要:高压配电柜是电力系统的关键电能分配节点,保证其运行的稳定可靠具有重要意义.文章综合运用了470MHz无线测温.无线传输等技术手段,设计了一套 ...

  7. 智能井盖安全监测系统,提高城市井盖安全性

    城市燃气.桥梁.供水.排水.热力.综合管廊等城市基础设施生命线就像人体的"神经"和"血管",是城市安全运行的保障.2023年全国住房和城乡建设工作会议提出,启动 ...

  8. RISC-V MCU 智能安全驾驶监测系统

    智能安全驾驶检测 Binary Tree小队 张浩然 谢文倩 杜晓霞 智能安全驾驶检测系统 队员:张浩然 谢文倩 杜晓霞 摘要 现代社会频频发生车祸事件,为了减少各类车祸事故的发生,我们设计了一个智能 ...

  9. 物联网应用系统三层结构的设计_基于物联网技术的智能油烟在线监测系统的设计与应用...

    摘要:餐饮业作为我国第三产业中一个重要的传统服务性行业,其因市场大.增长快.影响广.吸纳就业能力强的特点而广受重视.它经历了三十多年的发展与市场竞争,现在我国餐饮业发展已经进入了经营主体多样化和行业发 ...

最新文章

  1. 简述 clearfix 的原理
  2. 【转发】什么时候该用委托,为什么要用委托,委托有什么好处
  3. java severlet教程_javaweb-severlet
  4. 饶毅坚守教育学者的风骨,网友鼓励:远离精致利己主义的舒适区
  5. 软件设计应该遵循的基本原则有哪些?
  6. 5.Multil-task lasso(多任务lasso回归分析)
  7. sv队列和动态数组的区别_systemverilog学习(4)动态数组
  8. 面向对象编程03—封装、继承、重写、MRO、多态
  9. 机器学习 KNN算法_0 丐版(matlab实现)
  10. Python的可变类型与不可变类型
  11. 简述MVC思想与PHP如何实现MVC
  12. Z-BlogPHP 1.7 Tenet 正式版源码
  13. LintCode初级题——fizz buzz
  14. code vs 1013 求先序排列
  15. python语言变量随时命名随时赋值_Python变量及数据类型用法原理汇总
  16. EurekaServer高可用的注册中心集群搭建
  17. 服务端客户端均采用epoll模式,建立3万TCP连接对内存的影响。
  18. Symbian 清除栈 CleanupStack
  19. 安卓手机修改音量键为HOME和BACK
  20. LOB字段相关概念(自动创建LOB索引段和重建索引方法)

热门文章

  1. 简单聊聊MySQL中的六种日志
  2. 度小满金融踩雷中粮信托近5000万,融资企业母公司为短融网大股东
  3. [Swift通天遁地]七、数据与安全-(6)管理文件夹和创建并操作文件
  4. 目标检测之one-stage和two-stage网络的区别
  5. 搭建Remix IDE本地开发环境
  6. Ambassador系列-09-AuthService认证服务
  7. Python旅途休憩——闭包
  8. Windows 10 Enterprise LTSC 2021 简体中文版、英文版下载 -- 最后一代 Windows 10
  9. WTL 绘制 圆角对话框 自绘对话框
  10. 艺赛旗RPA 第三方库系列(二):提升 pip 工具的下载速度