DS18B20在STM32F103RC的应用

前言

DS18B20是一个温度传感器模块,关于其配置原理可参见这篇文章:

https://blog.csdn.net/weixin_45419341/article/details/124210290

本人使用的单片机型号为STM32F103RC,语言为C语言,代码是由DS18B20的卖家给的适用于51单片机的代码修改而来。本人在stm32上使用DS18B20的目的仅为完成学校任务,只针对了一个DS18B20的情况,并且未针对温度为负值的情况进行改编。本人水平一般,代码仅供参考。

代码

ds18b20.c

/*
 * DS18B20测试程序
 * 
 * 用途:数码管模块测试程序
 * 
 * 原作者					日期				备注
 * Huafeng Lin			2012/04/21			新增
 * Huafeng Lin			2012/04/21			修改
 * 
 * 改编:shuangyueniao
 */
#include "stm32f10x_conf.h"
#include "stm32f10x_gpio.h"
#include "DataType.h"
#include "ds18b20.h"

static u8 DQ; 				//数据传输线接单片机的相应的引脚为PC6 
unsigned char tempL=0; 		//设全局变量
unsigned char tempH=0; 
//static u8 fg=1;        	//温度正负标志

void ConfigDQ(u8 mode)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	if(mode == 0)
	{
		//配置PC6
		GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_6;           //设置引脚
		GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;        //设置上拉输入类型
		GPIO_Init(GPIOC, &GPIO_InitStructure);                //根据参数初始化GPIO
	}
	else if(mode == 1)
	{
		//配置PC6
		GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_6;           //设置引脚
		GPIO_InitStructure.GPIO_Speed   =GPIO_Speed_50MHz;
		GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;     //设置推挽输出类型
		GPIO_Init(GPIOC, &GPIO_InitStructure);                //根据参数初始化GPIO
	}
}
void Init_DS18B20(void) 
{
//	unsigned char x=1;
	ConfigDQ(1); 					                //将PC6切换成推挽输出模式
	GPIO_WriteBit(GPIOC, GPIO_Pin_6, Bit_SET);		//DQ先置高 
	Delay_us(10); 				                    //稍延时
	GPIO_WriteBit(GPIOC, GPIO_Pin_6, Bit_RESET); 	//发送复位脉冲
	Delay_us(600); 				                    //延时(>480us) 
	GPIO_WriteBit(GPIOC, GPIO_Pin_6, Bit_SET); 		//拉高数据线 
	Delay_us(50); 				                    //等待(15~60us)
	ConfigDQ(0);
	DQ=GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_6);	//读PC6
//	x=DQ; 					                        //用X的值来判断初始化有没有成功,18B20存在的话X=0,否则X=1
	Delay_us(500); 
}

//读一个字节
unsigned char ReadOneChar(void)  	//主机数据线先从高拉至低电平1us以上,再使数据线升为高电平,从而产生读信号
{
	unsigned char i=0; 		        //每个读周期最短的持续时间为60us,各个读周期之间必须有1us以上的高电平恢复期
	unsigned char dat=0; 
	for (i=8;i>0;i--) 		        //一个字节有8位 
	{
		ConfigDQ(1);
		GPIO_WriteBit(GPIOC, GPIO_Pin_6, Bit_RESET); 	//拉低数据线
		dat>>=1;
		Delay_us(1);
		GPIO_WriteBit(GPIOC, GPIO_Pin_6, Bit_SET); 		//拉高数据线
		Delay_us(10);
		ConfigDQ(0);
		DQ=GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_6);	//读PC6
		if(DQ)
		dat|=0x80; 
		Delay_us(45);
	} 
	return(dat);
}

//写一个字节
void WriteOneChar(unsigned char dat) 
{ 
	unsigned char i=0; 		//数据线从高电平拉至低电平,产生写起始信号。15us之内将所需写的位送到数据线上,
	ConfigDQ(1);
	for(i=8;i>0;i--) 		//在15~60us之间对数据线进行采样,如果是高电平就写1,低写0发生。 
	{
		//在开始另一个写周期前必须有1us以上的高电平恢复期。 
		GPIO_WriteBit(GPIOC, GPIO_Pin_6, Bit_RESET); 			//拉低数据线
		Delay_us(15);
		DQ=dat&0x01;
		if(DQ==1){
			GPIO_WriteBit(GPIOC, GPIO_Pin_6, Bit_SET); 			//拉高数据线
		}
		else if(DQ==0){
			GPIO_WriteBit(GPIOC, GPIO_Pin_6, Bit_RESET); 		//拉低数据线
		}
		Delay_us(60); 
		GPIO_WriteBit(GPIOC, GPIO_Pin_6, Bit_SET); 				//拉高数据线
		dat>>=1;
	} 
	Delay_us(10);
	GPIO_WriteBit(GPIOC, GPIO_Pin_6, Bit_SET); 					//拉高数据线
}

