1、DB18B20采样与显示电路
2、DB18B20简介
- DS18B20是一款高精度的单总线数字温度传感器,适用于多种温度测量场合。
- 温度范围:-55℃至125℃
- 精度:可编程设定9至12位分辨率,对应温度分辨率0.5℃、0.25℃、0.125℃、0.0625℃
- 通信:单总线协议,通过一根通信线完成数据传输
- 供电:支持2.5V至5.5V电压供电,也可通过寄生电源供电
- 内部结构:64位ROM和9字节暂存器,支持多点组网
编程难点:严格的时序要求,需要精确控制起始和采样时间
3、软件代码
DS18B20.c
/********************************************************************** 模块名称: DS18B20.c* 模块描述: DS18B20温度传感器驱动程序实现* 创建人: bianjingyuan* 创建日期: 2024年11月4日* 编译环境: Windows XP + MPLAB IDE 8.83 + Picc 9.60* 版本号: 1.0* 修改记录: 无*********************************************************************/#include "DS18B20.h" // 包含DS18B20的头文件// 定义数据类型
#define uint unsigned int // uint 类型定义为无符号整型
#define uchar unsigned char // uchar 类型定义为无符号字符型// 定义汇编指令
#define nop asm("NOP") // 定义空操作指令// 定义DS18B20通信端口
#define DQ RD0 // 选择与DS18B20通信的端口为 RD0// 定义获取高字节和低字节的宏
#define highbyte(value) ((value) >> 8) // 获取无符号整型的高字节
#define lowbyte(value) ((value) & 0xFF) // 获取无符号整型的低字节// DQ引脚的高低电平设置宏
#define DQ_HIGH() TRISD0 = 1 // 将 DQ 端口设置为输入(高电平)
#define DQ_LOW() DQ = 0; TRISD0 = 0 // 将 DQ 端口设置为输出并拉低(低电平)// 全局变量
uchar temp_h; // 存储温度整数部分(范围从 0 到 255)
uchar temp_l; // 存储温度小数部分(范围从 0 到 99)/********************************************************************** 函 数 名: Init_DS18B20* 功能描述: 初始化DS18B20传感器* 调用函数: delayus()* 全局变量: 无* 输 入: 无* 返 回: 无***********************************************************************/
void Init_DS18B20(void)
{unsigned char ucPresence = 1; // 用于检查DS18B20的存在信号while (ucPresence) // 如果没有收到应答信号则持续尝试{DQ_LOW(); // 将总线拉到低电平以初始化传感器delayus(200); // 延时503us以确保传输稳定delayus(200);delayus(200);DQ_HIGH(); // 释放总线,等到上拉电阻将总线拉高delayus(90); // 等待从机的应答信号if (DQ == 1) // 如果没有接收到低电平应答信号ucPresence = 1;elseucPresence = 0; // 接收到应答信号delayus(250);delayus(250); // 额外等待一段时间以确保时序完整}
}/********************************************************************** 函 数 名: Read_One_Char* 功能描述: 读取DS18B20的一个字节* 调用函数: delayus()* 全局变量: 无* 输 入: 无* 返 回: unsigned char 读取到的字节***********************************************************************/
unsigned char Read_One_Char(void)
{unsigned char ucI, ucValue = 0;static bit bJ;for (ucI = 8; ucI > 0; ucI--) // 循环读取8位数据{ucValue >>= 1; // 将已读取的数据右移一位DQ_LOW(); // 拉低电平以开始数据读取delayus(5); // 延时6us以确保信号有效DQ_HIGH(); // 拉高电平以释放总线delayus(3); // 等待数据的稳定bJ = DQ; // 读取当前数据位if (bJ) ucValue |= 0x80; // 如果是高电平,将当前数据位置1delayus(80); // 延时63us以确保一个完整的读周期}return ucValue;
}/********************************************************************** 函 数 名: Write_One_Char* 功能描述: 写一个字节至DS18B20* 调用函数: delayus()* 全局变量: 无* 输 入: unsigned char ucVal - 要写入的字节值* 返 回: 无***********************************************************************/
void Write_One_Char(unsigned char ucVal)
{unsigned char ucI, ucTemp;for (ucI = 8; ucI > 0; ucI--) // 循环写入8位数据{ucTemp = ucVal & 0x01; // 获取要写入字节的最低位DQ_LOW(); delayus(4); // 拉低电平以标记写入时间隙if (ucTemp == 1) DQ_HIGH(); // 如果是1,拉高电平delayus(75); // 延时63us完成写入DQ_HIGH(); delayus(1); // 等待总线恢复稳定ucVal >>= 1; // 处理下一个数据位}
}/********************************************************************** 函 数 名: Read_Temperature* 功能描述: 读取DS18B20温度,并显示到数码管XXX.XX格式* 调用函数: Init_DS18B20(), Write_One_Char(), Read_One_Char(), highbyte(), send()* 全局变量: 无* 输 入: 无* 返 回: 无***********************************************************************/
void Read_Temperature(void)
{unsigned char ucA = 0, ucB = 0; // 用于存储温度的临时变量unsigned int uiT = 0;DQ_HIGH(); // 准备开始通信Init_DS18B20(); // 初始化DS18B20Write_One_Char(0xCC); // 跳过ROM命令Write_One_Char(0x44); // 启动温度转换Init_DS18B20(); // 再次初始化以准备数据读取Write_One_Char(0xCC); // 跳过ROM命令Write_One_Char(0xBE); // 读取温度寄存器DQ_HIGH();ucA = Read_One_Char(); // 读取温度低字节ucB = Read_One_Char(); // 读取温度高字节uiT = ucB; // 将高字节转移到整型变量中uiT <<= 8;uiT |= ucA; // 将低字节加入到整型变量中// 计算整数部分和小数部分temp_h = (uiT >> 4); // 整数部分temp_l = (100 * (ucA & 0x0F)) >> 4; // 小数部分 (0-99 之间)
}
main.c
//***************************************************************************/
//* 文件名:demo-DS18B20.c
//* 文件描述:PIC16f887,20MHZ,单总线DS18B20温度传感器取样数字显示程序
//* 此文件用于器件的驱动程序仿真
//* 创建人:bianjingyuan 2024年11月4日
//* 编译环境: Windows XP + MPLAB IDE 8.83 + Picc 9.60
//* 版本号:1.0
//* 修改记录:无
//***************************************************************************/
// 硬件资源分配表:
// pic16f887工作频率 20MHZ 外部晶体振荡
//***************************************************************************/
// max7219的引脚定义如下:
// din RE0 //RE0-RE2为887引脚输出
// clk_1 RE2=1
// clk_0 RE2=0
// load_1 RE1=1
// load_0 RE1=0
//***************************************************************************/
// DS1820的空闲状态是高电平,如果总线停留在低电平超过480μs,所有器件都将被复位。
// 单线总线系统包括一个总线控制器和一个或多个从机。DS1820是从机。
// 单线总线需要一个约5KΩ的上拉电阻。DS1820间的任何通讯都需要以初始化序列开始
//***************************************************************************/
// DS1820的引脚定义如下:
// DQ RD0 //定义通信端口
//***************************************************************************/#include "pic.h" //包含单片机内部资源预定义// 数据类型定义
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#define nop asm("NOP")
#define sleep asm("sleep")
#define DQ RD0 //定义DS1820通信端口// *************************以下声明本模块中所调用的函数类型 *****************/
// 发送一字节数据到MAX7219,指定地址和数据
extern void send(uchar address, uchar data);
// 初始化MAX7219器件
extern void Max7219_Init(void);
// 初始化DS18B20传感器
extern void Init_DS18B20(void);
// 从DS18B20读取一个字节的数据
extern uchar Read_One_Char(void);
// 向DS18B20写入一个字节的数据
extern void Write_One_Char(uchar data);
// 读取DS18B20传感器的温度
extern void Read_Temperature(void);
// 延时指定的微秒数,a为延时长度
void delayus(uchar a);
// 延时指定的毫秒数,a为延时长度
void delay_ms(uchar a);
// 延时约1秒钟
void delay_1s(void);
// 初始化系统参数和配置
void Initial_System(void);
// 设置I/O端口状态
void Set_Port_IO(void);extern uchar temp_h; // 存储整数部分
extern uchar temp_l; // 存储小数部分// ****************************887芯片配置位*************************************/
__CONFIG (0x20F2); // 20MHZ外部晶振// *****************************定义全局变量***********************************/// ***************************主程序*******************************************/
void main()
{di();Initial_System();Set_Port_IO();Max7219_Init();
redo:Read_Temperature();send(0x01, 15);send(0x02, 15);send(0x03, (temp_h / 10)); // 显示第二位温度数据send(0x04, (temp_h % 10) + 128); // 最后一位显示小数点send(0x05, temp_l / 10); // 显示小数部分send(0x06, temp_l % 10);send(0x07, 15);send(0x08, 15);delay_1s();goto redo;
}/**************************以下为函数和子程序********************************/
//* 名称: delayus(uchar a)
//* 说明: 对应20M的工作频率,a取值1-250
//* 功能: a大于0,延时约(a*0.8+2) us
//* 调用: 无
//* 输入: 无
//* 返回值: 无
//***************************************************************************/
void delayus(uchar a)
{uchar i;for(i = a; i > 0; i--){nop;}
}//***************************************************************************/
//* 名称: delay_ms(uchar a)
//* 说明: 对应8M的工作频率
//* 功能: a延时约a ms,a取值范围从1-127
//* 调用: 无
//* 输入: 无
//* 返回值: 无
//***************************************************************************/
void delay_ms(uchar a)
{uchar i;a = a << 1;while(a--)for(i = 142; i > 0; i--) { nop; nop; nop; nop; }
}//***************************************************************************/
//* 名称: delay_1s()
//* 说明: 对应20M的工作频率
//* 功能: 软件延时1s
//* 调用: 无
//* 输入: 无
//* 返回值: 无
//**************************************************************************/
void delay_1s(void) // 延迟1S
{ulong d = 185300; // 对应20M的工作频率while(--d);
}//***************************************************************************/
//* 名称: initial_system()
//* 说明: 887芯片初始化
//* 功能: 系统初始化子程序
//* 调用: 无
//* 输入: 无
//* 返回值: 无
//**************************************************************************/
void Initial_System(void)
{OPTION = 0b01010000; // 1us = TMROINTCON = 0b00000000; // 开外围模块中断ANSEL = 0; // 设定没有通道做AD,这样才能使用E口做显示驱动ANSELH = 0b00000000;
}//***************************************************************************/
//* 名称: set_port_io()
//* 说明: 887芯片端口I/O定义
//* 功能: 端口I/O定义
//* 调用: 无
//* 输入: 无
//* 返回值: 无
//**************************************************************************/
void Set_Port_IO(void)
{TRISA = 0;PORTA = 0;TRISD = 0; PORTD = 0;TRISE = 0; // 显示驱动PORTE = 0;
}
4、代码解析
该程序实现了对DS18B20温度传感器的驱动和数据读取。主要功能包括:
- 初始化DS18B20传感器,确保其处于可以通信的状态。
- 读取DS18B20传感器的温度数据,并将其转换为二进制格式。
- 将读取的温度数据进行处理,分解为整数部分和小数部分,并准备好显示。
- 提供写入功能,用于向DS18B20传感器发送命令。
这些功能广泛应用于需要实时温度检测和采集的设备或系统中。
5、硬件资源分配表
序号 | 引脚 | 类别 | 方向 | 功能定义 | 功能内容 | 相关的寄存器及配置 |
---|---|---|---|---|---|---|
1 | RD0 | 数字IO | 双向 | DQ | DS18B20数据总线 | TRISD0配置 |
- 初始化DS18B20传感器,确保其能够进行温度检测。
- 启动温度转换并读取温度寄存器中的数据。
- 将读取的温度数据转换为可显示的格式(整数和小数部分)。
- 提供基础的写入和读取字节的功能,与DS18B20传感器进行命令和数据交互。
6、软件流程图
7、仿真运行结果