我的单片机课设基于51的温度报警器

更新时间:2024-07-06 03:17:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

课程设计说明书

1引言

1.1 单片机的应用背景

目前单片机渗透到我们生活的各个领域,几乎很难找到哪个领域没有单片机的踪迹。导弹的导航装置,飞机上各种仪表的控制,计算机的网络通信与数据传输,工业自动化过程的实时控制和数据处理,广泛使用的各种智能IC卡,民用豪华轿车的安全保障系统,录象机、摄像机、全自动洗衣机的控制,以及程控玩具、电子宠物等等,这些都离不开单片机,更不用说自动控制领域的机器人、智能仪表、医疗机械了。

世面上主要的单片机类型有 Motorola 单片机、Microchip 单片机、东芝单片机、8051单片机、Atmel 单片机等。此次课设中用到的是ATMEL公司,下面着重介绍一下ATMEL公司的单片机。

ATMEL 公司是世界上著名的高性能低功耗非易失性存储器和数字集成电路的一流半导体制造公司。ATMEL 公司最令人注目的是它的EEPROM 电可擦除技术闪速存储器技术和质量高可靠性的生产技术。在CMOS 器件生产领域中,ATMEL 的先进设计水平优秀的生产工艺及封装技术一直处于世界的领先地位。这些技术用于单片机生产,使单片机也具有优秀的品质在结构性能和功能等方面都有明显的优势,ATMEL 公司的单片机是目前世界上一种独具特色。

而性能卓越的单片机它在计算机外部设备通讯设备自动化工业控制宇航设备仪器仪表和各种消费类产品中都有着广泛的应用前景。其生产的AT90系列是增强型RISC内载FLASH单片机,通常称为AVR系列。AT91M系列是基于ARM7TDMI 嵌入式处理器的ATMEL 16/32 微处理器系列中的一个新成员,该处理器用高密度的16 位指令集实现了高效的32 位 RISC 结构且功耗很低。另外ATMAL的增强型51系列单片机目前在市场上仍然十分流行,其中AT89S51十分活跃。

当今社会,人们在追求高质量的生活,所以生活中离不开单片机,根据国家权威统计显示,目前我国的单片机容量达3亿片,且每年以大约20%的速度增长,但在世界市场我国的占有率还不到1%。沿海地区尤其像电子产品高度发达的深圳大部分单片机应用更是广泛,这种发展趋势也不断向内地辐射,因此,学好单片机有很重要的意义。

1

课程设计说明书

2 总体设计方案

2.1 功能简介

8位LED数码管直接显示DS18B20所测量的温度,超出-50~110℃范围时喇叭报警,并且对应的发光二极管开始闪烁,在温度范围内时喇叭停止报警并且数码管显示其温度,测量精度为0.5℃。

2.2 设计思路

AT89C51作为数字温度计的核心器件,是一种带4K字节FLASH存储器,具有低电压、高性能 特性的8位微处理器。该器件是INTEL公司生产的MCS-5l系列单片机中的基础产品,采用了可靠的CMOS工艺制造技术,属于标准的MCS-51产品。由于将多功能8位CPU和闪烁存储器组合在单个芯片中,ATMEL的AT89C51是一种高效微控制器,芯片中集成了CPU、RAM、ROM、定时/计数器和多功能I/O接口等计算机所需的基本功能部件。

时钟信号用来控制单片机内各种微操作的时间基准,通常有两种形式得到,即内部震荡方式和外部震荡方式。内部震荡方式所得的信号比较稳定,故设计数字温度计的时钟信号选用内部震荡方式,晶振选用12MHZ。

温度传感器选用单线数字温度传感芯片DS18B20,DS18B20在与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯。多个DS18B20可以并联在唯一的三线上,最多只能并联8个,实现多点测温,造成信号传输的不稳定。电压范围为3.0 V至5.5 V 无需备用电源。其测温范围是-55~128℃。

