Bootstrap

零基础STM32单片机编程入门(十四) 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。
在这里插入图片描述

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

硬件准备:

STLINK接STM32F103C8T6小系统板,STLINK接电脑USB口。

板子与OLED用杜邦线连接:
板子G----液晶GND
板子3.3–液晶VCC
板子B10—液晶SCL
板子B11—液晶SDA

用杜邦线把模块与开发板相连:
板子3.3----模块VCC
板子A0-----模块DQ
板子G------模块GND

打开STM32CubeMX软件,新建工程
在这里插入图片描述
Part Number处输入STM32F103C8,再双击就创建新的工程
在这里插入图片描述
配置下载口引脚
在这里插入图片描述
配置外部晶振引脚
在这里插入图片描述
配置系统主频
在这里插入图片描述
配置PA0为输入,因为模块内部有上拉电阻,所以不需要配上拉
在这里插入图片描述

配置工程文件名,保存路径,KEIL5工程输出方式
在这里插入图片描述
生成工程
在这里插入图片描述
用Keil5打开工程
在这里插入图片描述

添加OLED驱动文件
在这里插入图片描述

添加温度传感器相关代码
在这里插入图片描述
在这里插入图片描述

主要代码

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);//计算CRC
void GemTemp (void);//获取温度
void Config18b20 (void);//配置18B20
void ReadID (void);//读取ID
void TemperatuerResult(void);
void SystemClock_Config(void);
unsigned long Count;
//等待us级
void Delay_us(unsigned long i)
{
	unsigned long j;
	for(;i>0;i--)
	{
			for(j=12;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;


//CRC表格
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)
{

	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0,GPIO_PIN_SET);
	Delay_us(2); //延时2微秒
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0,GPIO_PIN_RESET);
	Delay_us(490);   //delay 530 uS//80
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0,GPIO_PIN_RESET);
	Delay_us(100);   //delay 100 uS//14
	if(HAL_GPIO_ReadPin(GPIOA ,GPIO_PIN_0)== 0)
		flag = 1;   //detect 1820 success!
	else
		flag = 0;    //detect 1820 fail!
	Delay_us(480);        //延时480微秒
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0,GPIO_PIN_SET);
}

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

/************************************************************
*Function:读18B20的一个字节
*parameter:
*Return:
*Modify:
*************************************************************/
unsigned char ReadByte (void)     //读取单字节
{
	unsigned char  i,u=0;
	for(i=0;i<8;i++)
	{		
		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0,GPIO_PIN_RESET);
		Delay_us (2);
		u >>= 1;
	
		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0,GPIO_PIN_SET);
		Delay_us (4);
		if(HAL_GPIO_ReadPin(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:18B20读温度流程
*parameter:
*Return:
*Modify:
*************************************************************/
void TemperatuerResult(void)
{
  	p = id_buff;
  	ReadID();
  	Config18b20();
	Init18b20 ();
	HAL_Delay(20);
	WriteByte(0xcc);   //skip rom
	WriteByte(0x44);   //Temperature convert

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


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

}

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();//8M外部晶振,72M主频

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
	MX_GPIO_Init();
  /* USER CODE BEGIN 2 */
	OLED_Init();//OLED初始化  
	OLED_Clear();//清屏
	GetTemp();               //获取温度
	GetTemp();               //再次获取温度
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	GetTemp();               //再次获取温度
	OLED_Clear();            //OLED清屏  
	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);//显示温度	   
	HAL_Delay(1000);//等待1S
  }
  /* USER CODE END 3 */
}

七.CubeMX工程源代码下载

链接:https://pan.baidu.com/s/1XQyG-EprZrgUbiQpUxmQug
提取码:yk9n
如果链接失效,可以联系博主给最新链接
程序下载下来之后解压就行

八.小结

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

;