//读温度值(低位放tempL;高位放tempH;)
void ReadTemperature(u32 *sdata, u8 *xiaoshu, u8 *xiaoshu1, u8 *xiaoshu2)
{ 
	Init_DS18B20(); 					    //初始化
	WriteOneChar(0xcc); 				    //跳过读序列号的操作
	WriteOneChar(0x44); 				    //启动温度转换
	Delay_us(5000); 					    //转换需要一点时间,延时 
	Init_DS18B20(); 					    //初始化
	WriteOneChar(0xcc); 				    //跳过读序列号的操作 
	WriteOneChar(0xbe); 				    //读温度寄存器(头两个值分别为温度的低位和高位) 
	tempL=ReadOneChar(); 				    //读出温度的低位LSB
	tempH=ReadOneChar(); 				    //读出温度的高位MSB	
	if(tempH>0x7f)      				    //最高位为1时温度是负
	{
		tempL=~tempL;					    //补码转换,取反加一
		tempH=~tempH+1;       
//		fg=0;      						    //读取温度为负时fg=0
	}
	*sdata = tempL/16+tempH*16;      	    //整数部分
	*xiaoshu1 = (tempL&0x0f)*10/16; 	    //小数第一位
	*xiaoshu2 = (tempL&0x0f)*100/16%10;    	//小数第二位
	*xiaoshu=(*xiaoshu1)*10+(*xiaoshu2);    //小数两位
}

ds18b20.h

#ifndef __DS18B20_H
#define __DS18B20_H
 
#include "stm32f10x.h"
#include "stm32f10x_conf.h"
#include "stm32f10x_gpio.h"
#include "delay.h"
#include "DataType.h"
 
void ConfigDQ(u8 mode);	//配置PC6
void Init_DS18B20(void);	//初始化ds18b20
unsigned char ReadOneChar(void);	//读一个字节
void WriteOneChar(unsigned char dat);	//写一个字节
void ReadTemperature(u32 *sdata, u8 *xiaoshu, u8 *xiaoshu1, u8 *xiaoshu2);	//读温度值
#endif

DataType.h

/*********************************************************************************************************
* 模块名称:DataType.h
* 摘    要:数据类型定义
* 当前版本:1.0.0
* 作    者:SZLY(COPYRIGHT 2018 - 2020 SZLY. All rights reserved.)
* 完成日期:2020年01月01日 
* 内    容:
* 注    意:                                                                  
**********************************************************************************************************
* 取代版本:
* 作    者:
* 完成日期: 
* 修改内容: 
* 修改文件:
*********************************************************************************************************/
#ifndef _DATA_TYPE_H_
#define _DATA_TYPE_H_

/*********************************************************************************************************
*                                              包含头文件
*********************************************************************************************************/

/*********************************************************************************************************
*                                              宏定义
*********************************************************************************************************/
typedef signed char         i8;
typedef signed short        i16;
typedef signed int          i32;
typedef unsigned char       u8;
typedef unsigned short      u16;
typedef unsigned int        u32;

typedef int                 BOOL;
typedef unsigned char       BYTE;
typedef unsigned short      HWORD;  //两个字节组成一个半字
typedef unsigned int        WORD;   //四个字节组成一个字
typedef long                LONG;

#define LOHWORD(w)          ((HWORD)(w))                            //字的低半字 
#define HIHWORD(w)          ((HWORD)(((WORD)(w) >> 16) & 0xFFFF))   //字的高半字

#define LOBYTE(hw)          ((BYTE)(hw) )                           //半字的低字节
#define HIBYTE(hw)          ((BYTE)(((WORD)(hw) >> 8) & 0xFF))      //半字的高字节

//两个字节组成一个半字
#define MAKEHWORD(bH, bL)   ((HWORD)(((BYTE)(bL)) | ((HWORD)((BYTE)(bH))) << 8))

//两个半字组成一个字
#define MAKEWORD(hwH, hwL)  ((WORD)(((HWORD)(hwL)) | ((WORD)((HWORD)(hwH))) << 16))

#define TRUE          1
#define FALSE         0
#define NULL          0
#define INVALID_DATA  -100

/*********************************************************************************************************
*                                              枚举结构体定义
*********************************************************************************************************/

/*********************************************************************************************************
*                                              API函数声明
*********************************************************************************************************/

#endif

  • 12
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值