显示部分使用8位LED数码管来作为温度的直接输出,当温度超出-50~110℃时,喇叭报警和发光二极管闪烁来提示。

采用C语言设计温度计的程序,对DS18B20进行初始化、读、写,读取温度,数据的转换,温度显示和报警处理等等。

2.3 芯片器材

主机:单片机AT89C51一片;温度传感器:DS18B20一片,显示电路:74LS245,8位LED数码管;时钟电路:电容两个,晶振片一个;报警电路:发光二极管两个,喇叭一个;其他导线若干,+5V电源等等。

2

课程设计说明书

3 硬件设计

3.1 AT89C51

3.1.1 AT98C51引脚图

U119XTAL1P0.0/AD0P0.1/AD1P0.2/AD2P0.3/AD3P0.4/AD4P0.5/AD5P0.6/AD6P0.7/AD7P2.0/A8P2.1/A9P2.2/A10P2.3/A11P2.4/A12P2.5/A13P2.6/A14P2.7/A15P3.0/RXDP3.1/TXDP3.2/INT0P3.3/INT1P3.4/T0P3.5/T1P3.6/WRP3.7/RD39383736353433322122232425262728101112131415161718XTAL29RST293031PSENALEEA12345678P1.0P1.1P1.2P1.3P1.4P1.5P1.6P1.7AT89C51LS1 图1 AT89C51引脚图 本次设计需要注意的几个端口:

P0口(32—39):是一组8位漏极开路行双向I/O口,也既地址/数据总线复用口。可作为输出口使用时,每位可吸收电流的方式驱动8个TTL逻辑电路,对端口写“1”可作为高阻抗输入输入端用。在访问外部数据存储器时,这组口线分时转换地址(低8位)和数据总线复用,在访问期间激活内部上拉电阻。在Flash编程时,PO口接收指令字节,而在程序校验时,输出指令字节,校验时,要求接上拉电阻。

P1口(1—8):是一个内部提供上拉电阻的8位双向I/O口,P1口缓冲器能接收输出4TTL门电流。P1口管脚写入1后,被内部上拉为高,可用作输入,P1口被外部下拉为低电平时,将输出电流,这是由于内部上拉的缘故。在FLASH编程和校验时,P1口作为第八位地址接收。

P2口(21—28):是一个内部上拉电阻的8位双向I/O口,P2口缓冲器可接收,输出4个TTL门电流,当P2口被写“1”时,其管脚被内部上拉电阻拉高,且作为输入。并因此作为输入时,P2口的管脚被外部拉低,将输出电流。这是由于内部上拉的缘故。P2口当用于外部程序存储器或16位地址外部数据存储器进行存取时,P2口输出地址的高八位。在给出地址“1”时,它利用内部上拉优势,当对外部八位地址数据存储器进行读写时,P2口输出其特殊功能寄存器的内容。P2口在FLASH编程和校验时接收高八位地址信号和控制信号。

3

课程设计说明书

P3口(10—17):是一组带有内部上拉电阻的8位双向I/O口,,P1的输入缓冲级可驱动(吸收或输出电流)4个TTL逻辑门电路。对P3口写入“1”时,它们被内部上拉电阻拉高并可作为输出端口。作输出端口时,被外部拉低的P3口将用上拉电阻输出电流。P3口除可作为一般的I/O口线外,更重要的用途是它的第二功能,如图2所示:

图2 端口引脚P3

EA/Vpp(31):内部和外部程序存储器选择线。EA=0时访问外部ROM 0000H—FFFFH;EA=1时,地址0000H—0FFFH空间访问内部ROM,地址1000H—FFFFH空间访问外部ROM。本次设计EA接高电平。

XTAL1(19)和XTAL2(18):使用内部振荡电路时,用来接石英晶体和电容;使用外部时钟时,用来输入时钟脉冲。

RST/VPD(9):复位信号输入端。AT89S51接能电源后,在时钟电路作用下,该脚上出现两个机器周期以上的高电平,使内部复位。第二功能是VPD,即备用电源输入端。当主电源Vcc发生故障,降低到低电平规定值时,VPD将为RAM提供备用电源,发保证存储在RAM中的信号不丢失。

