1. 程式人生 > 其它 >STM8驅動溫度感測器DS18B20

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****/