基于PRECHIN普中51-实验板学习—温度传感器相关学习(10)

概要

学习使用DS18B20温度传感器

温度转换规则

总线控制器(可以理解为主机,例51单片机)必须发送【44h】命令,DS18B20才开始检测,上电默认精度为12位。

温度>0,s=0;实际温度 = 实测值 * 0.0625;                注:设置的精度不同,乘以的系数也不同。s代表最高五位,最高五位为1,说明为负数。(数据输出共16位)

温度<0,s=1;实际温度 = (~实测值)*0.0625;        

例如:

        该图中使用的精度为12位,所以计算温度时候,需要*0.0625。

DS18B20读取温度使用流程

  1. DS18B20复位
  2. 写入字节0xcc,跳过ROM指令
  3. 写入字节0x44,开始温度转换
  4. 延时
  5. DS18B20复位
  6. 写入字节0xcc,跳过ROM指令
  7. 写入字节0xbe,读取高速暂存器
  8. 读取暂存器的第0个字节,即温度数据的LSB(低八位)
  9. 读取暂存器的第1个字节,即温度数据的HSB(高八位)
  10. DS18B20复位,表明数据读取结束
  11. 将LSB和HSB整合成一个16位数据
  12. 判断读取结果的符号,进行正负温度的数据处理

DS18B20复位

复位可以理解为系统初始化,需要按照时许编程

按照时序来看,先给持续给一段低电平,再拉高电平持续一段时间。

检测DS18B20是否存在

当主机从DQ主线发送信息到DS18B20,如果DS18B20接收到,则将DQ电平拉低为0,过一段时间后再将DQ主线挂起,拉高电平。如果DQ=0;说明DS18B20存在。

从主机向DS18B20写命令

写命令的同时也要注意,在向DQ主线中写入0、1时,时序也不相同。写命令的时候需要先写低位,后写高位。如何实现先写地位后写高位呢。通过&0x01获得最低位,再通过将要写入的命令>>=1获取第二个低位。

主机向DS18B20可写入的指令码

因为在使用的时候只用了一个DS18B20,所以直接从0xcc写入命令即可。       

DS18B20读取主机传过来的命令

DS18B20读取命令的时候也要根据传过来的命令的码元0、1的不同选择不同的时序。要先一位一位的读,再将读到的16位转为两个字节

根据时序一位一位读取命令

将读到的16位转为2字节

DS18B20的初始化和开始转换命令

DS18B20的初始化

DS18B20的开始转换

DS18B20连续读两个字节的数据

主程序开始

总结

主程序中先初始化ds18b20温度传感器,初始化完成后,不断地进行温度检测,如果想让温度传感器实现温度监测,就要根据ds18b20使用流程进行配置。最后根据读取到的数据判断正负温度。这里读取到的数据是带有小数点的,要实时显示到动态数码管中的话,就考虑将温度变为整数,存放到动态数码管,再根据小数点的位置,位选设置点亮。

  • 20
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是普中51-实验制作的简易作业代码: ```c #include <reg52.h> #include <intrins.h> #define uchar unsigned char #define uint unsigned int sbit beep = P1^5; // 蜂鸣器 sbit DIO = P2^0; // 点阵屏数据线 sbit CLK = P2^1; // 点阵屏钟线 sbit SDA = P2^2; // 温度传感器数据线 sbit SCL = P2^3; // 温度传感器钟线 sbit LATCH = P2^4; // 74HC595锁存器控制线 uchar code DIG_CODE[] = { // 共阴数码管显示代码表 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F }; uchar code LED_CODE[] = { // LED灯显示代码表 0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F }; uchar code KEY_CODE[] = { // 矩阵键盘按键代码表 0xEE, 0xDE, 0xBE, 0x7E }; uchar code DIS_CODE[] = { // 显示屏显示代码表 0x38, 0x0C, 0x01, 0x06, 0x1F }; uchar code TEXT[] = "Hello, World!"; // 显示屏显示文本 void delay(uint t) // 延函数 { while (t--); } void writeByte(uchar dat) // 点阵屏写入一个字节 { uchar i; for (i = 0; i < 8; i++) { DIO = dat & 0x80; dat <<= 1; CLK = 0; _nop_(); CLK = 1; } } void writeCmd(uchar cmd) // 点阵屏写入命令 { LATCH = 0; writeByte(0xC0); writeByte(cmd); LATCH = 1; } void writeData(uchar dat) // 点阵屏写入数据 { LATCH = 0; writeByte(0xC1); writeByte(dat); LATCH = 1; } void initDS18B20() // 初始化温度传感器 { SDA = 1; SCL = 1; delay(2); SDA = 0; delay(80); SDA = 1; delay(2); } void writeDS18B20(uchar dat) // 写入温度传感器一个字节 { uchar i; for (i = 0; i < 8; i++) { SDA = dat & 0x01; dat >>= 1; SCL = 0; delay(2); SCL = 1; delay(2); } } uchar readDS18B20() // 读取温度传感器一个字节 { uchar i, dat = 0; for (i = 0; i < 8; i++) { SCL = 0; delay(2); SCL = 1; delay(2); dat >>= 1; if (SDA) dat |= 0x80; } return dat; } void displayDS18B20() // 显示温度传感器温度 { uchar temp[2]; float t; initDS18B20(); writeDS18B20(0xCC); writeDS18B20(0x44); delay(1000); initDS18B20(); writeDS18B20(0xCC); writeDS18B20(0xBE); temp[0] = readDS18B20(); temp[1] = readDS18B20(); t = (temp[1] << 8) | temp[0]; t /= 16; writeCmd(0x80); writeData(DIG_CODE[(int)(t / 10)]); writeData(DIG_CODE[(int)(t % 10)] | 0x80); writeData(0x39); writeData(DIG_CODE[(int)((t - (int)t) * 10)]); } void main() { uchar i, j, k, key, led, dis; TMOD = 0x01; // 定器0工作在模式1 TH0 = 0xFC; // 定器0计数初值 TL0 = 0x66; ET0 = 1; // 开启定器0中断 EA = 1; // 开启总中断 TR0 = 1; // 开始计数 while (1) { key = 0; P2 = 0xFE; if (P0 != 0xFF) { for (i = 0; i < 4; i++) { P2 = 0xFE >> i; if (P0 != 0xFF) { for (j = 0; j < 4; j++) { if (P0 == KEY_CODE[j]) { key = i * 4 + j + 1; break; } } break; } } } if (key > 0) { led = LED_CODE[key - 1]; dis = DIS_CODE[key - 1]; } else { led = 0xFF; dis = 0xFF; } P1 = led; writeCmd(0x40); for (k = 0; k < 8; k++) { writeData(TEXT[k]); } displayDS18B20(); delay(1000); writeCmd(0x80); writeData(dis); delay(500); beep = 1; delay(50); beep = 0; delay(450); } } void timer0() interrupt 1 // 定器0中断服务函数 { TH0 = 0xFC; TL0 = 0x66; P0 = DIG_CODE[k]; if (++k >= 8) k = 0; } ``` 其中,点阵屏使用74HC595移位寄存器控制,共阴数码管、LED灯、矩阵键盘、显示屏、蜂鸣器都是直接接口控制,温度传感器使用DS18B20芯片,通过单总线协议控制读取温度数据。代码实现了按键控制LED灯、显示屏显示文本和数码管显示温度,每隔1秒钟更新一次温度数据,并且每隔500毫秒闪烁一次显示屏的显示代码,同蜂鸣器出滴声。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值