/PSEN:外部程序存储器的选通信号。在由外部程序存储器取指期间,每个机器周期两次/PSEN有效。但在访问外部数据存储器时,这两次有效的/PSEN信号将不出现./EA/VPP。当/EA保持低电平时,则在此期间外部程序存储器(0000H-FFFFH),不管是否有内部程序存储器。注意加密方式1时,/EA将内部锁定为RESET;当/E.端保持高电平时,此间内部程序存储器。在FLASH编程期间,此引脚也用于施加12V编程电源(VPP)。

XTAL1:反向振荡放大器的输入及内部时钟工作电路的输入。 XTAL2:来自反向振荡器的输出。

3.1.2 AT89C51结构特点

4

课程设计说明书

8位CPU,片内振荡器和时钟电路,32根I/O线,外部存贮器寻址范围ROM、RAM64K,16位的定时器/计数器,5个中断源,两个中断优先级,全双工串行口,布尔处理器。

3.2 温度获取

使用美国Dallas半导体公司的数字化温度传感器DSB1820,支持 “一线总线”接口的温度传感器,全部传感元件及转换电路集成在形如一只三极管的集成电路内。“一线总线”独特而且经济的特点,DS18B20体积小、经济、灵活,使你可以充分发挥“一线总线”的优点。DS18B20支持“一线总线”接口,测量温度范围为-55°C~+125°C,在-10~+85°C范围内,精度为±0.5°C。现场温度直接以“一线总线”的数字方式传输,大大提高了系统的抗干扰性。适合于恶劣环境的现场温度测量,如:环境控制、设备或过程控制、测温类消费电子产品等。支持3V~5.5V的电压范围,使系统设计更灵活、方便。

DS18B20产品的特点 :

(1)、只要求一个端口即可实现通信。

(2)、在DS18B20中的每个器件上都有独一无二的序列号。 (3)、实际应用中不需要外部任何元器件即可实现测温。 (4)、测量温度范围在-55。C到+125。C之间。 (5)、数字温度计的分辨率用户可以从9位到12位选择。 (6)、内部有温度上、下限告警设置。 DS18B20内部结构如图3所示:

64位ROM和一线 高速暂存器 存储和控制逻辑 温度传感器 高温触发器TH 低温触发器TL 配置寄存器 8位CRC生成器 图3 DS18B20内部结构

供电方式

5

课程设计说明书

DS18B20功能命令如表1所示:

表1 DS18B20功能命令表

命令 CONVERT READ SCRATCHPAD

READ ROM WRITE SCRATPAD MATCH ROM SEARCH ROM ALARM SEARCH

SKIP ROM READ POWER SUPPLY

功能描述 启动温度转换 读取温度寄存器 读DS18B20的序列号

将数据写入暂存器的第2、3字节中

匹配ROM 搜索ROM 报警搜索 跳过读序列号的操作

读电源供给方式,0寄生,1外部电源

代码 44H BEH 33H 4EH 55H F0H ECH CCH B4H

其连线使用如图4所示(2接P3.6):

R24.7k321U2VCCDQGNDDS18B20109.0 图4 DS18B20连线图

由于DS18B20单线通信功能是分时完成的,所以有严格的时隙概念,读写时序很重要。系统对DS18B20的各种操作必须按协议进行。操作协议为:初始化DS18B20(发复位脉冲)→发ROM功能命令→发存储器操作命令→处理数据。

由于DS18B20采用的是1-Wire总线协议方式,即在一根数据线实现数据的双向传输,而对AT89S51单片机来说,硬件上并不支持单总线协议,因此,我们必须采用软件的方法来模拟单总线的协议时序来完成对DS18B20芯片的访问。

由于DS18B20是在一根I/O线上读写数据,因此,对读写的数据位有着严格的时序要求。DS18B20有严格的通信协议来保证各位数据传输的正确性和完整性。该

