零基础国产GD32单片机编程入门(十七)DS18B20温度传感器模块实战含源码

一.概要

DS18B20是一款常用的高精度的单总线数字温度测量芯片,具有体积更小、适用电压更宽、更经济、可选更小的封装方式,更宽的电压适用范围,适合于构建自己的经济的测温系统,因此也就被设计者们所青睐。

单总线数字温度芯片,通讯线只有一根信号线就能实现数据通讯,这根信号线就能实现握手及信号发送与接收,再加上电源,地,总共三根线就能实现单片机跟温度传感器通讯,实现温度读取。
在这里插入图片描述

二.DS18B20主要性能参数

IC输出型:数字式
感应精度范围:± 0.5°C
温度检测范围:-55°C 到 +125°C
电源电流:1mA
电源电压范围:3V 到 5.5V
分辨率:12bit
封装类型:TO-92
针脚数:3

引脚定义:
DQ为数字信号输入/输出端
GND为电源地
VCC为外接供电电源输入端,电源供电 3.0~5.5V

在这里插入图片描述

三.DS18B20温度传感器内部框图

64位ROM存储了器件的唯一序列码。
暂存器包含了两个字节的温度寄存器,存储来自于温度传感器的数字输出。另外,暂存器提供了一高一低两个报警触发阈值寄存器(TH和TL)。配置寄存器允许用户设定温度数字转换的分辨率为9,10,11或12位。2个字节的用户可编程E2PROM是非易失性存储,器件掉电时数据不会失去。
DS18B20 使用单总线协议,总线通讯通过一根控制信号线实现。控制线需要一个弱上拉电阻这样所有的器件都通过DS18B20 的DQ引脚连接到总线上。在这个总线系统中,单片机(主机)通过每个器件的唯一64位编码识别并寻址总线上的器件。因为每个器件都有唯一的编码,实际上挂在总线上并可以被寻址的设备数量是无限的。
在这里插入图片描述

四.DS18B20模块原理图

在这里插入图片描述

五.DS18B20模块跟单片机板子接线和通讯时序

1.单片机跟DS18B20连接示意图

在这里插入图片描述

2.单片机跟DS18B20通讯流程与时序

在这里插入图片描述

单片机发复位指令及DS18B20发存在响应时序
在这里插入图片描述
单片机读写数据位时序
在这里插入图片描述

3.通讯流程中的9个数据字节内容格式

在这里插入图片描述

4.温度数据寄存器LSB/MSB格式

在这里插入图片描述

比如温度值是125度,按照上述格式存储,那LSB字节就是0xD0,MSB字节是0x07。
在这里插入图片描述

六.GD32单片机DS18B20温度传感器实验

硬件准备:

STLINK接GD32F103C8T6开发板,STLINK接电脑USB口。

用杜邦线把模块与开发板相连:
开发板3.3V <->模块VCC
开发板PA0脚 <->模块DQ
开发板GND <->模块GND
模块灯亮说明电源连接成功,插上OLED液晶
在这里插入图片描述

主要代码

/*****************************************************************************
  文件: main.c
  作者: Zhengyu https://gzwelink.taobao.com
  版本: V1.0.0
  时间: 202101201
  平台:MINI-GD32F103C8T6开发板
*******************************************************************************/
#include "gd32f10x.h"
#include "gd32f10x_libopt.h"
#include "systick.h"
#include "oled.h"
typedef unsigned char u8;
typedef unsigned long u32;
void Init18b20 (void);
void WriteByte (unsigned char wr);  //单字节写入
void read_bytes (unsigned char j);
unsigned char Temp_CRC (unsigned char j);
void GemTemp (void);
void Config18b20 (void);
void ReadID (void);
void TemperatuerResult(void);
void SystemClock_Config(void);
unsigned long Count;
//1us等待,108M主频
void Delay_us(unsigned long i)
{
	unsigned long j;
	for(;i>0;i--)
	{
			for(j=24;j>0;j--);
	}
}
unsigned char  flag;
unsigned int   Temperature;
unsigned char  temp_buff[9]; //存储读取的字节,read scratchpad为9字节,read rom ID为8字节
unsigned char  id_buff[8];
unsigned char  *p;
unsigned char  crc_data;



