点击链接获取Keil源码与Project Backups仿真图:
https://download.csdn.net/download/qq_64505944/87777752?spm=1001.2014.3001.5503
源码获取
主要内容:
基于51单片机设计一个温度检测报警器,至少具有以下功能:温度的检测和超过设定值时的报警功能
基本要求:
1、功能齐全,要配有功能说明;
2、protus仿真电路的设计,并设计源程序且能在 keil运行源程序;
3、运行结果的分析。
主要参考资料:
[1]刘光乾. 教学Keil C51软件安装及STC89C52单片机实训平台的应用详解[N]. 电子报,2019-12-15(009).
[2]丁霞等基于单片机的红外测温仪设计[J].山西电子技术,2011(04):21-23.
[3]李娜娜等基于MLX90615和MSP430的红外测温系统的设计[J].传感器与微系统,2011,30(09):115-117+120.
[4]林德. 嵌入式C编程实战[M].人民邮电出版社:, 201610.185.
[5]何尚等嵌入式系统原理与应用[M].重庆大学出版社:, 201908.347.
[6]付丽辉等 单片机原理及应用实训教程[M].南京大学出版社:21世纪应用型本科院校规划教材, 201707.199.
[7]邓胡滨等 单片机原理及应用技术[M].人民邮电出版社:, 201412.342.
完 成 期 限:12 月 11 日 - 12 月 26 日
指导教师签名:
摘 要
单片计算机即单片微型计算机。由 RAM ,ROM,CPU构成,定时,计数和多种接口于一体的微控制器。它体积小,成本低,功能强,广泛应用于智能产业和工业自动化上。而51系列单片机是各单片机中最为典型和最有代表性的一种。这次课程设计通过对它的学习,应用,从而达到学习、设计、开发软、硬的能力。本设计主要设计了一个基于AT89C51单片机的温度检测报警器。并在数码管上显示相应的温度。应用Proteus 实现了单片机温度检测报警系统的设计与仿真。该方法仿真效果真实、准确,节省了硬件资源。
目 录
摘 要 III
目 录 IV
1 绪论 1
1.1系统的设计背景 1
1.2 AT89C51单片机介绍 1
1.3系统的开发环境 1
1.3.1 开发平台 1
1.3.2 开发工具 2
2 功能说明 2
2.1功能分析 2
2.2功能流程图 2
2.3主要原件 3
3 系统运行 3
3.1系统主电路 3
3.2系统的设计 4
3主控模块硬件电路设计 4
4复位电路 5
5晶振电路 5
6声光报警模块 5
7感应模块 5
3.3 运行结果 6
3.4 运行结果分析 6
4 源程序 7
5 总结 17
参考文献 18
1 绪论
1.1系统的设计背景
本次的课程设计是对周边环境的温度采集进行检测报警,当选择采用的温度感应器采集的温度不符合于用户的设定值之后,进行声光报警。本人将设计分成硬件设计和软件设计,其中硬件设计主要是通过使用Proteus仿真软件来选择合适的元器件,然后模拟其运行以此设计。软件设计是通过使用专门的软件设计平台来编辑硬件的功能逻辑,硬件以此来作为基础,完成本次预想的功能。
本次功能选择采用DS18B20温度感应器作为本次检测温度的感应器,将采集的温度传输给单片机,单片机获取该数据后传输给显示模块,显示模块显示数据,将数据可视化给用户观看,本次设定的报警阈值是超过三十五摄氏度的时候进行声光报警。
1.2 AT89C51单片机介绍
AT89C51是一种带4K字节闪烁可编程可擦除只读存储器的低电压,高性能CMOS8位微处理器,俗称单片机。单片机的可擦除只读存储器可以反复擦除1000次。该器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51 指令集和输出管脚相兼容。AT89C51单片机有40个引脚,其中包含2个专用于主电源的引脚,2个外接晶体的引脚,4个控制或与其它电源复用的引脚,以及32条输入输出IO引脚。
1.3系统的开发环境
1.3.1 开发平台
Windows 平台以其全新的界面简单快捷的操作方式而成为软件开发的趋势。根据本系统的运行环境和实际情况,选择Windows 10作为开发测试和运行的平台,以下是详细信息:
操作系统:Windows 10 家庭中文版
系统类型:64 位操作系统, 基于 x64 的处理器
1.3.2 开发工具
Proteus 8 ;Keil uVision4
2 功能说明
2.1功能分析
通过Proteus仿真制作一个温度检测报警器,可以输出温度。
2.2功能流程图
图2-1 功能流程图
2.3主要原件
主要原件有:
图2-2 原件图
3 系统运行
3.1系统主电路
下图为基于51单片机设计的电子闹钟系统的主电路界面:
图3-1 温度检测主电路
3.2系统的设计
1温度采集电路设计
温度采集电路部分,采用数字温度传感器DS18B20进行温度采集。DS18B20是DALLAS公司生产的一线式数字温度传感器,具有3个引脚;温度的侧量范围为-55C到+125C,测量精度为0.5C;被测温度用符号扩展的16位数字量方式串行输出,并且CPU中央处理器只需用一个端口线就可以与DS18B20通信。
2显示模块电路设计
LCD1602显示屏与单片机的P0口相互连接,单片机将获取到的温度数据传输给LCD1602显示屏,按照软件代码里显示的样式来进行双行显示。
3主控模块硬件电路设计
本次设计的温度检测报警系统主控模块为单片机的最小系统。最小系统是由单片机,复位电路,晶振电路三个部分组合而成。本次使用的单片机为AT89C51单片机,该单片机作为初学者们常用的单片机,优点是结构完善,寄存器集中管理,并且拥有丰富的指令系统,最大的优势是在于它拥有乘法和除法的指令,这是很多处于八位单片机都不具有的功能。缺点是使用某些其他功能的时候需要进行扩展模组,增加了很多其他的负担,并且输入输出口的高电平能力过低,保护芯片能力较差。该单片机可以直接与设计的复位电路和晶振电路连接组合成单片机里面的最小系统。
4复位电路
这个电路可以对单片机进行初始化操作,按下按键之后,系统会回到最初刚开机时候的情况。复位电路设计电容和电阻是用于单片机里控制复位的时间,所以设计的时候,我们要对其中的电阻和电容进行合适的选择。重启整个系统的复位电路设计
5晶振电路
电路能够为这次设计提供一个事件顺序,之后的软件设计编程中的时候,单片机的执行的指令都会按照这个最基础事件顺序来进行排列执行。在本次的设计中,设计使用了的是11MHz的晶振,还有27PF瓷片电容来组成了这次晶振电路。之后将晶振电路中的元器件互相链接好,然后连接到AT89C51单片机的XTAL1和XTAL2引脚相连接,也就是18和19号引脚。
6声光报警模块
在本次设计的声光报警模块里,它的主要功能是把上述中的感应模块里面采集的数据进行判断,数据大于其预警值启动的报警模块。本次声光报警模块选择使用了一个电阻、一个RED灯、一个发生喇叭组合而成。RED灯连接在单片机的P1.6端口上,喇叭接口在P1.7接口上。
7感应模块
本次设计的感应模块采用的是DS18B20感应器来检测周边环境的温度,DS18B20是常用的数字温度传感器,其输出的是数字信号,具有体积小,硬件开销低,抗干扰能力强,精度高的特点。DS18B20数字温度传感器接线方便,封装成后可应用于多种场合,如管道式,螺纹式,磁铁吸附式,不锈钢封装式,主要根据应用场合的不同而改变其外观。封装后的DS18B20可用于电缆沟测温,锅炉测温,机房测温,农业大棚测温,洁净室测温,弹药库测温等各种非极限温度场合。耐磨耐碰,体积小,使用方便,封装形式多样,适用于各种狭小空间设备数字测温和控制领域。本次将DS18B20感应器通过连接在单片机的P2.0接口上进行数据传输。
3.3 运行结果
图3-2 温度检测运行结果
3.4 运行结果分析
本次设计是使用当下流行的传感器传感技术,通过使用DS18B20温度传感器来采集周边温度然后将其数据传给主控模块,单片机对数据进行判断,同时将数据传输给显示屏显示给用户查看,当数据超过报警值的时候,启动声光报警提示用户。本次完成的功能有:
1、通过使用DS18B20感应器检测温度;
2、通过使用Lcd1602显示屏来进行数据显示;
3、当采集的温度超过三十五摄氏度的时候进行声光报警。
4 源程序
#include<reg51.h>
#include "TEMP.H"
#include "LCD.H"
#define uint unsigned int
#define uchar unsigned char
sbit led = P1^6; //led引脚
sbit beep = P1^7; //蜂鸣器引脚
sbit key = P1^4; //按键引脚
//函数声明
void Lcd_Display(int temp);
void alarm(uchar t);
void keyscan();
uchar tab[]="Temp:";
uchar tab1[5];
uchar tab2[]="LCL:-20"; //下限值
uchar tab3[]="HCL:+35"; //上限值
uchar start=1;
void main()
{
uchar i,j,k;
beep=0; //上电先将蜂鸣器关闭
LcdInit(); //初始化lcd
while(1)
{
keyscan(); //检测按键是否按下
if(start == 1) //显示当前温度值
{
LcdWriteCom(0x80); //lcd屏起始写地址0x80
for(k=0;k<5;k++)
{
LcdWriteData(tab[k]); //第一行写入temp:
}
LcdWriteCom(0x8c);
LcdWriteData(0xdf);
LcdWriteData('c'); //第0x8c位置写入温度符号
Lcd_Display(Ds18b20ReadTemp()); //温度写入lcd屏
Delay1ms(200);
LcdWriteCom(0x80+0x40); //第二行开始写上限值
for(j=0;j<7;j++)
{
LcdWriteData(tab3[j]);
}
LcdWriteCom(0x88+0x40);
LcdWriteData(0xdf);
LcdWriteData('c');
}
if(Ds18b20ReadTemp() >= 560 || Ds18b20ReadTemp() <= -320 ) //当温度超出上下限值时报警
{
led = 0; //led亮
alarm(90); //蜂鸣器响
}
else
{
led = 1; //否则不报警
}
}
//显示温度上下限报警值
}
//LM016L显示程序
void Lcd_Display(int temp)
{
float tp;
if(temp < 0) //当温度小于0
{
LcdWriteCom(0x85);
LcdWriteData('-'); //在lcd屏上0x85的位置写-号
temp = temp-1;
temp = ~temp; //ds18b20读取的负数温度是实际温度的补码
tp = temp; //将其减一再取反求出原码
temp = tp*0.0625; //转化为十进制数
}
else
{
LcdWriteCom(0x85);
LcdWriteData('+'); //在lcd屏上0x85的位置写+号
tp = temp;
temp = tp*0.0625;
}
tab1[0] = temp/100;
tab1[1] = temp%100/10;
tab1[2] = temp%10;
tab1[3] = 0;
tab1[4] = 0;
LcdWriteCom(0x86); //写地址0x86
LcdWriteData('0'+tab1[0]); //百位
LcdWriteCom(0x87); //写地址0x87
LcdWriteData('0'+tab1[1]); //十位
LcdWriteCom(0x88); //写地址0x88
LcdWriteData('0'+tab1[2]); //个位
LcdWriteCom(0x89); //写地址0x89
LcdWriteData('.'); //小数点
LcdWriteCom(0x8a); //写地址0x8a
LcdWriteData('0'+tab1[3]); //十分位
LcdWriteCom(0x8b); //写地址0x8b
LcdWriteData('0'+tab1[4]); //百分位
}
//蜂鸣器报警
void alarm(uchar t) //控制频率使蜂鸣器发出声音
{
uchar i,j;
for(i = 0;i < 200;i++)
{
beep = ~beep;
for(j = 0;j < t;j++);
}
}
//按键程序
void keyscan()
{
if(key == 0) //检测按键是否按下
{
Delay1ms(1000); //消抖
if(key == 0) //再次检测按键
{
start = !start; //取反
LcdWriteCom(0x01); //清屏
}
while(!key); //检测按键是否松开
}
}
#include "LCD.H"
//LCD1602延时函数
void Lcd1602_Delay1ms(uint c) //误差0us
{
uchar a,b;
for (; c>0; c--)
{
for (b=199;b>0;b--)
{
for(a=1;a>0;a--);
}
}
}
//LM016L初始化子程序
void LcdInit() //LCD初始化子程序
{
LcdWriteCom(0x38); //开显示
LcdWriteCom(0x0c); //开显示不显示光标
LcdWriteCom(0x06); //写一个指针加1
LcdWriteCom(0x01); //清屏
LcdWriteCom(0x80); //设置数据指针起点
}
//LM016L写命令子程序
void LcdWriteCom(uchar com) //写入命令
{
LCD1602_E = 0; //使能
LCD1602_RS = 0; //选择发送命令
LCD1602_RW = 0; //选择写入
LCD1602_DATAPINS = com; //放入命令
Lcd1602_Delay1ms(1); //等待数据稳定
LCD1602_E = 1; //写入时序
Lcd1602_Delay1ms(5); //保持时间
LCD1602_E = 0;
}
//LM016L写数据子程序
void LcdWriteData(uchar dat) //写入数据
{
LCD1602_E = 0; //使能清零
LCD1602_RS = 1; //选择输入数据
LCD1602_RW = 0; //选择写入
LCD1602_DATAPINS = dat; //放入数据
Lcd1602_Delay1ms(1); //等待数据稳定
LCD1602_E = 1; //写入时序
Lcd1602_Delay1ms(5); //保持时间
LCD1602_E = 0;
}
#include<reg51.h>
#include "TEMP.H"
#include "LCD.H"
#define uint unsigned int
#define uchar unsigned char
sbit led = P1^6; //led引脚
sbit beep = P1^7; //蜂鸣器引脚
sbit key = P1^4; //按键引脚
//函数声明
void Lcd_Display(int temp);
void alarm(uchar t);
void keyscan();
uchar tab[]="Temp:";
uchar tab1[5];
uchar tab2[]="LCL:-20"; //下限值
uchar tab3[]="HCL:+35"; //上限值
uchar start=1;
void main()
{
uchar i,j,k;
beep=0; //上电先将蜂鸣器关闭
LcdInit(); //初始化lcd
while(1)
{
keyscan(); //检测按键是否按下
if(start == 1) //显示当前温度值
{
LcdWriteCom(0x80); //lcd屏起始写地址0x80
for(k=0;k<5;k++)
{
LcdWriteData(tab[k]); //第一行写入temp:
}
LcdWriteCom(0x8c);
LcdWriteData(0xdf);
LcdWriteData('c'); //第0x8c位置写入温度符号
Lcd_Display(Ds18b20ReadTemp()); //温度写入lcd屏
Delay1ms(200);
LcdWriteCom(0x80+0x40); //第二行开始写上限值
for(j=0;j<7;j++)
{
LcdWriteData(tab3[j]);
}
LcdWriteCom(0x88+0x40);
LcdWriteData(0xdf);
LcdWriteData('c');
}
if(Ds18b20ReadTemp() >= 560 || Ds18b20ReadTemp() <= -320 ) //当温度超出上下限值时报警
{
led = 0; //led亮
alarm(90); //蜂鸣器响
}
else
{
led = 1; //否则不报警
}
}
//显示温度上下限报警值
}
//LM016L显示程序
void Lcd_Display(int temp)
{
float tp;
if(temp < 0) //当温度小于0
{
LcdWriteCom(0x85);
LcdWriteData('-'); //在lcd屏上0x85的位置写-号
temp = temp-1;
temp = ~temp; //ds18b20读取的负数温度是实际温度的补码
tp = temp; //将其减一再取反求出原码
temp = tp*0.0625; //转化为十进制数
}
else
{
LcdWriteCom(0x85);
LcdWriteData('+'); //在lcd屏上0x85的位置写+号
tp = temp;
temp = tp*0.0625;
}
tab1[0] = temp/100;
tab1[1] = temp%100/10;
tab1[2] = temp%10;
tab1[3] = 0;
tab1[4] = 0;
LcdWriteCom(0x86); //写地址0x86
LcdWriteData('0'+tab1[0]); //百位
LcdWriteCom(0x87); //写地址0x87
LcdWriteData('0'+tab1[1]); //十位
LcdWriteCom(0x88); //写地址0x88
LcdWriteData('0'+tab1[2]); //个位
LcdWriteCom(0x89); //写地址0x89
LcdWriteData('.'); //小数点
LcdWriteCom(0x8a); //写地址0x8a
LcdWriteData('0'+tab1[3]); //十分位
LcdWriteCom(0x8b); //写地址0x8b
LcdWriteData('0'+tab1[4]); //百分位
}
//蜂鸣器报警
void alarm(uchar t) //控制频率使蜂鸣器发出声音
{
uchar i,j;
for(i = 0;i < 200;i++)
{
beep = ~beep;
for(j = 0;j < t;j++);
}
}
//按键程序
void keyscan()
{
if(key == 0) //检测按键是否按下
{
Delay1ms(1000); //消抖
if(key == 0) //再次检测按键
/***让18B20开始转换温度***/
void Ds18b20ChangTemp()
{
Ds18b20Init();
Delay1ms(1);
Ds18b20WriteByte(0xcc); //跳过ROM操作命令
Ds18b20WriteByte(0x44); //温度转换命令
//Delay1ms(100); //等待转换成功,而如果你是一直刷着的话,就不用这个延时了
}
/***发送读取温度命令**/
void Ds18b20ReadTempCom()
{
Ds18b20Init();
Delay1ms(1);
Ds18b20WriteByte(0xcc); //跳过ROM操作命令
Ds18b20WriteByte(0xbe); //发送
5 总结
本次通过单片机制作电子闹钟对我有很大的影响,让我意识到仿真的运行离不开源程序代码的编写,要设计好代码逻辑结构,提高代码可读性、复用性,设计出适合仿电路运行的代码体系。有时候单片机的学习很单调,有些知识学起来很抽象,不容易理解,只能慢慢适应,一边学习理论知识,一边编写程序,将程序刷入单片机进行调试,通过这种方式才能更快速的学习单片机。
设计完整个作品之后,才能明白到实践能够证明自己的所学,明白了自己还有很多不足的地方。硬件部分设计的时候有很多地方因为不熟悉仿真软件,设计完成进度缓慢。软件设计的时候,许多功能函数的设计不清楚,不明白。在网上查了很多的资料才完成。在这之后我将更加注重实践,吸取这次的不足,完善自己。学习单片机不可能一蹴而就,要不断地学习和积累,坚持不懈才会有所收获。
参考文献
[1]刘光乾. 教学Keil C51软件安装及STC89C52单片机实训平台的应用详解[N]. 电子报,2019-12-15(009).
[2]丁霞等基于单片机的红外测温仪设计[J].山西电子技术,2011(04):21-23.
[3]李娜娜等基于MLX90615和MSP430的红外测温系统的设计[J].传感器与微系统,2011,30(09):115-117+120.
[4]林德. 嵌入式C编程实战[M].人民邮电出版社:, 201610.185.
[5]何尚等嵌入式系统原理与应用[M].重庆大学出版社:, 201908.347.
[6]付丽辉等 单片机原理及应用实训教程[M].南京大学出版社:21世纪应用型本科院校规划教材, 201707.199.
[7]邓胡滨等 单片机原理及应用技术[M].人民邮电出版社:, 201412.342.