6

课程设计说明书

协议定义了几种信号的时序:初始化时序、读时序、写时序。所有时序都是将主机作为主设备,单总线器件作为从设备。而每一次命令和数据的传输都是从主机主动启动写时序开始,如果要求单总线器件回送数据,在进行写命令后,主机需启动读时序完成数据接收。数据和命令的传输都是低位在先。

DS18B20的复位时序 DS18B20的读时序

对于DS18B20的读时序分为读0时序和读1时序两个过程。

对于DS18B20的读时隙是从主机把单总线拉低之后,在15秒之内就得释放单总线,以让DS18B20把数据传输到单总线上。DS18B20在完成一个读时序过程,至少需要60us才能完成。

DS18B20的写时序

对于DS18B20的写时序仍然分为写0时序和写1时序两个过程。

对于DS18B20写0时序和写1时序的要求不同,当要写0时序时,单总线要被拉低至少60us,保证DS18B20能够在15us到45us之间能够正确地采样IO总线上的“0”电平,当要写1时序时,单总线被拉低之后,在15us之内就得释放单总线。

3.3 时钟电路

单片机的时钟信号使用内部震荡方式产生,其电路图如图5所示:

C122PFU1X112M18XTAL219XTAL1C222PFR110k9RSTC310uF293031PSENALEEA 图5内部震荡电路 7 课程设计说明书

电容器C、C1起稳定震荡频率、快速起振的作用,电容值一般为5-30pF,晶振通常选用6MHZ、12MHZ、24MHZ。内部震荡方式所得的时钟信号比较稳定。

3.4 温度显示电路

八位共阴极数码管,能够显示带一位小数的正负温度。零下时:3显示负号,4显示十位,5显示十位和小数位。6、7显示°C。零上时:3显示百位,4显示十位,5显示个位和小数位,6、7显示°C。当温度超过109.5°C或低于-49.5°C时,发光二极管闪烁并且喇叭报警。

图6 LED的管脚和电路原理

电路上,数码管又可以分为共阴和共阳两种。 数码管的公共端就是位选段。

共阴极的数码管公共端接地,段选高电平有效。 共阴极公共端接+5伏电源,段选端低电平有效。

位选端地意思就是只有这一端选通的时候才能给段选端赋不同的值。 比如说对共阴极的数码管,只有先给位选一个低电平时,才能给段选端赋不同的码,才能在数码管上显示不同的数字。

用途:用于各类仪表、仪器、家用电器等的数字显示。

特点“颜色丰富、亮度高、功耗低、响应速度快、易于集成电路译码器,驱动器直接配合使用。

8段数码管属于LED发光器件的一种。LED发光器件一般常用的有两类:数码管和点阵。8段数码管又称为8字数码管,分为8段:A、B、C、D、E、F、G、P。其中P位小数点。数码管常用的有10根管脚,每一段有一根管脚,另外两根管脚位一个数码管的公共端COM,两根之间互相连通,

八段数码管也分为共阴型和共阳型,共阳型就是发光管的正极都连在一起,作为一条引线,负极分开。八段数码发光管就是8个发光管组成的,在空间排列成为8字型带个小数点,只要将电压家在阳极和阴极之间相应的笔画就会发光。8个发光二极管的阳极并联在一起,8个阴极分开,因此成为共阳八段数码管。

8

其如图7:

课程设计说明书

ABCDEFGDP12345678

图7晶体管显示电路

3.5报警电路

由两个发光二极管组成和一个喇叭组成,分别是高温报警和低温报警,当高温超过110或低温低于50时,对应的二极管闪烁,同时喇叭发出警报。

如图8和图9:

R3220D1高温报警R4220D2低温报警

图8二极管报警电路

LS1SOUNDER 图9喇叭报警电路

9

课程设计说明书

4 程序设计

4.1 程序流程图

程序流程图如图10所示:

开始 初始化DS18B20 N 应答脉冲? Y 跳过读序列号的操作 发出温度转换的命令 等待温度转换完成 初始化DS18B20 跳过读序列号的操作 读温度命令 将温度高、低位读出 处理数据到百、十、个、小数位,并在数码管上显示 N 超出限制? Y 喇叭响和二级管闪烁

图10 程序流程图

10

课程设计说明书

4.2 初始化子程序

使用DS18B20时,单片机先向DS18B20送出复位信号,单片机将数据拉低并保持480~960μs;再释放数据线,由上拉电阻拉高15~60μs;然后再由DS18B20发出低电平60~240μs,就完成了复位操作。

通过init_ds18b20()函数来实现18B20的初始化 char init_ds18b20() {

uchar status;

dq = 1;delay(8);//高电平 dq = 0;delay(90); dq = 1;delay(8);//高电平 status = dq; delay(100); dq = 1;高电平 return status; }

4.3 读子程序

读数据之前,单片机先将数据线拉低,再释放。DS18B20在数据线从高电平跳低后15μs内将数据送到数据线上。单片机在15μs后读数据线。

通过read_temperature()函数读取温度值到DS18B20 void read_temperature() {

if( init_ds18b20() ==1)

ds18b20_is_ok = 0;//DS18B20故障 else {

writeonebyte(0xcc);//跳过序列号 writeonebyte(0x44);//启动温度转换 init_ds18b20();//DS18B20初始化 writeonebyte(0xcc);//跳过序列号 writeonebyte(0xbe);//读取温度寄存器

temp_value[0] = readonebyte();//温度低8位

temp_value[1] = readonebyte();//温度高8位

11

课程设计说明书

alarm_temp_hl[0] = readonebyte();//报警温度DH alarm_temp_hl[1] = readonebyte();//报警温度DL ds18b20_is_ok = 1;//DS18B20正常工作 }

}

4.4 写子程序

在单片机对DS18B20写数据时,应先将数据线拉低1μs以上,再写入数据(写1为高,写0为低)。待单片机写入的数据变化15~60μs后,DS18B20将对数据线采样。单片机写入数据到DS18B20的保持时间为60~120μs。通过writeonebyte()函数写入8位字节。

void writeonebyte(uchar dat) { uchar i;

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

{dq = 0;dq = dat & 0x01;delay(5); dq = 1;dat >>=1; } }

通过set_alarm_temp_value()函数中的实现数据的读入

void set_alarm_temp_value()

{

init_ds18b20();初始化DS18B20 writeonebyte(0xcc); //跳过序列号

writeonebyte(0x4e);//将设定的温度报警值写入DS18B20 writeonebyte(alarm_temp_hl[0]); //写入TH writeonebyte(alarm_temp_hl[1]); //写入TL writeonebyte(0x7f);//12位精度 init_ds18b20(); //初始化DS18B20 writeonebyte(0xcc); //跳过序列号

writeonebyte(0x48); //温度报警值存入DS18B20

}

4.5 数据处理子程序

12

课程设计说明书

先判断温度高8位,如果CY为1,则将高、低8八位求补;对高、低8位的数据按权整合称一个整数,判断是否在-50~110℃之间,超出范围则置报警灯为亮;将该数按百、十、个位分别存入相应的存储单元。流程图如图11所示:

取温度值 符号为正? Y N 求补码 高、低8位整合成为一个整数存入A中 -50~110之间? N 报警 Y 分别存入百、十、个、小数位

图11 数据处理流程图

通过子函数display_temperature()中的 uchar ng = 0 , np = 0; char signed_current_temp;

if ( ( temp_value[1] & 0xf8) == 0xf8 )//如果是负数则取反加1 {temp_value[1] = ~temp_value[1]; temp_value[0] =~temp_value[0] + 1;

if ( temp_value[0] == 0x00 ) temp_value[1]++;正数显示温度值加1

ng = 1;np = 0xfd;//默认负号显示在左边第2排 }

display_digit[0] = df_table[temp_value[0] & 0x0f ];//查表得到温度小数部分 currentt = ((temp_value[0] & 0xf0)>>4) | ((temp_value[1] & 0x07)<<4);//获取温度整数部分

signed_current_temp = ng? -currentt :currentt;//有符号数当前温度值

13

课程设计说明书

hi_alarm = signed_current_temp >= alarm_temp_hl[0] ? 1 : 0;//高温报警设置 lo_alarm = signed_current_temp <= alarm_temp_hl[1] ? 1: 0;//低温报警设置 // 将整数部分分解为三位待显示数字 display_digit[3] = currentt /100;//百位 display_digit[2] = currentt % 100 /10;//十位 display_digit[1] = currentt % 10;//个位 if (display_digit[3] == 0 ) {

display_digit[3] = 10;//高位是零则不显示

np = 0xfb;//调整负号位置 if( display_digit[2] == 0) {

display_digit[2] =10;//高位是零则不显示 np = 0xf7;//调整负号位置 }

语句实现温度数据处理,如果 温度数据是正,则直接分别显示百、十、个位,如果最高位是零,则最高位不显示。如果温度是负,则取反后再显示。

4.6 显示子程序

将百、十、个、小数位的数据查表,送到对应的数码管显示,程序流程图如12所示:

14

课程设计说明书

取温度

温度为负? Y N 显示百位,延时 显示负号,延时 显示十位,延时 显示个位,延时 显示小数位,延时 N 显示400遍? N Y 超过范围? Y 延时 返回

图12 显示程序流程图

通过子函书中display_temperature()中的

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

{

P0 = 0x39;P2 = 0x7f; delay(t);P2 = 0xff;//显示C

P0 = 0x63; P2 = 0xbf;delay(t);P2 = 0xff;//显示。

15

课程设计说明书

P0 =dsy_code[display_digit[0]];//小数位

P2 = 0xdf;delay(t) ;P2 = 0xff;个位位选

P0 =(dsy_code[display_digit[1]]) | 0x80;//个位及小数点段选 P2 = 0xef;delay(t);P2 = 0xff;十位位选 P0 =dsy_code[display_digit[2]];//十位段选 P2 = 0xf7; delay(t) ;P2 = 0xff;百位位选 P0 = dsy_code[display_digit[3]];//百位段选 P2 = 0xfb;delay(t);P2 = 0xff;负号位选 if(ng)//如果为负数则在调整后的位置显示\ {

P0 = 0x40;P2 = np;delay(t); P2 = 0xff; } }

