DS18B20使用注意事项

芯片STC15W404AS

最重要两点:一是精准延时,用内嵌汇编的方式保证;二是CRC校验

keil中内嵌汇编的方法:
直接嵌入汇编代码的方法:
1、在 C 文件中要嵌入汇编代码片以如下方式加入汇编代码:
#pragma ASM
; Assembler Code Here
#pragma ENDASM
2、在 Project 窗口中包含汇编代码的 C 文件上右键,选择“Options for ...”,点击右边的“Generate Assembler SRC File”
和“Assemble SRC File”,使检查框由灰色变成黑色(有效)状态;
3、根据选择的编译模式,把相应的库文件(如 Small 模式时,是 Keil\C51\Lib\C51S.Lib)加入工程中, 该文件必须作为工程的最
后文件;
4、编译,即可生成目标代码

bsp_ds18b20.h
/*********************************************************************************                                  
* 模块名称 : 温度传感器DS18B20   
* 文件名称 : bsp_ds18b20.h
* 版    本 : V0.1
* 说    明 : 
* 日 期 :20151022  
* 作 者 :文治国     
*********************************************************************************/
#ifndef __BSP_DS18B20_H__
#define __BSP_DS18B20_H__

#ifdef  DS18B20_GLOBALS
#define DS18B20_EXT
#else
#define DS18B20_EXT extern
#endif //DS18B20_GLOBALS

#include "config.h"

#define DS18B20_RESET_OUT_TIME 12*20 //300
#define DS18B20_ERR_TEMPERATURE 9999
#define DS18B20_RESET_ERR 1

#define DEFAULT_ALARM_TEMPERATURE 50
#define MAX_ALARM_TEMPERATURE 99
#define MIN_ALARM_TEMPERATURE 20

#define DS18B20_JUMP_ROM_CMD 0XCC //跳过ROM
#define DS18B20_AD_START_CMD 0X44 //开始温度转换
#define DS18B20_READ_RAM_CMD 0XBE //读取RAM

#define DS18B20_PORT GPIO_P1
#define DS18B20_PIN GPIO_Pin_6
#define DS18B20_VALUE P16
#define DS18B20_H() DS18B20_VALUE = 1
#define DS18B20_L() DS18B20_VALUE = 0

#define DS18B20_OUT_H() DS18B20_H()   //输出高
#define DS18B20_OUT_L() DS18B20_L() //输出低

#define DS18B20_IN_H() DS18B20_H()
#define GPIO_READ_DS18B20() DS18B20_VALUE

DS18B20_EXT bit F_ad_trans_en; //定时转换标志
DS18B20_EXT bit F_ad_trans_start; //开始转换标志
DS18B20_EXT bit F_ad_read_en; //转换结束可读取标志
DS18B20_EXT bit F_ad_read_ok; //温度正确读取标志
DS18B20_EXT bit F_negative; //负数标志

DS18B20_EXT uint16_t Now_Temperature; //实时温度

DS18B20_EXT void DS18B20_INPUT(void);
DS18B20_EXT void DS18B20_OUTPUT(void);
DS18B20_EXT void GPIO_DS18B20_Config(void);
DS18B20_EXT void Read_Temperature_Process(void);
DS18B20_EXT void DS18B20_Start_Trans(void);
DS18B20_EXT void Read_DS18B20(void);

#endif //__BSP_DS18B20_H__

bsp_ds18b20.c

/**********************************************************
* 函 数 名: Delay_1us
* 功能说明: 精准1US延时函数
* 参    数:无
* 返 回 值: 无
* 使用说明:
* 调用方法:Delay_1us()
************************************************************/
void Delay_1us(void)
{
#pragma ASM
NOP; //@12.000MHz   8+4(CALL)
NOP;
NOP;
NOP;
NOP;
NOP;
NOP;
NOP;
#pragma ENDASM
}

/**********************************************************
* 函 数 名: Delay_2us
* 功能说明: 精准2US延时函数
* 参    数:无
* 返 回 值: 无
* 使用说明:
* 调用方法:Delay_2us()
************************************************************/
void Delay_2us(void)
{
#pragma ASM //@12.000MHz
NOP;
NOP;
PUSH 30H
MOV 30H,#2
Delay_2us_loop:
DJNZ 30H,Delay_2us_loop
POP 30H
#pragma ENDASM
}

