📄 test_ds18b20.c
字号:
//---------------------------------------------------
// 文件名: Test_DS18B20.c
// 创建日期: 080225
// 创建: Tim
// 描述: 作用——测试温度传感器能否正常使用
// 现象——用八段数码管来显示温度,精确到小数点后3位
// 注意——精确延时的要求
//---------------------------------------------------
#include <reg52.h>
unsigned char code sled_table[] = { // 位编码
0x14, // 0
0xD7, // 1
0x4C, // 2
0x45, // 3
0x87, // 4
0x25, // 5
0x24, // 6
0x57, // 7
0x04, // 8
0x05, // 9
0x06, // A
0xA4, // B
0x3C, // C
0xC4, // D
0x2C, // E
0x2E // F
};
unsigned char code bit_table[] = { // 位选
0xDF, // bit0
0xEF, // bit1
0xF7, // bit2
0xFB, // bit3
0xFD, // bit4
0xFE, // bit5
};
unsigned char code dot = 0xFB; // 小数点
sbit TDQ = P1 ^ 7; // 温度传感器数据引脚
unsigned char th, tl; // 读出温度的高位字节和低位字节
unsigned char tint, tdec; // 11位的温度值分离成整数部分和小数部分
unsigned char disbuf[6]; // 存储转换后的数字字符
// us级延时函数,精度约为2us
void delay2us(unsigned char i)
{
while(--i);
}
// 毫秒级延时函数
void delay_ms(unsigned int ms)
{
unsigned int i, j;
for(i = 0; i < ms; i++)
for(j = 0; j < 1000; j++);
}
// 函数原型申明
//----------------------------------------------------
// DS18B20驱动
void reset(); // 复位函数
void writebyte(unsigned char wdata); // DS18B20写驱动函数
unsigned char readbyte(); // DS18B20读驱动函数
// 温度值显示
void changeform(); // 字符格式转换函数
void display(); // 八段数码管显示函数
// main函数
//----------------------------------------------------
void main()
{
// 主循环:读出DS18B20采集的温度值-->在八段数码管上显示该值
while(1)
{
// 读取温度
//---------------------------
// 初始化温度值
th = 0;
tl = 0;
tint = 0;
tdec = 0;
// 开始DS18B20的操作序列(序列的详细作用与含义参见DS18B20的器件手册)
reset(); // 向DS18B20发出复位脉冲
writebyte(0xCC); // 跳过DS18B20的ROM操作
writebyte(0x44); // 启动DS18B20的温度转换操作
reset(); // 复位
writebyte(0xCC); // 跳过DS18B20的ROM操作
writebyte(0xBE); // 读出DS18B20内部ROM的寄存器,其中前两个TL、TH依次为温度值的低8位和高3位(包括5位符号)
tl = readbyte(); // 保存TL
th = readbyte(); // 保存TH
// 处理读出的温度值,分离整数报部分和小数部分
tdec = tl & 0x0f; // 温度小数部分的值
tl = tl >> 4; // 低位右移4位,舍弃小数部分
th = th & 0x07; // 去掉符号位
tint = th << 4; // 高位左移4位
tint = tint | tl; // 拼接得到温度整数部分的值
// 显示温度
//---------------------------
changeform(); // 按位转换温度值为字符,保存到disbuf[]中
display(); // 调用显示函数显示温度值
}
}
// DS18B20驱动函数
//----------------------------------------------------
// 包括:
// 1. 复位函数reset(): 向DS18B20发出复位脉冲
// 2. 写函数writebyte(): 向DS18B20写一字节(操作编码)
// 3. 读函数readbyte(): 从DS18B20的数据引脚读出一字节
// 复位函数reset()
//-----------------------------------------------
// 注:详细的复位时序说明参见DS18B20的器件手册
void reset()
{
unsigned char ack = 0; // 用于保存DS18B20对复位脉冲的响应
TDQ = 1; // 置数据引脚为高
delay2us(50); // 插入短延时
TDQ = 0; // 向DS18B20发出复位脉冲,至少维持480us
delay2us(250); // 要求延时大于480us
TDQ = 1; // 拉高数据线,等待DS18B20响应
delay2us(50); // 插入短延时,等待数据线拉高和DS18B20的响应,
// 一般为建立时间为15~60us,DS18B20的响应脉冲维持60~240us
ack = TDQ; // 接收DS18B20响应,复位完成
delay2us(50); // 插入短延时,隔开后续操作
}
// 写函数writebyte()
//-----------------------------------------------
// 注:详细的时序要求参见DS18B20的器件手册
void writebyte(unsigned char wdata)
{
unsigned char i;
// 按低位到高位的顺序将8位数据(一字节)写入DS18B20
for (i = 0; i < 8; i++)
{
TDQ = 0; // 拉低数据线,至少1us
TDQ = wdata & 0x01; // 写入一位
delay2us(30); // 插入延时,等待DS18B20采样数据,该采样延时值为15-60us,故此处至少延时60us
TDQ = 1; // 拉高数据线,等待写下一位
wdata >>= 1; // 写数据移位
}
delay2us(10); // 插入短延时,隔开后续操作(此处延时不宜过长,否则会影响到部分操作,如读操作)
}
// 读函数readbyte()
//-----------------------------------------------
// 注:详细的时序要求参见DS18B20的器件手册
unsigned char readbyte()
{
unsigned char i;
unsigned char rdata = 0;
// 按低位到高位的顺序将8位数据(一字节)写入DS18B20
for (i = 0; i < 8; i++)
{
TDQ = 0; // 拉低数据线,至少1us
rdata >>= 1; // 读数据移位,准备记录数据
TDQ = 1; // 拉高数据线,准备读数据
if (TDQ == 1) // 如果DS18B20没有拉低总线(说明读出的改位为1)向rdata最高位写1
{
rdata = rdata | 0x80; // 将1写入到最高位
}
delay2us(30); // 插入延时,约为60us,等待DS18B20发送下一个数据
}
return(rdata); // 返回读数据
}
// 八段数码管显示函数
//----------------------------------------------------
// 包括:
// 1. 格式转换函数changeform(): 按位转换数字字符
// 2. 显示函数display(): 显示数值
// 格式转换函数changeform()
//-----------------------------------------------
void changeform()
{
unsigned char ctemp;
// 小数部分的转换
//------------------------------------------
float dec;
// 处理小数部分,保存小数点后面3位数字
dec = tdec; // 将小数部分的值转换浮点类型
dec = dec * 0.0625 * 1000; // 将小数部分的值转换成温度值(乘以DS18B20的精度0.0625)并乘以1000,以便截取3位的有效位
ctemp = dec; // 取3位有效数字,即dec的整数部分
// 将小数部分的数值按位转换成十进制数字
disbuf[0] = ctemp % 10; // 小数点后第三位(0.001)
ctemp = ctemp / 10;
disbuf[1] = ctemp % 10; // 小数点后第二位(0.01)
ctemp = ctemp / 10;
disbuf[2] = ctemp % 10; // 小数点后第一位(0.1)
// 整数部分的转换
//------------------------------------------
ctemp = tint; // 取整数部分
disbuf[3] = ctemp % 10; // 个位(1)
ctemp = ctemp / 10;
disbuf[4] = ctemp % 10; // 十位(10)
ctemp = ctemp / 10;
disbuf[5] = ctemp % 10; // 百位(10)
delay2us(30); // 插入短延时
}
// 显示函数display()
//-----------------------------------------------
void display()
{
unsigned int displaytime = 1000; // 设定显示时间,该值需要调试,以便得到最佳效果
unsigned char i;
unsigned char mask;
while(displaytime--) // 显示循环
{
for (i = 0; i < 6; i++)
{
// 设置掩码,屏蔽P1_7(被DS18B20的数据线占据)
mask = 0x80;
mask = mask & P1;
mask = mask | 0x7F;
// 按位显示数字
P1 = bit_table[i] & mask; // 位选,与掩码做"&"操作
P0 = sled_table[disbuf[i]]; // 选择字符显示
delay_ms(100); // 插入显示延时
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -