STM32单片机编程入门实战:DS18B20温度传感器模块使用指南(附源码)

文章目录

  • 一.概要
  • 二.DS18B20主要性能参数
  • 三.DS18B20温度传感器内部框图
  • 四.DS18B20模块原理图
  • 五.DS18B20模块跟单片机板子接线和通讯时序
  • 1.单片机跟DS18B20连接示意图
  • 2.单片机跟DS18B20通讯流程与时序
  • 3.通讯流程中的9个数据字节内容格式
  • 4.温度数据寄存器LSB/MSB格式
  • 六.STM32单片机DS18B20温度传感器实验
  • 七.CubeMX工程源代码下载
  • 八.小结
  • 一.概要

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

    作者:光子物联单片机

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32单片机编程入门实战:DS18B20温度传感器模块使用指南(附源码)

    发表回复