/**********************************************************
* 函 数 名: Delay_5us
* 功能说明: 精准5US延时函数
* 参    数:无
* 返 回 值: 无
* 使用说明:
* 调用方法:Delay_5us()
************************************************************/
void Delay_5us(void)
{
#pragma ASM //@12.000MHz
NOP;
NOP;
NOP;
PUSH 30H
MOV 30H,#9
Delay_5us_loop:
DJNZ 30H,Delay_5us_loop
POP 30H
#pragma ENDASM
}

/**********************************************************
* 函 数 名: Delay_10us
* 功能说明: 精准10US延时函数
* 参    数:无
* 返 回 值: 无
* 使用说明:
* 调用方法:Delay_10us()
************************************************************/
void Delay_10us(void)
{
#pragma ASM //@12.000MHz
NOP;
NOP;
NOP;
PUSH 30H
MOV 30H,#21
Delay_10us_loop:
DJNZ 30H,Delay_10us_loop
POP 30H
#pragma ENDASM
}

/**********************************************************
* 函 数 名: Delay_15us
* 功能说明: 精准15US延时函数
* 参    数:无
* 返 回 值: 无
* 使用说明:
* 调用方法:Delay_15us()
************************************************************/
void Delay_15us(void)
{
#pragma ASM //@12.000MHz
NOP;
NOP;
NOP;
PUSH 30H
MOV 30H,#33
Delay_15us_loop:
DJNZ 30H,Delay_15us_loop
POP 30H
#pragma ENDASM
}

