本项目选择STC89C52单片机和DS18B20数字温度传感器,通过读取传感器输出的温度值,经由打算和处理后,并将结果显示在数码管上,实现环境温度的实时监测和显示。个中,STC89C52单片机为主控芯片,卖力吸收和处理数字温度传感器的数据,并通过数码管将温度值进行显示。
二、整体设计【1】设计思路
利用 STC89C52 单片机和 DS18B20 数字温度传感器,通过 I/O 口进行连接,读取传感器输出的温度值。通过打算和处理后,将温度值在数码管上进行显示。个中,STC89C52 单片机为主控芯片,卖力吸收和处理数字温度传感器的数据,并通过数码管将温度值进行显示。
硬件方面,须要利用 STC89C52 单片机和 DS18B20 数字温度传感器。个中,STC89C52 单片机通过 P1 口连接4位数码管的动态扫描旗子暗记线,并与 DS18B20 传感器的 DQ 线相连。DS18B20须要利用一个2.2K欧姆上拉电阻和一个10K欧姆下拉电阻。

在软件方面,紧张进行以下操作:
(1)初始化函数
初始化串行总线,设置为推挽输出,并将数码管段选端口初始化为高电平输出,数码管位选端口初始化为低电平输出。
(2)读取温度值函数
通过发送读取命令,从 DS18B20 数字温度传感器中读取温度值。
(3)温度值打算函数
根据 DS18B20 数字温度传感器的温度值打算方法,将读取到的数值进行转换,得到实际温度值。
(4)数码管显示函数
将温度值分离出整数和小数部分,然后经由数码管驱动程序,通过数码管进行显示。
三、详细代码实现【1】DS18B20温度读取DS18B20 是一种数字温度传感器,采取单总线接口进行通讯。它可以在较长的间隔内实现温度值的准确丈量,并且不须要调零或校准,被广泛运用于各种打算机掌握系统、电子设备和温度掌握运用中。其分辨率为 12 位,温度范围为 -55 度 Celsius 到 +125 度 Celsius。
下面代码实现的功能是:读取DS18B20温度再通过串口打印出来。
#include <reg51.h>#define uchar unsigned char#define uint unsigned intsbit DQ = P1^0; // DS18B20 数字温度传感器数据线连接到 P1.0 引脚// DS18B20 数据传输函数void DS18B20_WriteByte(uchar dat);uchar DS18B20_ReadByte();void DS18B20_Start();void DS18B20_End();void DS18B20_Delay(uint i);// 初始化函数void init();// 串口初始化函数void uart_init();// 串口发送函数void send_string(char s);void main() { uchar temp_h, temp_l; uint temp; init(); uart_init(); // 串口初始化 while(1) { DS18B20_Start(); // 启动传输 DS18B20_WriteByte(0xCC); // 忽略 ROM 指令 DS18B20_WriteByte(0x44); // 发送温度转换指令 DS18B20_End(); // 结束传输 DS18B20_Start(); // 启动传输 DS18B20_WriteByte(0xCC); // 忽略 ROM 指令 DS18B20_WriteByte(0xBE); // 发送读取指令 // 读取温度值 temp_l = DS18B20_ReadByte(); // 读取低位温度值 temp_h = DS18B20_ReadByte(); // 读取高位温度值 // 打算温度值 temp = (temp_h << 8) + temp_l; temp = (float)temp / 16; send_string("The temperature is: "); send_string(temp); send_string("\r\n"); DS18B20_End(); // 结束传输 }}// DS18B20 数据传输函数void DS18B20_WriteByte(uchar dat){ uchar i; for (i = 0; i < 8; i++) { DQ = 0; // 写时序开始 DQ = dat & 0x01; // 写数据 DS18B20_Delay(1); // 延时 1us DQ = 1; // 写时序结束 dat >>= 1; }}uchar DS18B20_ReadByte(){ uchar i, dat = 0; for (i = 0; i < 8; i++) { DQ = 0; // 读时序开始 DS18B20_Delay(1); // 延时 1us dat >>= 1; if(DQ) dat |= 0x80; DS18B20_Delay(5); // 延时 5us DQ = 1; // 读时序结束 } return dat;}void DS18B20_Start(){ DQ = 1; DS18B20_Delay(1); DQ = 0; DS18B20_Delay(480); DQ = 1; DS18B20_Delay(60);}void DS18B20_End(){ DQ = 1; DS18B20_Delay(1);}void DS18B20_Delay(uint i){ while(i--);}// 初始化函数void init(){ TMOD |= 0x20; // 定时器 1 事情在模式 2 TH1 = 0xfd; // 设置波特率,4800 bps TL1 = 0xfd; TR1 = 1; // 启动定时器}// 串口初始化函数void uart_init(){ SCON = 0x50; // 8 位数据,可变波特率,许可吸收 ES = 1; // 许可串口中断 EA = 1; // 许可总中断}// 串口发送函数void send_string(char s){ while(s) { SBUF = s; while(!TI); TI = 0; s++; }}
【2】读取温度数码管显示
数码管是一种数码显示装置,常日由一个数码管的阵列组成,可以用来显示数字、字母和一些分外符号。广泛运用于各种电子装置中,如打算器、时钟、温度计、电压表、档位指示器等。数码管常日可分为共阳极和共阴极两种类型,个中共阳极的数码管是将阳极连接在一起,通过掌握对应的阴极接口以实现显示数字,而共阴极则是将阴极连接在一起,通过掌握对应的阳极接口以实现显示。
数码管的显示事理是通过不同的电旗子暗记按照一定的逻辑在数码管内部的小灯泡上点亮不同的线段,从而形成所需的数字、字母或符号。要实现数码管的显示掌握,须要利用微掌握器或其他数字电路实现对数码管各个位的掌握,在采集到数据后将其转换为可显示的信息,并将其显示在相应的数码管上。
下面是通过DS18B20 温度传感器读取温度再通过数码管显示温度:
#include <reg51.h>#define uchar unsigned char#define uint unsigned intsbit DQ = P1^0; // DS18B20 数字温度传感器数据线连接到 P1.0 引脚sbit DIO = P2^0; // 数码管数据总线 DIO 连接到 P2.0 引脚sbit RCLK = P2^1; // 数码管存储总线 RCLK 连接到 P2.1 引脚sbit SRCLK = P2^2; // 数码管移位总线 SRCLK 连接到 P2.2 引脚// DS18B20 数据传输函数void DS18B20_WriteByte(uchar dat);uchar DS18B20_ReadByte();void DS18B20_Start();void DS18B20_End();void DS18B20_Delay(uint i);// 初始化函数void init();// 串口初始化函数void uart_init();// 串口发送函数void send_string(char s);// 数码管显示函数void display(uchar num);void main() { uchar temp_h, temp_l; uint temp; init(); uart_init(); // 串口初始化 while(1) { DS18B20_Start(); // 启动传输 DS18B20_WriteByte(0xCC); // 忽略 ROM 指令 DS18B20_WriteByte(0x44); // 发送温度转换指令 DS18B20_End(); // 结束传输 DS18B20_Start(); // 启动传输 DS18B20_WriteByte(0xCC); // 忽略 ROM 指令 DS18B20_WriteByte(0xBE); // 发送读取指令 // 读取温度值 temp_l = DS18B20_ReadByte(); // 读取低位温度值 temp_h = DS18B20_ReadByte(); // 读取高位温度值 // 打算温度值 temp = (temp_h << 8) + temp_l; temp = (float)temp / 16; // 数码管显示温度 display(temp); send_string("The temperature is: "); send_string(temp); send_string("\r\n"); DS18B20_End(); // 结束传输 }}// DS18B20 数据传输函数void DS18B20_WriteByte(uchar dat){ uchar i; for (i = 0; i < 8; i++) { DQ = 0; // 写时序开始 DQ = dat & 0x01; // 写数据 DS18B20_Delay(1); // 延时 1us DQ = 1; // 写时序结束 dat >>= 1; }}uchar DS18B20_ReadByte(){ uchar i, dat = 0; for (i = 0; i < 8; i++) { DQ = 0; // 读时序开始 DS18B20_Delay(1); // 延时 1us dat >>= 1; if(DQ) dat |= 0x80; DS18B20_Delay(5); // 延时 5us DQ = 1; // 读时序结束 } return dat;}void DS18B20_Start(){ DQ = 1; DS18B20_Delay(1); DQ = 0; DS18B20_Delay(480); DQ = 1; DS18B20_Delay(60);}void DS18B20_End(){ DQ = 1; DS18B20_Delay(1);}void DS18B20_Delay(uint i){ while(i--);}// 初始化函数void init(){ TMOD |= 0x20; // 定时器 1 事情在模式 2 TH1 = 0xfd; // 设置波特率,4800 bps TL1 = 0xfd; TR1 = 1; // 启动定时器}// 串口初始化函数void uart_init(){ SCON = 0x50; // 8 位数据,可变波特率,许可吸收 ES = 1; // 许可串口中断 EA = 1; // 许可总中断}// 串口发送函数void send_string(char s){ while(s) { SBUF = s; while(!TI); TI = 0; s++; }}// 数码管显示函数void display(uchar num){ uchar code table[] = { 0x3f, // '0' 0x06, // '1' 0x5b, // '2' 0x4f, // '3' 0x66, // '4' 0x6d, // '5' 0x7d, // '6' 0x07, // '7' 0x7f, // '8' 0x6f, // '9' }; uchar i; for (i = 0; i < 8; i++) { RCLK = 0; DS = table[num % 10]; // 取出个位数码 num /= 10; // 取下一位数 SRCLK = 1; SRCLK = 0; } RCLK = 1; RCLK = 0;}