//=========================DS18b20.h=========================//
/*-----------------------------------------------
DS18b20 驱动程序
------------------------------------------------*/
#ifndef __DS18B20_H
#define __DS18B20_H
typedef enum{FAILED = 0 ,PASSED = !FAILED} TestStatus ;
#define DQ_GPIO GPIOD
#define DQ_GPIO_Pin GPIO_Pin_5
//REGISTER COMMANDS
#define REGISTER_9_BITS 0x1F
#define REGISTER_10_BITS 0x3F
#define REGISTER_11_BITS 0x5F
#define REGISTER_12_BIT2 0x7F
//ROM COMMANDS
#define ROM_Search_Cmd
#define ROM_Read_Cmd
#define ROM_Match_Cmd
#define ROM_Skip_Cmd
#define ROM_AlarmSearch_Cmd 0xEC
0xF0
0x33
0x55
0xCC
//DS18b20 FUNCTION COMMANDS
#define Convert_T
0x44
#define Write_Scratchpad 0x4E
#define Read_Scratchpad
0xBE
#define Copy_Scratchpad
0x48
#define Recall_EEPROM 0x88
#define Read_PowerSupply 0x84
#define DQ_Write_1()
#define DQ_Write_0()
#define DQ_ReadBit()
GPIO_SetBits(DQ_GPIO ,DQ_GPIO_Pin)
//写 1
GPIO_ResetBits(DQ_GPIO ,DQ_GPIO_Pin)//写 0
GPIO_ReadInputDataBit(DQ_GPIO ,DQ_GPIO_Pin) //读 DQ 上的值
extern void GPIO_DQ_Out_Mode(void) ; //DQ 输出模式
extern void GPIO_DQ_Input_Mode(void) ;
//DQ 输入模式
//发送复位脉冲
extern void Tx_ResetPulse(void) ;
extern void Rx_PresencePulse(void) ; //接受应答信号
extern void Write_OneByte_ToDS18b20(unsigned char data) ; //写一个字节到 18b20
extern unsigned char Read_OneByte_FromDS18b20(void) ; //从 18b20 读一个字节
extern void Read_Temperature(unsigned char *sign ,unsigned char *interger ,
unsigned int *decimal) ; //读温度
//写配置参数 TH,TL 和初始化配置寄存器
extern void Write_EEPROM(unsigned char Th,unsigned char Tl,unsigned char Register_Con );
void DS18B20_Init(void) ; //初始化
#endif /*DS18B20*/
//=================================================================//
//=========================DS18b20.c================================//
#include "stm32f10x_lib.h"
#include "DS18b20.h"
#include "SysTick_Delay.h"
/******************************************
函数名称:GPIO_DQ_Out_Mode
功 能:设置 DQ 引脚为开漏输出模式
参 数:无
返回值 :无
*******************************************/
void GPIO_DQ_Out_Mode(void)
{
GPIO_InitTypeDef GPIO_InitStructure ;
GPIO_InitStructure.GPIO_Pin = DQ_GPIO_Pin ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD ; //开漏输出
GPIO_Init(DQ_GPIO ,&GPIO_InitStructure) ;
}
/******************************************
函数名称:GPIO_DQ_Input_Mode
功 能:设置 DQ 引脚为浮空输入模式
参 数:无
返回值 :无
*******************************************/
void GPIO_DQ_Input_Mode(void)
{
GPIO_InitTypeDef GPIO_InitStructure ;
GPIO_InitStructure.GPIO_Pin = DQ_GPIO_Pin ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING ; //浮空输入
GPIO_Init(DQ_GPIO ,&GPIO_InitStructure) ;
}
/******************************************
函数名称:Tx_ResetPulse
功 能:发送复位脉冲
参 数:无
返回值 :无
*******************************************/
void Tx_ResetPulse(void)
{
//复位脉冲
GPIO_DQ_Out_Mode() ;
DQ_Write_0() ;
Delay_Nus(500) ; //至少保持 480us
DQ_Write_1() ;
//加速上升沿速度
Delay_Nus(1) ;
}
/******************************************
函数名称:Rx_PresencePulse
功 能:接受应答信号
参 数:无
返回值 :无
*******************************************/
void Rx_PresencePulse(void)
{
GPIO_DQ_Input_Mode() ;
while( DQ_ReadBit()) ;
while( DQ_ReadBit() == 0) ; //DS18b20 将总线拉低 60~240us ,然后总线由上拉电阻拉高
Delay_Nus(300) ;
GPIO_DQ_Out_Mode() ;
//接受完成,主机重新控制总线
//等待 DS18b20 应答
}
/******************************************
函数名称:Write_OneByte_ToDS18b20
功 能:写一个字节到 DS18b20
参 数:无
返回值 :无
*******************************************/
void Write_OneByte_ToDS18b20(unsigned char data)
{
unsigned char i ;
GPIO_DQ_Out_Mode() ;
for(i=0 ;i<8 ;i++)
{
//低位在前
if(data&0x01)
{
//写 1
DQ_Write_0() ; //写时间空隙总是从总线的低电平开始
Delay_Nus(8) ;
DQ_Write_1() ;
Delay_Nus(80) ; //整个写 1 时隙不低于 60us
//15us 内拉高
}
else
{
//写 0
DQ_Write_0() ;
Delay_Nus(110) ; //保持在 60us 到 120us 之间
DQ_Write_1() ;
Delay_Nus(5) ;
}
data >>= 1 ;
}
}
/******************************************
函数名称:Read_OneByte_FromDS18b20
功 能:从 DS18b20 读一个字节
参 数:无
返回值 :读出的数据
*******************************************/
unsigned char Read_OneByte_FromDS18b20(void)
{
unsigned char i ,data = 0 ;
for(i=0 ;i<8 ;i++)
{
GPIO_DQ_Out_Mode() ;
data >>= 1 ;
DQ_Write_0() ;
Delay_Nus(2) ;
GPIO_DQ_Input_Mode() ;
Delay_Nus(1) ;
if(DQ_ReadBit())
{
data |= 0x80 ;
}
Delay_Nus(70) ;
//等待这一位数据完成传输
}
GPIO_DQ_Out_Mode() ;
return data ;
}
/******************************************
函数名称:Read_Temperature
功 能:读取温度信息
参 数:*sign - 保存符号(零上或零下)
*integer - 保存整数部分
*decimal - 保存小数部分
返回值 :无
*******************************************/
void Read_Temperature(unsigned char *sign ,
unsigned char *interger ,
unsigned int *decimal)
{
unsigned char a=0;
unsigned char b=0;
//volatile unsigned char c=0;
//volatile unsigned char d=0;
//volatile unsigned char e=0;
unsigned int tmp ;
DS18B20_Init();
Write_OneByte_ToDS18b20(ROM_Read_Cmd);
DS18B20_Init();
Write_OneByte_ToDS18b20(ROM_Skip_Cmd);//跳过读序列号操作
Write_OneByte_ToDS18b20(Convert_T); //启动温度转换
Delay_Nms(780);//等待 DS18b20 转换完成
DS18B20_Init();
Write_OneByte_ToDS18b20(ROM_Skip_Cmd);
Write_OneByte_ToDS18b20(Read_Scratchpad); //读取寄存器内容(可以从寄存器 0 读到寄
存器 8)
a= Read_OneByte_FromDS18b20();
b= Read_OneByte_FromDS18b20();
//c= Read_OneByte_FromDS18B20();
//d= Read_OneByte_FromDS18B20();
//e= Read_OneByte_FromDS18B20();
//温度低 8 位
//温度高 8 位
//TH
//TL
//Configuration Register
Tx_ResetPulse();
tmp = (b<<8) | a ;
if(b & 0xF0)
{
*sign = 1 ;
//中断数据读取
//符号部分
tmp = ~tmp+1 ;
}
else
{
sign = 0 ;
}
//整数部分
*interger = (tmp>>4) & 0x00FF;
*decimal = (tmp & 0x000F) * 625 ; //小数部分
}
/******************************************
函数名称:Write_EEPROM
功 能:写配置参数
参 数:Th - 报警温度上限
Tl - 报警温度下限
Register_Con - 控制寄存器的值
返回值 :读出的数据
*******************************************/
void Write_EEPROM(unsigned char Th,unsigned char Tl,unsigned char Register_Con )
{
DS18B20_Init();
Write_OneByte_ToDS18b20(ROM_Skip_Cmd);
Write_OneByte_ToDS18b20(Write_Scratchpad);
Write_OneByte_ToDS18b20(Th);//Th=7F
Write_OneByte_ToDS18b20(Tl);//Tl=FF 最高位符号位
Write_OneByte_ToDS18b20(Register_Con);//12 位模式
Delay_Nms(700);
DS18B20_Init();
Write_OneByte_ToDS18b20(ROM_Skip_Cmd);
Write_OneByte_ToDS18b20(Copy_Scratchpad);//将寄存器的配置值写入 EEPROM
Delay_Nms(300);
}
/******************************************
函数名称:DS18B20_Init
功 能:初始化 DS18b20
参 数:无
返回值 :无
*******************************************/
void DS18B20_Init(void)
{
}
Tx_ResetPulse();
Rx_PresencePulse();
//=================================================================//
//========================要用到的其他文件============================//
//===========================Systick_Delay.h==========================//
/*--------------------------------------------------
利用 SysTick 进行精确定时
---------------------------------------------------*/
#ifndef __SYSTICKDELAY_H
#define __SYSTICKDELAY_H
#include "stm32f10x_lib.h"
extern void Delay_Nms(u16 Nms);
extern void Delay_Nus(u32 Nus);
#endif
/*SYSTICKDELAY_H*/
//=================================================================//
//=========================Systick_Delay.c============================//
#include "stm32f10x_lib.h"
#include "SysTick_Delay.h"
//延时 Nms
//注意 Nms 的范围
//Nms<=0xffffff*8/SYSCLK
//对 72M 条件下,Nms<=1864
void Delay_Nms(u16 Nms)
{
SysTick->LOAD=(u32)Nms*9000; //给重装载寄存器赋值,9000 时,将产生 1ms 的时基
SysTick->CTRL|=0x01;
while(!(SysTick->CTRL&(1<<16)));
SysTick->CTRL=0X00000000;
SysTick->VAL=0X00000000;
//等待时间到达
//关闭计数器
//清空计数器
//开始倒数
}
//延时 us
void Delay_Nus(u32 Nus)
{
SysTick->LOAD=Nus*9;
SysTick->CTRL|=0x01;
//时间加载
//开始倒数
while(!(SysTick->CTRL&(1<<16)));//等待时间到达
SysTick->CTRL=0X00000000;
SysTick->VAL=0X00000000;
//关闭计数器
//清空计数器
}
//=================================================================//
/* 写得一般,希望大家能给点建议! */