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