-
Notifications
You must be signed in to change notification settings - Fork 3
/
ds18b20.c
149 lines (143 loc) · 3.33 KB
/
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
/* github.com/jinzhifeng */
/* QQ : 356290462 */
/* jin-zhifeng@hotmail.com */
#include "ds18b20.h"
DS18B20_CheckState DS18B20_Init(void)
/**
* \brief Init Ds18b20 初始化
*
* \param None
*
* \retval AckFlag
*/
{
DS18B20_CheckState AckFlag;
DS18B20_DQ_SET(); //释放总线为高电平初始态
DS18B20_DelayXus(100);
DS18B20_DQ_CLR(); //拉低总线
DS18B20_DelayXus(500); //精确延时,维持至少480us
DS18B20_DQ_SET(); //释放总线
DS18B20_DelayXus(50); //等待15-60us后,检测ds18b20是否发出的60-240us低电平存在脉冲
if(ReadPin_DS18B20_DQ() == GPIO_PIN_RESET) //读DS18B20是否发出低电平存在脉冲
{
AckFlag = DS18B20_Exist;
// printf("检测到DS18B20温度传感器...\r\n");
}
else
{
AckFlag = DS18B20_NotExist;
printf("未检测到DS18B20温度传感器...请检查线路!\r\n");
}
DS18B20_DelayXus(100);
return AckFlag;
}
uint8_t DS18B20_ReadOneByte(void)
/**
* \brief 主机向Ds18b20读1个字节的数据
*
* \param None
*
* \retval RdData
*/
{
uint8_t i, ReadData = 0; //必须将默认值设为0,否则需要加ReadData &= 0x7F;
for(i = 0; i < 8; i++)
{
DS18B20_DQ_CLR(); //拉低总线
DS18B20_DelayXus(1);
DS18B20_DQ_SET(); //释放总线
ReadData >>= 1; //准备下一位
if(ReadPin_DS18B20_DQ())
ReadData |= 0x80;
else
ReadData &= 0x7F;
DS18B20_DelayXus(65);
DS18B20_DQ_SET(); //释放总线
}
return ReadData;
}
void DS18B20_WriteOneByte(uint8_t WriteByte)
/**
* \brief 主机向Ds18b20写1个字节的数据
*
* \param WriteByte
*
* \retval None
*/
{
uint8_t i;
for(i = 0; i < 8; i++)
{
DS18B20_DQ_CLR(); //拉低总线
if(WriteByte & 0x01)
DS18B20_DQ_SET(); //释放总线
else
DS18B20_DQ_CLR(); //拉低总线
DS18B20_DelayXus(65);
DS18B20_DQ_SET(); //释放总线
WriteByte >>= 1; //准备下一位
}
}
float Get_DS18B20_Temperature(void)
/**
* \brief 主机向Ds18b20读温度值
*
* \param None
*
* \retval Temperature
*/
{
uint8_t TL;
uint16_t TH;
float Temperature;
DS18B20_Init();
DS18B20_WriteOneByte(SKIP_ROM); //跳过读序列号的操作
DS18B20_WriteOneByte(CONVERT_T); //启动温度转换
DS18B20_DelayXus(20);
DS18B20_Init();
DS18B20_WriteOneByte(SKIP_ROM); //跳过读序列号的操作
DS18B20_WriteOneByte(READ_SCRATCHPAD); //读温度寄存器,共9个byte,前两个byte为温度值
TL = DS18B20_ReadOneByte(); //TL存低字节
TH = DS18B20_ReadOneByte(); //TH存高字节
// TH <<= 4;
// TH += (TL & 0xF0) >> 4;
// Temperature = TH;
TH <<= 8;
TH |= TL;
Temperature = TH * 0.0625;
return Temperature;
}
volatile void DS18B20_DelayXus(uint32_t DelayXus)
/**
* \brief 延时子程序,延时DelayXus微秒
*
* \param DelayXus
*
* \retval None
*/
{
uint32_t dwCurCounter = 0;
uint32_t dwPreTickVal = SysTick->VAL;
uint32_t dwCurTickVal;
DelayXus = DelayXus * (HAL_RCC_GetHCLKFreq() / 1000000);
for(;;)
{
dwCurTickVal = SysTick -> VAL;
if(dwCurTickVal < dwPreTickVal)
{
dwCurCounter = dwCurCounter + dwPreTickVal - dwCurTickVal;
}
else
{
dwCurCounter = dwCurCounter + dwPreTickVal + SysTick->LOAD - dwCurTickVal;
}
dwPreTickVal = dwCurTickVal;
if(dwCurCounter >= DelayXus)
{
return;
}
}
}
/* github.com/jinzhifeng */
/* QQ : 356290462 */
/* jin-zhifeng@hotmail.com */