赞
踩
•DS18B20是一种常见的数字温度传感器,其控制命令和数据都是以数字信号的方式输入输出,相比较于模拟温度传感器,具有功能强大、硬件简单、易扩展、抗干扰性强等特点
引脚 | 功能 |
---|---|
VDD | 电源(3.0V ~ 5.5V) |
GND | 电源地 |
DQ(data queue) | 单总线接口 |
(左图为课程中的图片,右图为我的原理图中的图片)
(没有懂但没关系)
存储器(暂存器)结构:
Byte0和Byte1分别存储温度的低位和高位,默认为85
不能直接读写EEPROM,需要先将数据写入暂存器,然后通过通信,将数据在写入EEPROM,读出数据同理
Byte5、Byte6和Byte7为保留字段
1.初始化:主机将总线拉低至少480us,然后释放总线,等待15~60us后,存在的从机会拉低总线60~240us以响应主机,之后从机将释放总线(实际写程序中,一般取中间值)
2.发送一位:主机将总线拉低60~120us,然后释放总线,表示发送0;主机将总线拉低1~15us,然后释放总线,表示发送1。从机将在总线拉低30us后(典型值)读取电平,整个时间片应大于60us
3.也就是说,在30us这个时间点,读取总线的电平状态,如果是高电平,则表示发送1,如果是低电平,则表示发送0
发送一个字节:连续调用8次发送一位的时序,依次发送一个字节的8位(低位在前)
接收一个字节:连续调用8次接收一位的时序,依次接收一个字节的8位(低位在前)
•初始化:从机复位,主机判断从机是否响应
•ROM操作:ROM指令+本指令需要的读写操作
•功能操作:功能指令+本指令需要的读写操作
ROM操作就是访问64位ROM,功能操作就是访问暂存器
•温度变换:初始化→跳过ROM →开始温度变换
•温度读取:初始化→跳过ROM →读暂存器→连续的读操作
(S是符号位,温度为负,则BIT11-15全为1,温度为正,则BIT11-15全为0)
1.利用DS18B20读取温度并将温度显示在LCD1602上
写一位数据函数
- void OneWire_SendBit(unsigned char Bit)
- {//初始化后,发送数据,初始化完成后,若有从机,则从机响应完之后会自动释放总线
- unsigned char i;
-
- //拉低总线
- OneWire_DQ = 0;
-
- //在10us时,发送一位数据
- //软件生成的延时函数调用需要4us左右,因为这里把延时代码放到读数据函数里面了,没有另外定义一个延时函数,故延时14us(软件生成)
- //延时10us
- _nop_();
- i = 4;
- while (--i);
- //发送数据
- OneWire_DQ = Bit;
- //延时50us(总共60us,之前延时10us,再延时50us可完成时序)软件生成延时54us
- _nop_();
- i = 24;
- while (--i);
- //释放总线
- OneWire_DQ = 1;
- }
读一位数据函数
- unsigned char OneWire_ReceiveBit()
- {
- unsigned char i;
- unsigned char Bit;
- //拉低总线
- OneWire_DQ = 0;
- //延时5us(软件生成9us)
- i = 2;
- while (--i);
- //释放总线
- OneWire_DQ = 1;
- //延时5us(软件生成9us)
- i = 2;
- while (--i);
- Bit = OneWire_DQ;
- //延时50us(软件生成延时54us)
- _nop_();
- i = 24;
- while (--i);
-
- return Bit;
- }
发送和接收字节函数
- void OneWire_SendByte(unsigned char Byte)
- {
- unsigned char i;
- for(i=0;i<8;i++)
- {//依次从低到高取出Byte的各个位
- OneWire_SendBit(Byte&(0x01<<i));
- }
- }
-
- unsigned char OneWire_ReceiveByte()
- {
- unsigned char i, Byte = 0x00;
- for(i=0;i<8;i++)
- {//依次从低到高为Byte的各个位赋值
- if(OneWire_ReceiveBit())//bit为0,跳过赋值(默认为0),bit为1,为对应位赋值为1
- {
- Byte |= (0x01<<i);
- }
- }
- return Byte;
- }
温度变换函数
- #define DS18B20_SKIP_ROM 0xCC
- #define DS18B20_CONVERT_T 0x44
-
- void DS18B20_ConvertT()
- {
- OneWire_Init();
- OneWire_SendByte(DS18B20_SKIP_ROM);
- OneWire_SendByte(DS18B20_CONVERT_T);
- }
温度读取函数
- #define DS18B20_READ_SCRATCHPAD 0xBE
-
- float DS18B20_ReadT()
- {
- unsigned char TLSB, TMSB;
- int temp;
- float temperature;
- OneWire_Init();
- OneWire_SendByte(DS18B20_SKIP_ROM);
- OneWire_SendByte(DS18B20_READ_SCRATCHPAD);
- //此时,总线控制权交给从机
- TLSB = OneWire_ReceiveByte();
- TMSB = OneWire_ReceiveByte();
- //TMSB左移8位再和TLSB进行或运算即可获得16位的数值
- temp = (TMSB<<8)|TLSB;
- //根据图6,温度值的小数点在BIT4与BIT3之间,故将temp除以16即可得到温度值(右移一位相当于除以2)
- temperature = temp/16.0;//强制转换为浮点数
- }
主函数
- #include <REGX52.H>
- #include "LCD1602.h"
- #include "DS18B20.h"
-
- void main()
- {
- float t;//温度
- LCD_Init();
- LCD_ShowString(1,1,"Temperature");
-
- while(1)
- {
- DS18B20_ConvertT();
- t = DS18B20_ReadT();
- if(t < 0)
- {
- LCD_ShowChar(2,1,'-');
- t = -t;//负数转为正数
- }
- else
- {
- LCD_ShowChar(2,1,'+');
- }
- LCD_ShowNum(2,2,t,3);//这个函数第三个参数为unsigned int,t是float型,会自动转为unsigned int(即小数部分丢失)
- LCD_ShowChar(2,5,'.');
- //t先乘以10000,将t转化为没有小数的整数,因t是16位的,乘以10000后可能超出unsigned int的表示范围,
- //于是将其转为unsigned long,之后再对10000取余,取出后四位(即原来t的小数位)
- LCD_ShowNum(2,6,(unsigned long)(t*10000)%10000,3);
- }
- }
-
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。