STM8驱动温度传感器DS18B20

Posted Mount256

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM8驱动温度传感器DS18B20相关的知识,希望对你有一定的参考价值。


使用软件:IAR FOR STM8

编程方式:固件库

硬件配套:STM8S105K4T6最小系统板

这是我在做课设时摸索出来的代码,现记录如下:

1. DS18B20.h

#ifndef __DS18B20_H
#define __DS18B20_H

/***********DS18B20驱动***********/
/*****要用RESET判断*****/

#include "stm8s.h"
#include "delay.h"

/***********Definition***********/
#define RESPONSE_MAX_TIME_1  200
#define RESPONSE_MAX_TIME_2  240
#define DS18B20_DQ_PORT   (GPIOD)
#define DS18B20_DQ_PIN    (GPIO_PIN_4) /* PA4 */
#define DS18B20_DQ_OUT    GPIO_Init(DS18B20_DQ_PORT, DS18B20_DQ_PIN, GPIO_MODE_OUT_PP_HIGH_SLOW) 
#define DS18B20_DQ_IN     GPIO_Init(DS18B20_DQ_PORT, DS18B20_DQ_PIN, GPIO_MODE_IN_PU_NO_IT)
#define DS18B20_DQ_HIGH   GPIO_WriteHigh(DS18B20_DQ_PORT, DS18B20_DQ_PIN)
#define DS18B20_DQ_LOW    GPIO_WriteLow (DS18B20_DQ_PORT, DS18B20_DQ_PIN)
#define DS18B20_DQ_STATUS GPIO_ReadInputPin(DS18B20_DQ_PORT, DS18B20_DQ_PIN)

/***********Structure***********/
typedef struct 

  uint8_t intT;         /* 整数部分 */
  uint8_t decT;         /* 小数部分 */
  uint8_t sign;         /* 符号位,1表示负数,0表示非负数 */
  ErrorStatus flag;     /* 检测数据是否有效 */
TemperatureTypeDef;

/***********Function***********/
void DS18B20_Reset(void);               /* 向DS18B20发送复位信号 */
ErrorStatus DS18B20_Check(void);        /* 检测DS18B20存在脉冲 */
static BitStatus DS18B20_ReadBit(void);        /* 从DS18B20读一个位   */
static uint8_t DS18B20_ReadByte(void);         /* 从DS18B20读一个字节 */
static void DS18B20_WriteByte(uint8_t cmd);    /* 从DS18B20写一个字节 */
void DS18B20_GetTemperature(TemperatureTypeDef* Temperature);   /* 开始温度转换及获取温度数据 */

#endif /* __DS18B20_H */

2. DS18B20.c

#include "DS18B20.h"
#include "UART.h"

/******发送复位信号******/
void DS18B20_Reset(void)

  DS18B20_DQ_OUT;
  DS18B20_DQ_LOW;
  Delay_us(750);
  DS18B20_DQ_HIGH;
  Delay_us(15);


/******检测存在脉冲******/
ErrorStatus DS18B20_Check(void)

  uint8_t cnt = 0;
  
  DS18B20_DQ_IN;        /* 设置DQ管脚为输入模式 */
  /* 等待复位信号低电平 */ 
  while((DS18B20_DQ_STATUS != RESET) && (cnt < RESPONSE_MAX_TIME_1))  
  
    cnt++; 
    Delay_us(1);
  
  
  if(cnt >= RESPONSE_MAX_TIME_1)
    return ERROR;
  else
    cnt = 0;
  
  /* 再等待复位信号拉高,表示复位结束 */
  while((DS18B20_DQ_STATUS == RESET) && (cnt < RESPONSE_MAX_TIME_2))  
  
    cnt++; 
    Delay_us(1);
  
  
  if(cnt >= RESPONSE_MAX_TIME_2)
    return ERROR;
  else
    return SUCCESS;


/******从DS18B20读一个位******/
static BitStatus DS18B20_ReadBit(void)

  BitStatus data;
  
  DS18B20_DQ_OUT;
  DS18B20_DQ_LOW;
  Delay_us(2);
  DS18B20_DQ_HIGH;
  
  DS18B20_DQ_IN;
  Delay_us(12);       
  
  if(DS18B20_DQ_STATUS != RESET)   
    data = SET;              
  else 
    data = RESET;	   
  
  Delay_us(50);         
  return data;       


/******从DS18B20读一个字节******/
static uint8_t DS18B20_ReadByte(void)

  uint8_t t, data;
  uint8_t i;
  
  for(i = 0; i < 8; i++)
  
    t = DS18B20_ReadBit();
    data = (t << 7) | (data >> 1);
  
  return data;