/**********************************************************
* 函 数 名: Delay_45us
* 功能说明: 精准45US延时函数
* 参    数:无
* 返 回 值: 无
* 使用说明:
* 调用方法:Delay_45us()
************************************************************/
void Delay_45us(void)
{
#pragma ASM //@12.000MHz
NOP;
NOP;
NOP;
PUSH 30H
MOV 30H,#105
Delay_45us_loop:
DJNZ 30H,Delay_45us_loop
POP 30H
#pragma ENDASM

/**********************************************************
* 函 数 名: Delay_60us
* 功能说明: 精准60US延时函数
* 参    数:无
* 返 回 值: 无
* 使用说明:
* 调用方法:Delay_60us()
************************************************************/
void Delay_60us(void)
{
#pragma ASM //@12.000MHz
NOP;
NOP;
NOP;
PUSH 30H
MOV 30H,#141
Delay_60us_loop:
DJNZ 30H,Delay_60us_loop
POP 30H
#pragma ENDASM
}

/**********************************************************
* 函 数 名: Delay_240us
* 功能说明: 精准240US延时函数
* 参    数:无
* 返 回 值: 无
* 使用说明:
* 调用方法:Delay_240us()
************************************************************/
void Delay_240us(void)
{
#pragma ASM //@12.000MHz
NOP;
PUSH 30H
PUSH 31H
MOV 30H,#3
MOV 31H,#56
Delay_240us_loop:
DJNZ 31H,Delay_240us_loop
DJNZ 30H,Delay_240us_loop
POP 31H
POP 30H
NOP;
NOP;
NOP;
NOP;
#pragma ENDASM
}   
/**********************************************************
* 函 数 名: Delay_550us
* 功能说明: 精准550US延时函数
* 参    数:无
* 返 回 值: 无
* 使用说明:
* 调用方法:Delay_550us()
************************************************************/
void Delay_550us(void)
{
#pragma ASM //@12.000MHz
NOP;
PUSH 30H
PUSH 31H
MOV 30H,#6
MOV 31H,#29
Delay_550us_loop:
DJNZ 31H,Delay_550us_loop
DJNZ 30H,Delay_550us_loop
POP 31H
POP 30H
NOP;
NOP;
NOP;
NOP;
#pragma ENDASM
}  
 /*********************************************************************************                                  
* 模块名称 : DS18B20模块    
* 文件名称 : bsp_ds18b20.c
* 版    本 : V0.1
* 说    明 : 
* 日 期 :20171107  
* 作 者 :文治国     
*********************************************************************************/
#define DS18B20_GLOBALS
#include "bsp_ds18b20.h"

#include "GPIO.h"
#include "timer.h"
#include "bsp_real.h"
#include "alarm.h"
#include "USART.h"

//CRC8校验
code uint8_t chCRC8Talbe[256] = {
0x00, 0x5e, 0xbc, 0xe2, 0x61, 0x3f, 0xdd, 0x83,
0xc2, 0x9c, 0x7e, 0x20, 0xa3, 0xfd, 0x1f, 0x41, 
0x9d, 0xc3, 0x21, 0x7f, 0xfc, 0xa2, 0x40, 0x1e,
0x5f, 0x01, 0xe3, 0xbd, 0x3e, 0x60, 0x82, 0xdc, 
0x23, 0x7d, 0x9f, 0xc1, 0x42, 0x1c, 0xfe, 0xa0,
0xe1, 0xbf, 0x5d, 0x03, 0x80, 0xde, 0x3c, 0x62, 
0xbe, 0xe0, 0x02, 0x5c, 0xdf, 0x81, 0x63, 0x3d,
0x7c, 0x22, 0xc0, 0x9e, 0x1d, 0x43, 0xa1, 0xff,
0x46, 0x18, 0xfa, 0xa4, 0x27, 0x79, 0x9b, 0xc5, 
0x84, 0xda, 0x38, 0x66, 0xe5, 0xbb, 0x59, 0x07,
0xdb, 0x85, 0x67, 0x39, 0xba, 0xe4, 0x06, 0x58,
0x19, 0x47, 0xa5, 0xfb, 0x78, 0x26, 0xc4, 0x9a,
0x65, 0x3b, 0xd9, 0x87, 0x04, 0x5a, 0xb8, 0xe6, 
0xa7, 0xf9, 0x1b, 0x45, 0xc6, 0x98, 0x7a, 0x24, 
0xf8, 0xa6, 0x44, 0x1a, 0x99, 0xc7, 0x25, 0x7b,
0x3a, 0x64, 0x86, 0xd8, 0x5b, 0x05, 0xe7, 0xb9, 
0x8c, 0xd2, 0x30, 0x6e, 0xed, 0xb3, 0x51, 0x0f, 
0x4e, 0x10, 0xf2, 0xac, 0x2f, 0x71, 0x93, 0xcd,
0x11, 0x4f, 0xad, 0xf3, 0x70, 0x2e, 0xcc, 0x92,
0xd3, 0x8d, 0x6f, 0x31, 0xb2, 0xec, 0x0e, 0x50, 
0xaf, 0xf1, 0x13, 0x4d, 0xce, 0x90, 0x72, 0x2c, 
0x6d, 0x33, 0xd1, 0x8f, 0x0c, 0x52, 0xb0, 0xee, 
0x32, 0x6c, 0x8e, 0xd0, 0x53, 0x0d, 0xef, 0xb1, 
0xf0, 0xae, 0x4c, 0x12, 0x91, 0xcf, 0x2d, 0x73, 
0xca, 0x94, 0x76, 0x28, 0xab, 0xf5, 0x17, 0x49,
0x08, 0x56, 0xb4, 0xea, 0x69, 0x37, 0xd5, 0x8b,
0x57, 0x09, 0xeb, 0xb5, 0x36, 0x68, 0x8a, 0xd4,
0x95, 0xcb, 0x29, 0x77, 0xf4, 0xaa, 0x48, 0x16, 
0xe9, 0xb7, 0x55, 0x0b, 0x88, 0xd6, 0x34, 0x6a, 
0x2b, 0x75, 0x97, 0xc9, 0x4a, 0x14, 0xf6, 0xa8, 
0x74, 0x2a, 0xc8, 0x96, 0x15, 0x4b, 0xa9, 0xf7,
0xb6, 0xe8, 0x0a, 0x54, 0xd7, 0x89, 0x6b, 0x35,
};

/*******************************************************************
* 函 数 名: CRC8
* 功能说明: CRC校验码生成函数
* 参    数:void
* 返 回 值: 无
* 使用说明:  本代码中使用查表法,以提高运算速度
* 调用方法CRC8()
************************************************************/
uint8_t CRC8(uint8_t *puchMsg, uint8_t DataLen)
{
uint8_t uchCRC = 0;
while(DataLen--)
{
uchCRC = chCRC8Talbe[uchCRC ^ *puchMsg++];
}
return uchCRC;
}

/*******************************************************************
* 函 数 名: DS18B20_OUTPUT
* 功能说明: 配置DS18B20端口为输出 
* 参    数:无
* 返 回 值: 无
* 使用说明:
* 调用方法:DS18B20_OUTPUT()
************************************************************/
void DS18B20_OUTPUT(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.Mode = GPIO_OUT_PP; //输入或输出方式
GPIO_InitStructure.Pin  = DS18B20_PIN; //指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7, 或操作
GPIO_Inilize(DS18B20_PORT,&GPIO_InitStructure);
}

/*******************************************************************
* 函 数 名: DS18B20_INPUT
* 功能说明: 配置DS18B20端口为输入 
* 参    数:无
* 返 回 值: 无
* 使用说明:
* 调用方法:DS18B20_INPUT()
************************************************************/
void DS18B20_INPUT(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.Mode = GPIO_HighZ; //输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
GPIO_InitStructure.Pin  = DS18B20_PIN; //指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7, 或操作
GPIO_Inilize(DS18B20_PORT,&GPIO_InitStructure);
}

/*******************************************************************
* 函 数 名: GPIO_DS18B20_Config
* 功能说明: 配置DS18B20端口 
* 参    数:无
* 返 回 值: 无
* 使用说明:
* 调用方法:GPIO_DS18B20_Config()
************************************************************/
void  GPIO_DS18B20_Config(void)
{
DS18B20_OUTPUT();
DS18B20_OUT_H();
F_ad_trans_en = TRUE;
}

/*******************************************************************
* 函 数 名: DS18B20_Reset
* 功能说明: 复位DS18B20 
* 参    数:无
* 返 回 值: uint8_t 复位成功= 0   失败=1
* 使用说明:
* 调用方法:DS18B20_Reset()
************************************************************/
uint8_t DS18B20_Reset(void)
{
uint16_t out_time = 0;
DS18B20_OUTPUT(); //拉低总线
DS18B20_OUT_L();    
Delay_550us(); //480--960us
DS18B20_OUT_H(); //释放总线
DS18B20_INPUT();
Delay_60us(); //DS18B20 16--60us内应答

while(GPIO_READ_DS18B20() && (out_time < DS18B20_RESET_OUT_TIME))//60-240US
{
Delay_1us();
out_time++;
}
if(out_time >= DS18B20_RESET_OUT_TIME) //超时
{
return 1;
}

Delay_240us();
out_time = 0;
while(GPIO_READ_DS18B20()==0 && (out_time < DS18B20_RESET_OUT_TIME))//60-240US
{
Delay_1us();
out_time++;
}
if(out_time >= DS18B20_RESET_OUT_TIME) //超时
{
return 1;
}

return 0;
}

/*******************************************************************
* 函 数 名: DS18B20_Read
* 功能说明: 读DS18B20 
* 参    数:无
* 返 回 值: uint8_t 读数据
* 使用说明:
* 调用方法:DS18B20_Read()
************************************************************/
uint8_t DS18B20_Read(void)
{
uint8_t i, temp=0;

DISABLE_ALL_INTTERRUPT(); //不禁止中断的情况下,中断处理时间过长会影响DS18B20数据读写
for(i=0; i<8; i++)
{
temp >>= 1;
DS18B20_OUTPUT();
DS18B20_OUT_L();
Delay_2us();
DS18B20_OUT_H();
DS18B20_INPUT();  
Delay_1us();
if(GPIO_READ_DS18B20() != 0)
temp |= 0x80;
   Delay_60us();
}
ENABLE_ALL_INTTERRUPT();
return temp;
}

/*******************************************************************
* 函 数 名: DS18B20_Write
* 功能说明: 写DS18B20 
* 参    数:uint8_t
* 返 回 值:  
* 使用说明:
* 调用方法:DS18B20_Write()
************************************************************/
void DS18B20_Write(uint8_t wdata)
{
uint8_t i;
DISABLE_ALL_INTTERRUPT();
for(i=0; i<8; i++)
{
DS18B20_OUTPUT();
DS18B20_OUT_L();
Delay_10us();
if(wdata & 0x01)
DS18B20_OUT_H();
Delay_45us();
DS18B20_OUT_H();
    Delay_5us();
wdata >>= 1;
}
ENABLE_ALL_INTTERRUPT();
}

/*******************************************************************
* 函 数 名: DS18B20_Start_Trans
* 功能说明: DS18B20开始转换温度 12bit
* 参    数:void
* 返 回 值: 
* 使用说明:
* 调用方法:DS18B20_Start_Trans()
************************************************************/
void DS18B20_Start_Trans(void)
{
if(F_ad_trans_en == TRUE)
{
if(DS18B20_Reset() == 1)  //复位失败
{
return;
}
DS18B20_Write(DS18B20_JUMP_ROM_CMD); //跳过ROM 0XCC
DS18B20_Write(DS18B20_AD_START_CMD); //温度转换 0X44
F_ad_trans_en = FALSE;
F_ad_trans_start = TRUE; //开始转换
}
}

/*******************************************************************
* 函 数 名: Read_DS18B20
* 功能说明: DS18B20读取温度 
* 参    数:void
* 返 回 值: 带一位小数点温度值 
* 使用说明:
* 调用方法:Read_DS18B20()
************************************************************/
void Read_DS18B20(void)
{
uint16_t temp_l, temp_h;
uint16_t temp;
uint8_t i;
uint8_t ram_data[9]={0};
if(F_ad_read_en == TRUE)
{
if(DS18B20_Reset() == 1)  //复位失败
{
   
return;
}
DS18B20_Write(DS18B20_JUMP_ROM_CMD); //跳过ROM 0XCC
DS18B20_Write(DS18B20_READ_RAM_CMD); //读取RAM 0XBE
   
for(i=0; i<9; i++)
{
ram_data[i] = DS18B20_Read();
}
if(CRC8(ram_data, 9))   //校验失败,数据有误
{
F_ad_read_en = FALSE; //数据有误,下个周期再读
return;
}

//temp_l =  DS18B20_Read(); //读低八位
//temp_h =  DS18B20_Read(); //读高八位
temp_l =  ram_data[0]; //读低八位
temp_h =  ram_data[1]; //读高八位
if((temp_h & 0xf8) == 0xf8)
{
F_negative = TRUE;
temp = (temp_h << 8) | temp_l;
temp = (~temp) + 1; //取负绝对值
}
else
{
F_negative = FALSE;
temp = ((temp_h ) << 8) | temp_l;
}
temp = temp / 16; //
if(temp == 0)
F_negative = FALSE;

Now_Temperature = temp;
F_ad_read_en = FALSE;
return ;
}
}

/*******************************************************************
* 函 数 名: Read_Temperature_Process
* 功能说明: 读温度
* 参    数:void
* 返 回 值: 带一位小数点温度值 
* 使用说明:
* 调用方法:Read_Temperature_Process()
************************************************************/
void Read_Temperature_Process(void)
{
DS18B20_Start_Trans();
Read_DS18B20();
}

DS18B20使用注意事项相关推荐

  1. Stm32内部温度传感器

    STM32有一个内部的温度传感器,可以用来测量CPU及周围的温度(TA). 特点: 该温度传感器在内部和ADCx_IN16输入通道相连接,此通道把传感器输出的电压转换成数字值 温度传感器模拟输入推荐采 ...

  2. Esp8266 进阶之路19 【外设篇①】esp8266驱动 ds18b20、dht11 温湿度传感器,采集温湿度传感器到服务器。(附带Demo)

    本系列博客学习由非官方人员 半颗心脏 潜心所力所写,不做开发板.仅仅做个人技术交流分享,不做任何商业用途.如有不对之处,请留言,本人及时更改. 序号 SDK版本 内容 链接 1 nonos2.0 搭建 ...

  3. 关于51单片机驱动DS18B20代码的感想

    首先使用单总线驱动DS18B20有三个步骤 DS18B20 器件的初始化 ROM commond Function Command 这里我们经常使用的是初始化和功能命令字,对于第二项,是为了区分多个单 ...

  4. 51单片机+DS18B20+数码管显示+串口通讯+Proteus仿真

    51单片机+DS18B20+数码管显示+串口通讯+Proteus仿真 本实验通过51单片机读取DS18B20温度传感器的温度,然后通过数码管显示,并通过串口,将读取到的温度数据发送出去. 本案例需要使 ...

  5. K_A11_002 基于STM32等单片机驱动DS18B20串口与OLED0.96双显示

    K_A11_002 基于STM32等单片机驱动DS18B20 串口与OLED0.96双显示 一.资源说明 二.基本参数 1.参数 2.引脚说明 三.驱动说明 时序 对应程序: 四.部分代码说明 1.接 ...

  6. 技能梳理6@NODEMCU+BH1750+DS18B20+DHT11+PWM电机+ONENET

    智慧鱼缸,检测土壤湿度,检测室内温湿度和光照,检测鱼缸水位,检测鱼缸温度,各种蜂鸣器报警(水温超20-24)和控制舵机(步进电机),控制两个水泵,一个需要是从植物里面抽水到鱼缸,另外一个是供养氧作用, ...

  7. DS18B20读取温度并显示在数码管上

    下面是我的函数 分3个文件:头文件,DS18B20系列子函数文件,主函数部分(既数据处理和显示部分) 头文件 #ifndef __TEMP_H_ #define __TEMP_H_#include&l ...

  8. 51单片机~DS18B20温度传感器

    51单片机~DS18B20温度传感器 (一)简介说明: (二)接线: 1. 内部结构: 正温度前五位是0. 负温度前五位是1. 由LS,MS组成的四位十六进制数,和16位二进制数.(先MS后LS) 结 ...

  9. 51单片机 | DS18B20 温度传感器实验

    文章目录 一.DS18B20介绍 二.硬件设计 三.软件设计 1.数码管显示函数 2.DS18B20 初始化函数及温度读取函数 4.主函数 四.实验现象   这一节我们来学习精度较高的外部 DS18B ...

最新文章

  1. python 文字语音朗读-怎么用 Python 来朗读网页 ?
  2. Java技术在多数据库系统中的应用研究
  3. leetcode C++ 46. 全排列 给定一个 没有重复 数字的序列,返回其所有可能的全排列。
  4. java 双工模式_rabbitMq-工作模式(双工模式)-java
  5. 工厂方法设计模式示例
  6. Listview的OnScrollListener的滑动监听实现分页加载
  7. 小米裁员10%?官方回应:创业至今 从未裁员
  8. XP开通局域网共享(访问本机无需验证即可进入)
  9. java网络编程3 -- NIO一些简单说明
  10. Linux服务器安全之 fail2ban的安装与配置
  11. office for mac的字体设置
  12. 南京大学计算机考研复试名单,南大的考研复试名单能查出来吗?
  13. 基于双目摄像头测量距离
  14. linux考勤机密码,一种基于Linux操作系统的考勤机的制作方法
  15. 笔记本用HDMI转VGA转接线后,显示器没声音的解决方法
  16. 技术的理想该继续吗?
  17. r语言做绘制精美pcoa图_科学网—R语言 PCA PCoA ggplot2 - 靳泽星的博文
  18. 【python-docx 05】操作页眉和页脚
  19. jsp+ssm计算机毕业设计短视频文案创作平台系统【附源码】
  20. Facebook联合创始人Chris Hughes呼吁该公司进行分拆

热门文章

  1. calibre读书软件使用教程
  2. iphone 3gs 美版,6.1.3+降基带+越狱+解锁。成功分享(转)
  3. 【案例教程】ArcGIS在洪水普查、风险评估及区划中的实践技术
  4. 毕设 深度学习中文汉字识别
  5. 【面试】兼任IE低版本思路方案
  6. 1月第1周全球域名总量TOP20:中国亚军 涨幅缩小
  7. uva1611-Crane
  8. 如何用短信平台发送自定义短信?
  9. python 10进制和16进制转换
  10. js轮播最后一张跳到第一张的处理