语句实现温度显示,并且控制负号的位置。

4.7报警子程序

当温度大于110或小于-50时,达到报警值,则开始报警,发光二极管闪烁,同时喇叭发出警报。

此过程通过t0_int() interrupt 1函数实现语句如下: void t0_int() interrupt 1 {

TH0 = -1000/256;//定时器0写入初值 TL0 = -1000%6;//定时器0写入初值 beep = !beep;//喇叭送人矩形脉冲 if (++time0_count == 400) {

time0_count = 0;//计数

if (hi_alarm) hi_led = ~hi_led ;else hi_led = 1;//如果超过高温,二极管闪烁 if (lo_alarm) lo_led = ~lo_led; else lo_led = 1;//如果超过低温,二极管闪烁 } }

16

课程设计说明书

5 实验仿真

ABCDEFGDPC122PFU1X112M18XTAL219XTAL1P0.0/AD0P0.1/AD1P0.2/AD2P0.3/AD3P0.4/AD4P0.5/AD5P0.6/AD6P0.7/AD7P2.0/A8P2.1/A9P2.2/A10P2.3/A11P2.4/A12P2.5/A13P2.6/A14P2.7/A15P3.0/RXDP3.1/TXDP3.2/INT0P3.3/INT1P3.4/T0P3.5/T1P3.6/WRP3.7/RD3938373635343332212223242526272810111213141516171234567823456789191U3A0A1A2A3A4A5A6A7CEAB/BA74LS245B0B1B2B3B4B5B6B71817161514131211ABCDEFGDPC222PFR110k9RSTC310uF293031PSENALEEAR3220D1高温报警R4220D2低温报警12345678P1.0P1.1P1.2P1.3P1.4P1.5P1.6P1.7AT89C51R24.7k321LS1SOUNDER12345678U2VCCDQGNDDS18B20105.0本程序将报警温度设为高: 110 低: -50 图13 完整电路图

ABCDEFGDPC122PFU1X112M18XTAL219XTAL1P0.0/AD0P0.1/AD1P0.2/AD2P0.3/AD3P0.4/AD4P0.5/AD5P0.6/AD6P0.7/AD7P2.0/A8P2.1/A9P2.2/A10P2.3/A11P2.4/A12P2.5/A13P2.6/A14P2.7/A15P3.0/RXDP3.1/TXDP3.2/INT0P3.3/INT1P3.4/T0P3.5/T1P3.6/WRP3.7/RD3938373635343332212223242526272810111213141516171234567823456789191U3A0A1A2A3A4A5A6A7CEAB/BA74LS245B0B1B2B3B4B5B6B71817161514131211ABCDEFGDPC222PFR110k9RSTC310uF293031PSENALEEAR3220D1高温报警R4220D2低温报警12345678P1.0P1.1P1.2P1.3P1.4P1.5P1.6P1.7AT89C51R24.7k321LS1SOUNDER12345678U2VCCDQGNDDS18B20107.0本程序将报警温度设为高: 110 低: -50

图14温度范围内显示

17

课程设计说明书

6 总结

短短一周单片机的课设让我学到了不少东西。随着社会发展,单片机的应用已经非常广泛,渗透到智能仪表、工业控制、家用电器、计算机网络和通信网络、医用电器、汽车等领域。学好单片机真的很重要,这次课设过程中,现实搜集了网上一些资料和查了许多相关书籍,编写程序时遇到了许多问题,后请教同学和查阅相关资料这些问题得以解决。在调试过程中出现了许多错误,比如一些定义一些子函数名时大小写字母错误,导致程序不能运行,后经仔细检查每一个字母得以解决。这让我懂得了做任何事情都要有耐心,并且要细心,做任何事情都不可能一帆风顺,遇到挫折要积极面对,要有信心去解决,虚心向他人请教,这样也会让自己少走许多弯路。

学以致用,通过这次课设把学到的单片机地理论知识与实际结合起来,更加巩固了以前的学习,并且对单片机内部结构认识更加深刻。最后,特别感谢老师在课设过程中的指导和帮助。

18

课程设计说明书

参考文献

1、何立民主编,单片机中级教程,北京航空航天大学出版社 2、丁元杰主编,单片机原理与应用,机械工业出版社 3、彭伟编,单片机C语言程序设计实训,电子工业出版社

19

课程设计说明书

附录

程序清单: #include #include

#define uchar unsigned char #define uint unsigned int

sbit dq = P3^6; sbit beep = P3^7;

sbit hi_led = P1^4; sbit lo_led = P1^5;

uchar code

dsy_code[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00}; uchar code df_table[]= {0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9 }; char alarm_temp_hl[2] = {110,-50}; uchar currentt = 0; uchar temp_value[] ={ 0x00,0x00}; uchar display_digit[] = {0,0,0,0,};

bit hi_alarm = 0, lo_alarm = 0 ; bit ds18b20_is_ok = 1; uint time0_count = 0;

void delay(uint x) {

while(--x); }

char init_ds18b20() {

uchar status; dq = 1;delay(8); dq = 0;delay(90); dq = 1;delay(8); status = dq; delay(100); dq = 1;

return status; }

uchar readonebyte() {

uchar i,dat = 0; dq = 1;_nop_();

20

课程设计说明书

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

dq = 0; dat >>= 1;dq = 1;_nop_();_nop_(); if(dq) dat |= 0x80;delay(30);dq = 1; }

return dat; }