/******从DS18B20写一个字节******/
void DS18B20_WriteByte(uint8_t cmd)

  uint8_t bit;
  uint8_t i;
  
  DS18B20_DQ_OUT;
  
  for(i = 0; i < 8; i++)
  
    bit = cmd & 0x01;
    if (bit == 1) 
    
      DS18B20_DQ_LOW;
      Delay_us(2);
      DS18B20_DQ_HIGH;
      Delay_us(60); 
    
    else   
    
       DS18B20_DQ_LOW;
       Delay_us(60);   
       DS18B20_DQ_HIGH;
       Delay_us(2);    
      
    cmd = cmd >> 1; /* 写下一位 */
  


/******采集温度数据******/
void DS18B20_GetTemperature(TemperatureTypeDef* Temperature)

  uint8_t data_L, data_H;
  uint16_t data;
  
  DS18B20_Reset();                      /* 发送复位脉冲 */
  Temperature->flag = DS18B20_Check();  /* 检测存在脉冲 */
  if(Temperature->flag == ERROR)
    return;
  DS18B20_WriteByte(0xCC);    /* 跳过ROM检测 */
  DS18B20_WriteByte(0x44);    /* 开始温度转换 */
    
  /* 等待温度采集完成 */
  //while(DS18B20_ReadByte() != 0xFF);  
     
  DS18B20_Reset();                      /* 发送复位脉冲 */
  Temperature->flag = DS18B20_Check();  /* 检测存在脉冲 */
  if(Temperature->flag == ERROR)
    return;
  DS18B20_WriteByte(0xCC);    /* 跳过ROM检测 */
  DS18B20_WriteByte(0xBE);    /* 读取温度 */
		
  data_L = DS18B20_ReadByte(); /* 读取数据低8位 */
  data_H = DS18B20_ReadByte(); /* 读取数据高8位 */
    
#ifdef __UART_H                /* 用于调试的输出数据 */
  printf("\\n\\rTEST DATA: %d %d\\n\\r", data_L, data_H);
#endif
    
  if(data_H > 7)
    Temperature->sign = 1;     /* 负数 */
  else     
    Temperature->sign = 0;     /* 正数 */
    
  data = data_L | (data_H<<8); 
  data = data & 0x07FF;       /* 清除高五位的符号位 0000 0111 1111 1111 */
      
  Temperature->intT = data >> 4;       /* 整数部分(中间七位) */        
  Temperature->decT = data & 0x0F;     /* 小数部分(低四位) */

3. delay.h

#ifndef __DELAY_H
#define __DELAY_H 

#include "stm8s.h"

void Delay_ms(uint16_t nCount);
void Delay_us(uint16_t nCount);

#endif /* __DELAY_H */

4. delay.c

#include "delay.h"

//ms级别延时
void Delay_ms(uint16_t nCount)

  while(nCount--)
  
    Delay_us(1000);
  


//us级别延时
void Delay_us(uint16_t nCount)

  nCount *= 2;
  while(--nCount);

5. main.c

#include "stm8s.h"
#include "UART.h"
#include "DS18b20.h"

void SystemInit_CLK(void);

void main(void)

  ErrorStatus flag_init;
  TemperatureTypeDef Temperature = 0, 0, 1, ERROR;
  
  SystemInit_CLK();
  UART2_Config();
  
  printf("\\n\\rUART2 Example: retarget the C library printf()/getchar() functions to the UART\\n\\r");
  printf("\\n\\rEnter Text\\n\\r");
  
  DS18B20_Reset();
  flag_init = DS18B20_Check();
  
  if(flag_init == ERROR)
  
    printf("\\n\\rInit ERROR! Please Reset!\\n\\r");
    while(1);
  
  else 
    printf("\\n\\rInit SUCCESS!\\n\\r");
  
  while(1)
  
    DS18B20_GetTemperature(&Temperature); 
    if(Temperature.flag == SUCCESS)
    
      if(Temperature.sign == 0)
        printf("\\n\\rTemp: +%d.%d C\\n\\r", Temperature.intT, Temperature.decT);
      else
        printf("\\n\\rTemp: -%d.%d C\\n\\r", Temperature.intT, Temperature.decT);
    
    else
      printf("\\n\\rTemperature: --.-- C\\n\\r");
    Delay_ms(1000);
  


void SystemInit_CLK(void)

  CLK_DeInit();
  CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); // 16MHz
  CLK_SYSCLKConfig(CLK_PRESCALER_HSIDIV1);
  CLK_HSICmd(ENABLE);


#ifdef USE_FULL_ASSERT
void assert_failed(u8* file, u32 line)
 
  while (1)
  
  

#endif

/****END OF FILE****/

以上是关于STM8驱动温度传感器DS18B20的主要内容,如果未能解决你的问题,请参考以下文章

ds18b20采集温度并上报服务器

温度传感器DS18B20

STM32入门开发: 编写DS18B20温度传感器驱动(读取环境温度支持级联)

STM32入门开发: 编写DS18B20温度传感器驱动(读取环境温度支持级联)

51单片机学习笔记

Linux驱动开发-编写DS18B20驱动