零基础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驱动文件

添加温度传感器相关代码

主要代码

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

相关推荐
蓝斯49714 小时前
从.到实现一个Windows上的虚拟hid键盘设备
windows·单片机·计算机外设
熙芯XiChip15 小时前
硬实时与软实时RTOS核心区别
嵌入式硬件
伟大的前程15 小时前
unsigned int 定义的变量 在 电脑的 64 位系统中 和 32 位 cortex-m0 和 8 位的 51 单片机
单片机·嵌入式硬件
小渔村的拉线工15 小时前
1.HPM6E80 解析芯片整体工作原理和存储架构
单片机·嵌入式硬件·mcu·架构·hpm6e80
熙芯XiChip16 小时前
CAN与CANopen的本质区别
单片机
lilihewo16 小时前
Altium Designer 封装库的创建(分享pcb 3D封装库)
嵌入式硬件·51单片机
神罚天下ET17 小时前
典型arm位单片机启动流程(从上电到main.c)
c语言·arm开发·单片机
碧海银沙音频科技研究院18 小时前
蓝牙耳机使用WSDF5361锂保芯片进入船运模式实现方法
嵌入式硬件·算法
Zevalin爱灰灰19 小时前
模拟信号链电路——基于TL431的电压基准电路
单片机·嵌入式硬件
csdn杰哥19 小时前
瑞萨单片机开发教程[二十七] DTC 外部中断触发传输实验
单片机·嵌入式硬件·mongodb·瑞萨·ra6m5