void writeonebyte(uchar dat) {

uchar i;

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

{dq = 0;dq = dat & 0x01;delay(5); dq = 1;dat >>=1; } }

void read_temperature() {

if( init_ds18b20() ==1) ds18b20_is_ok = 0; else

{writeonebyte(0xcc); writeonebyte(0x44); init_ds18b20(); writeonebyte(0xcc); writeonebyte(0xbe);

temp_value[0] = readonebyte(); temp_value[1] = readonebyte(); alarm_temp_hl[0] = readonebyte(); alarm_temp_hl[1] = readonebyte(); ds18b20_is_ok = 1; } }

void set_alarm_temp_value() {

init_ds18b20(); writeonebyte(0xcc); writeonebyte(0x4e);

writeonebyte(alarm_temp_hl[0]); writeonebyte(alarm_temp_hl[1]); writeonebyte(0x7f); init_ds18b20(); writeonebyte(0xcc);

21

writeonebyte(0x48); }

void display_temperature()

课程设计说明书

{

uchar i;

uchar t = 150;

uchar ng = 0 , np = 0;

char signed_current_temp;

if ( ( temp_value[1] & 0xf8) == 0xf8 ) {temp_value[1] = ~temp_value[1]; temp_value[0] =~temp_value[0] + 1;

if ( temp_value[0] == 0x00 ) temp_value[1]++; ng = 1;np = 0xfd; }

display_digit[0] = df_table[temp_value[0] & 0x0f ];

currentt = ((temp_value[0] & 0xf0)>>4) | ((temp_value[1] & 0x07)<<4); signed_current_temp = ng? -currentt :currentt;

hi_alarm = signed_current_temp >= alarm_temp_hl[0] ? 1 : 0; lo_alarm = signed_current_temp <= alarm_temp_hl[1] ? 1: 0; display_digit[3] = currentt /100;

display_digit[2] = currentt % 100 /10; display_digit[1] = currentt % 10; if (display_digit[3] == 0 ) {

display_digit[3] = 10; np = 0xfb; if( display_digit[2] == 0) { display_digit[2] =10; np = 0xf7; } } for (i = 0;i <30;i ++) {

P0 = 0x39;P2 = 0x7f; delay(t);P2 = 0xff; P0 = 0x63; P2 = 0xbf;delay(t);P2 = 0xff; P0 =dsy_code[display_digit[0]]; P2 = 0xdf;delay(t) ;P2 = 0xff; P0 =(dsy_code[display_digit[1]]) | 0x80; P2 = 0xef;delay(t);P2 = 0xff; P0 =dsy_code[display_digit[2]]; P2 = 0xf7; delay(t) ;P2 = 0xff;

22

课程设计说明书

P0 = dsy_code[display_digit[3]]; P2 = 0xfb;delay(t);P2 = 0xff; if(ng) {

P0 = 0x40;P2 = np;delay(t); P2 = 0xff; } } }

void t0_int() interrupt 1 { TH0 = -1000/256; TL0 = -1000%6; beep = !beep; if (++time0_count == 400) { time0_count = 0; if (hi_alarm) hi_led = ~hi_led ;else hi_led = 1; if (lo_alarm) lo_led = ~lo_led; else lo_led = 1; } }

void main (void) {

IE = 0x82;

TMOD = 0x01; TH0 = -1000 / 256; TL0 = -1000 % 256; TR0 = 0; hi_led = 1; lo_led = 1;

set_alarm_temp_value(); read_temperature(); delay(50000); delay(50000); while(1) {

read_temperature(); if (ds18b20_is_ok) {

if (hi_alarm == 1 || lo_alarm == 1 ) TR0 = 1; else TR0 = 0;

display_temperature(); }

23

else {

P0=0x00; P2=0x00;} } }

课程设计说明书

24

本文来源:https://www.bwwdw.com/article/y84.html

Top