DS18B20使用注意事项

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/YYGY731793898/article/details/79359328

                                        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();
}


























































 

猜你喜欢

转载自blog.csdn.net/YYGY731793898/article/details/79359328