const unsigned char  CrcTable [256]={
0,  94, 188,  226,  97,  63,  221,  131,  194,  156,  126,  32,  163,  253,  31,  65,
157,  195,  33,  127,  252,  162,  64,  30,  95,  1,  227,  189,  62,  96,  130,  220,
35,  125,  159,  193,  66,  28,  254,  160,  225,  191,  93,  3,  128,  222,  60,  98,
190,  224,  2,  92,  223,  129,  99,  61,  124,  34,  192,  158,  29,  67,  161,  255,
70,  24,  250,  164,  39,  121,  155,  197,  132,  218,  56,  102,  229,  187,  89,  7,
219,  133, 103,  57,  186,  228,  6,  88,  25,  71,  165,  251,  120,  38,  196,  154,
101,  59, 217,  135,  4,  90,  184,  230,  167,  249,  27,  69,  198,  152,  122,  36,
248,  166, 68,  26,  153,  199,  37,  123,  58,  100,  134,  216,  91,  5,  231,  185,
140,  210, 48,  110,  237,  179,  81,  15,  78,  16,  242,  172,  47,  113,  147,  205,
17,  79,  173,  243,  112,  46,  204,  146,  211,  141,  111,  49,  178,  236,  14,  80,
175,  241, 19,  77,  206,  144,  114,  44,  109,  51,  209,  143,  12,  82,  176,  238,
50,  108,  142,  208,  83,  13,  239,  177,  240,  174,  76,  18,  145,  207,  45,  115,
202,  148, 118,  40,  171,  245,  23,  73,  8,  86,  180,  234,  105,  55,  213, 139,
87,  9,  235,  181,  54,  104,  138,  212,  149,  203,  41,  119,  244,  170,  72,  22,
233,  183,  85,  11,  136,  214,  52,  106,  43,  117,  151,  201,  74,  20,  246,  168,
116,  42,  200,  150,  21,  75,  169,  247,  182,  232,  10,  84,  215,  137,  107,  53}; 


/************************************************************
*Function:18B20初始化
*parameter:
*Return:
*Modify:
*************************************************************/
void Init18b20 (void)
{
	rcu_periph_clock_enable(RCU_GPIOA);
	gpio_init(GPIOA, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0);//PA0配置成输出
	gpio_bit_write(GPIOA, GPIO_PIN_0,SET);//PA0输出高
	Delay_us(2); //延时2微秒
 	gpio_bit_write(GPIOA, GPIO_PIN_0,RESET);//PA0输出低
	Delay_us(490);   //delay 530 uS//80
	 gpio_bit_write(GPIOA, GPIO_PIN_0,RESET);
	Delay_us(100);   //delay 100 uS//14
	if(gpio_input_bit_get(GPIOA ,GPIO_PIN_0)== 0)//判断PA0电平是否是低
		flag = 1;   //detect 1820 success!
	else
		flag = 0;    //detect 1820 fail!
	Delay_us(480);        //延时480微秒
	gpio_bit_write(GPIOA, GPIO_PIN_0,SET);
}

/************************************************************
*Function:向18B20写入一个字节
*parameter:
*Return:
*Modify:
*************************************************************/
void WriteByte (unsigned char  wr)  //单字节写入
{
	unsigned char  i;
	for (i=0;i<8;i++)
	{
	 	gpio_bit_write(GPIOA, GPIO_PIN_0,RESET);
    	Delay_us(2);
		if(wr&0x01)	 gpio_bit_write(GPIOA, GPIO_PIN_0,SET);
		else   gpio_bit_write(GPIOA, GPIO_PIN_0,RESET);
		Delay_us(45);   //delay 45 uS //5
		gpio_bit_write(GPIOA, GPIO_PIN_0,SET);
		wr >>= 1;
	}
}

/************************************************************
*Function:读18B20的一个字节
*parameter:
*Return:
*Modify:
*************************************************************/
unsigned char ReadByte (void)     //读取单字节
{
	unsigned char  i,u=0;
	for(i=0;i<8;i++)
	{		
		gpio_bit_write(GPIOA, GPIO_PIN_0,RESET);
		Delay_us (2);
		u >>= 1;
		gpio_bit_write(GPIOA, GPIO_PIN_0,SET);
		Delay_us (4);
		if(gpio_input_bit_get(GPIOA , GPIO_PIN_0) == 1)
		u |= 0x80;
		Delay_us (65);
	}
	return(u);
}

/************************************************************
*Function:读18B20
*parameter:
*Return:
*Modify:
*************************************************************/
void read_bytes (unsigned char  j)
{
	 unsigned char  i;
	 for(i=0;i<j;i++)
	 {
		  *p = ReadByte();
		  p++;
	 }
}

