STM8驅動溫度感測器DS18B20
阿新 • • 發佈:2021-12-21
目錄
使用軟體: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****/