【模块系列】STM32&&DS18B20

前言

  网上的DS18B20模块的代码,挺杂乱的。我就自己整理,注释修改了下,也验证过可以用了。不过,我调着调着发现代码中,引脚只用规定输出模式就行了,加了切换输入模式还会出错(阻碍时序),不管了,能用就行。还有就是,DS18B20_Init函数用来检测DS18B20器件是否存在,没有什么有,有时候拔了还显示检测到了。不过上述这些,都不妨碍,代码能正确获取温度参数。完整的例程工程链接放在末尾,文中会粘贴出DS18B20的库文件。

环境

  • 开发板:STM32C6T6最小系统板
  • 案例的代码环境:Keil5+标准库,OLED(4P)+DS18B20
  • 案例接线:模块器件的VCC接到3.3V。DS18B20的DQ口接PA0。OLED的SCL,SDA分别接PB8,PB9。

代码

代码部分就粘贴出DS18B20的C文件和H文件。一些事项和说明,我也在文件中说了。

DS18B20.H

#ifndef   __DS18B20_H
#define   __DS18B20_H
#include "stm32f10x.h"
#include "delay.h"

/*****/
//转移到同类单片机注意事项
//1.重写延时函数  2.重写引脚控制  3.重写数据引脚模式切换,包括修改对应引脚的时钟使能  4.导入替换对于的单片机头文件
//还有就是DS18B20获取数据要有一定的时间间隔
/*****/

//重写延时函数
#define DS18B20_DelayUs(us)	Delay_us(us)
#define DS18B20_DelayMs(ms)	Delay_ms(ms)
//数据引脚控制
#define DS18B20_DQ_OUT_Low GPIO_ResetBits(GPIOA,GPIO_Pin_0)  	//数据端口	PA0 输出低电平
#define DS18B20_DQ_OUT_High GPIO_SetBits(GPIOA,GPIO_Pin_0)  	//数据端口	PA0 输出高电平
#define DS18B20_DQ_IN GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)   //数据端口	PA0 读取

//#define u8 unsigned char
//#define u16 unsigned short
//#define u32 unsigned int
	
//数据引脚模式切换
void DS18B20_DataPin_In(void);
void DS18B20_DataPin_Out(void);
//DS18B20配置函数
int DS18B20_Init(void);
unsigned char DS18B20_Read(void);
void DS18B20_Write(unsigned char temp2);
unsigned char DS18B20_ReadData(void);
 
#endif

DS18B20.C

#include "DS18B20.h"
#include "stm32f10x.h"                  

unsigned char DS18B20_TempInt;	//整数部分
unsigned char DS18B20_TempFlo;	//小数部分

//数据引脚配置为输入模式
void DS18B20_DataPin_In()
{
 	GPIO_InitTypeDef   GPIO_Init_Structure;
	GPIO_Init_Structure.GPIO_Pin=GPIO_Pin_0;
	GPIO_Init_Structure.GPIO_Speed=GPIO_Speed_50MHz;
 	GPIO_Init_Structure.GPIO_Mode= GPIO_Mode_IN_FLOATING;
	GPIO_Init( GPIOA,  &GPIO_Init_Structure);
}

//数据引脚配置为输出模式
void DS18B20_DataPin_Out()
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
 	GPIO_InitTypeDef   GPIO_Init_Structure;
	GPIO_Init_Structure.GPIO_Pin=GPIO_Pin_0;
	GPIO_Init_Structure.GPIO_Speed=GPIO_Speed_50MHz;
 	GPIO_Init_Structure.GPIO_Mode= GPIO_Mode_Out_OD;
	GPIO_Init( GPIOA,  &GPIO_Init_Structure);
}

//DS18B20初始化
//返回值: 0.响应  1.无响应
int DS18B20_Init(void)
{
	int temp;
	DS18B20_DataPin_Out();
	DS18B20_DQ_OUT_High;
	DS18B20_DelayUs(10);
	DS18B20_DQ_OUT_Low;
	DS18B20_DelayUs(700);
	DS18B20_DQ_OUT_High;
	//DS18B20_DataPin_In();
	DS18B20_DelayUs(45);
	temp=DS18B20_DQ_IN;
	DS18B20_DelayUs(120);
	return (temp);
}

//读字节控制
unsigned char DS18B20_Read()
{
	unsigned char temp1,n;
	for(n=0;n<8;n++)
	{
		DS18B20_DQ_OUT_High;
		DS18B20_DelayUs(10);
		DS18B20_DQ_OUT_Low;
		DS18B20_DelayUs(1);
		DS18B20_DQ_OUT_High;
		DS18B20_DelayUs(10);
		temp1>>=1;
		if(DS18B20_DQ_IN==1)
		{
			temp1|=0x80;
		}
		else
		{
			temp1|=0x00;
		}
		DS18B20_DelayUs(10);
	}
	return(temp1);
}

//写字节控制
void DS18B20_Write(unsigned char temp2)
{
	unsigned char n;
	for(n=0;n<8;n++)
	{
		DS18B20_DQ_OUT_High;
		DS18B20_DelayUs(1);
		DS18B20_DQ_OUT_Low;
		if(temp2&0x01)
		{
			DS18B20_DQ_OUT_High;
		}
		else
		{
			DS18B20_DQ_OUT_Low;
		}
		
		DS18B20_DelayUs(60);
		DS18B20_DQ_OUT_High;
		DS18B20_DelayUs(1);
		temp2>>=1;
	}
	DS18B20_DelayUs(10);
}


//读取温度数值
/*函数说明:
*	函数里可以看到小数部分的数值是没有返回的,
*这么写是为了让全部的数据处理流程都在这里面,如
*果对小数部分有需求的可以重写该函数。
*/
unsigned char DS18B20_ReadData()
{
	unsigned char TempH,TempL;
	DS18B20_Init();
	DS18B20_Write(0xcc);
	DS18B20_Write(0x44);
	DS18B20_DelayMs(200);
	DS18B20_Init();
	DS18B20_Write(0xcc);
	DS18B20_Write(0xbe);
	//获取数据高低位
	TempL=DS18B20_Read();
	TempH=DS18B20_Read();
	//数据处理
	DS18B20_TempInt=TempH*16+TempL/16;	//整数部分
	DS18B20_TempFlo=(TempL%16)*10/16;	//小数部分
	return DS18B20_TempInt;
}

现象

【模块系列】STM32&&DS18B20_第1张图片

工程

链接:https://pan.baidu.com/s/1G7EOz9h4ljNz7CqYk6MxJg 提取码:8cyk

你可能感兴趣的:(模块系列,stm32,单片机,嵌入式硬件,mcu,笔记)