/************************************************************
*Function:CRC校验
*parameter:
*Return:
*Modify:
*************************************************************/
unsigned char Temp_CRC (unsigned char j)
{
   	unsigned char  i,crc_data=0;
  	for(i=0;i<j;i++)  //查表校验
    	crc_data = CrcTable[crc_data^temp_buff[i]];
    return (crc_data);
}

/************************************************************
*Function:读取温度
*parameter:
*Return:
*Modify:
*************************************************************/
void GemTemp (void)
{
   read_bytes (9);
   if (Temp_CRC(9)==0) //校验正确
   {
	  Temperature = temp_buff[1]*0x100 + temp_buff[0];
		Temperature /= 16;
		Delay_us(10);
    }
}

/************************************************************
*Function:内部配置
*parameter:
*Return:
*Modify:
*************************************************************/
void Config18b20 (void)  //重新配置报警限定值和分辨率
{
     Init18b20();
     WriteByte(0xcc);  //skip rom
     WriteByte(0x4e);  //write scratchpad
     WriteByte(0x19);  //上限
     WriteByte(0x1a);  //下限
     WriteByte(0x7f);     //set 12 bit (0.125)
     Init18b20();
     WriteByte(0xcc);  //skip rom
     WriteByte(0x48);  //保存设定值
     Init18b20();
     WriteByte(0xcc);  //skip rom
     WriteByte(0xb8);  //回调设定值
}

/************************************************************
*Function:读18B20ID
*parameter:
*Return:
*Modify:
*************************************************************/
void ReadID (void)//读取器件 id
{
	Init18b20();
	WriteByte(0x33);  //read rom
	read_bytes(8);
}

/************************************************************
*Function:18B20ID全处理
*parameter:
*Return:
*Modify:
*************************************************************/
void TemperatuerResult(void)
{
  	p = id_buff;
  	ReadID();
  	Config18b20();
	Init18b20 ();
	delay_1ms(20);
	WriteByte(0xcc);   //skip rom
	WriteByte(0x44);   //Temperature convert

	Init18b20 ();
	delay_1ms(20);
	WriteByte(0xcc);   //skip rom
	WriteByte(0xbe);   //read Temperature
	p = temp_buff;
	GemTemp();
}


void GetTemp(void)
{       
   if(Count == 2) //每隔一段时间读取温度
	{  
		 Count=0;
	   TemperatuerResult();
	}
	Count++;

}
uint32_t TimeCOunter;
int main(void)
{
	rcu_ahb_clock_config(RCU_AHB_CKSYS_DIV1);//AHB主频是1分频
	systick_config();//系统主频108MHZ,采用外部晶振,由两个宏决定(__SYSTEM_CLOCK_108M_PLL_HXTAL与HXTAL_VALUE)
	rcu_periph_clock_enable(RCU_AF);//管脚复用时钟alternate function clock使能 
	delay_1ms(1000);//等待1秒
	rcu_periph_clock_enable(RCU_GPIOB);//GPIOB时钟使能

	OLED_Init();//OLED初始化  
	OLED_Clear();//OLED清屏 
	GetTemp();//读取温度
	GetTemp();
	while(1) 
	{		
		GetTemp();//获取温度
		OLED_Clear();
		OLED_ShowCHinese(18,0,0);//光
		OLED_ShowCHinese(36,0,1);//子
		OLED_ShowCHinese(54,0,2);//物
		OLED_ShowCHinese(72,0,3);//联
		OLED_ShowCHinese(90,0,4);//网
		OLED_ShowString(6,3,"DS18B20 Test");
		OLED_ShowString(0,6,"Temperature:");  
		OLED_ShowNum(100,6,Temperature,3,16);//温度值,单位度	   
		delay_1ms(1000);
		
		

	}	 
 
}

七.工程源代码下载

通过网盘分享的文件:19.DS18B20温度传感器实验.zip
链接: https://pan.baidu.com/s/16_LUF35fDpInxMR7QxowJQ 提取码: 18c6
如果链接失效,可以联系博主给最新链接
程序下载下来之后解压就行

八.小结

DS18B20数字式温度传感器,与传统的热敏电阻有所不同的是,使用集成芯片,采用单总线技术,其能够有效的减小外界的干扰,提高测量的精度。同时,它可以直接将被测温度转化成串行数字信号供单片机处理,接口简单, 使数据传输和处理简单化。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值