-
Notifications
You must be signed in to change notification settings - Fork 3
/
ds18b20_1t.c
204 lines (170 loc) · 4.21 KB
/
ds18b20_1t.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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
/**************************************
*
* 温度传感器DS18B20测试程序
* 主芯片 : STC11F04E(1T)
* 工作频率: 5.66MHz
*
**************************************/
#include "ds18b20.h"
//---------------------------------------------------------------
// 延时时间
#ifdef STC11F04E
// 22 = 64us 24 = 70us
#define US60 24
#else
#define US60 60
#endif
#define US240 (4*US60)
#define US180 (3*US60)
//---------------------------------------------------------------
// 检测并启动DS18B20转换
// 返回0: 存在并已经启动
// 1: 不存在DS18B20
__bit StartDS18B20()
{
if (DS18B20_Reset() == 0) {
DS18B20_WriteByte(0xCC); //跳过ROM命令
DS18B20_WriteByte(0x44); //开始转换命令
} else {
return 1;
}
return 0;
}
// 读取测温值
void ReadTemp(BYTE *rom)
{
int i;
while (!DQ); //等待转换完成
DS18B20_Reset(); //设备复位
if (rom == 0) {
DS18B20_WriteByte(0xCC); //跳过ROM命令
} else {
DS18B20_WriteByte(0x55); // match rom
for (i=0;i<8;i++) {
DS18B20_WriteByte(rom[i]);
}
}
DS18B20_WriteByte(0xBE); //读暂存存储器命令
TPL = DS18B20_ReadByte(); //读温度低字节
TPH = DS18B20_ReadByte(); //读温度高字节
}
//---------------------- 工具函数 -------------------------
/**************************************
延时X微秒(STC12C5A60S2@12M)
不同的工作环境,需要调整此函数
此延时函数是使用1T的指令周期进行计算,与传统的12T的MCU不同
**************************************/
void DelayXus(BYTE n)
{
while (n--) {
__nop__;
__nop__;
}
}
/**************************************
复位DS18B20,并检测设备是否存在
**************************************/
__bit DS18B20_Reset()
{
__bit CY = 1;
DQ = 0; //送出低电平复位信号
DelayXus(US240); //延时至少480us
DelayXus(US240);
DQ = 1; //释放数据线
DelayXus(US60); //等待60us
CY = DQ; //检测存在脉冲
DelayXus(US240); //等待设备释放数据线
DelayXus(US180);
return CY;
}
/**************************************
从DS18B20读1字节数据
**************************************/
BYTE DS18B20_ReadByte()
{
BYTE i;
BYTE dat = 0;
for (i=0; i<8; i++) { //8位计数器
dat >>= 1;
#if 1
if (DS18B20_ReadBit()) {
dat |= 0x80;
}
#else
DQ = 0; //开始时间片
DelayXus(1); //延时等待
DQ = 1; //准备接收
DelayXus(1); //接收延时
if (DQ) {
dat |= 0x80; //读取数据
}
DelayXus(US60); //等待时间片结束
#endif
}
return dat;
}
// 读一位
__bit DS18B20_ReadBit()
{
__bit result;
DQ = 0; //开始时间片
#ifdef STC11F04E
__nop__; //延时等待
__nop__;
__nop__;
__nop__;
#else
DelayXus(10);
#endif
DQ = 1; //准备接收
#ifdef STC11F04E
__nop__; //延时等待
__nop__;
__nop__;
__nop__;
#else
DelayXus(10);
#endif
result = DQ;
DelayXus(US60); //等待时间片结束
return result;
}
/**************************************
向DS18B20写1字节数据
**************************************/
void DS18B20_WriteByte(BYTE dat)
{
char i;
for (i=0; i<8; i++) { //8位计数器
DQ = 0; //开始时间片
DelayXus(1); //延时等待
dat >>= 1; //送出数据
DQ = CY;
DelayXus(US60); //等待时间片结束
DQ = 1; //恢复数据线
DelayXus(1); //恢复延时
}
}
void DS18B20_WriteBit(__bit dat)
{
DQ = 0;
DelayXus(1);
DQ = dat;
DelayXus(US60);
DQ = 1;
DelayXus(1);
}
/*********************************************************
*功能:读序列
**参数:无返回
*********************************************************/
BYTE DS18B20_ReadRom(BYTE *rom)
{
BYTE i;
DS18B20_Reset();
DS18B20_WriteByte(0x33); //Read ROM
for (i=0; i<8; i++) {
rom[i] = DS18B20_ReadByte();
}
return 0;
}