使用软件:IAR FOR STM8

编程方式:固件库

硬件配套:STM8S105K4T6最小系统板

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

1. DS18B20.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#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

1
2
3
4
5
6
7
8
9
#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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#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****/