-
-
Notifications
You must be signed in to change notification settings - Fork 14
/
ds18b20.c
executable file
·213 lines (186 loc) · 4.97 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
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
204
205
206
207
208
209
210
211
212
213
#include "ds18b20.h"
#include "OnBoard.h"
#define DS18B20_SKIP_ROM 0xCC
#define DS18B20_CONVERT_T 0x44
#define DS18B20_READ_SCRATCHPAD 0xBE
#define DS18B20_WRITE_SCRATCHPAD 0x4E
// Device resolution
#define DS18B20_TEMP_9_BIT 0x1F // 9 bit
#define DS18B20_TEMP_10_BIT 0x3F // 10 bit
#define DS18B20_TEMP_11_BIT 0x5F // 11 bit
#define DS18B20_TEMP_12_BIT 0x7F // 12 bit
#ifndef DS18B20_RESOLUTION
#define DS18B20_RESOLUTION DS18B20_TEMP_10_BIT
#endif
#ifndef DS18B20_RETRY_COUNT
#define DS18B20_RETRY_COUNT 10
#endif
#define MAX_CONVERSION_TIME (750 * 1.2) // ms 750ms + some overhead
#define DS18B20_RETRY_DELAY ((uint16) (MAX_CONVERSION_TIME / DS18B20_RETRY_COUNT))
static void _delay_us(uint16);
static void _delay_ms(uint16);
static void ds18b20_send(uint8);
static uint8 ds18b20_read(void);
static void ds18b20_send_byte(int8);
static uint8 ds18b20_read_byte(void);
static uint8 ds18b20_Reset(void);
static void ds18b20_GroudPins(void);
static void ds18b20_setResolution(uint8 resolution);
static int16 ds18b20_convertTemperature(uint8 temp1, uint8 temp2, uint8 resolution);
static void _delay_us(uint16 microSecs) {
while (microSecs--)
{
asm("NOP");
asm("NOP");
asm("NOP");
asm("NOP");
asm("NOP");
asm("NOP");
asm("NOP");
asm("NOP");
}
}
static void _delay_ms(uint16 milliSecs) {
while (milliSecs--) {
_delay_us(1000);
}
}
// Sends one bit to bus
static void ds18b20_send(uint8 bit) {
TSENS_SBIT = 1;
TSENS_DIR |= TSENS_BV; // output
TSENS_SBIT = 0;
if (bit != 0)
_delay_us(8);
else
_delay_us(80);
TSENS_SBIT = 1;
if (bit != 0)
_delay_us(80);
else
_delay_us(2);
// TSENS_SBIT = 1;
}
// Reads one bit from bus
static uint8 ds18b20_read(void) {
TSENS_SBIT = 1;
TSENS_DIR |= TSENS_BV; // output
TSENS_SBIT = 0;
_delay_us(2);
// TSENS_SBIT = 1;
//_delay_us(15);
TSENS_DIR &= ~TSENS_BV; // input
_delay_us(5);
uint8 i = TSENS_SBIT;
_delay_us(60);
return i;
}
// Sends one byte to bus
static void ds18b20_send_byte(int8 data) {
uint8 i, x;
for (i = 0; i < 8; i++) {
x = data >> i;
x &= 0x01;
ds18b20_send(x);
}
//_delay_us(100);
}
// Reads one byte from bus
static uint8 ds18b20_read_byte(void) {
uint8 i;
uint8 data = 0;
for (i = 0; i < 8; i++) {
if (ds18b20_read())
data |= 0x01 << i;
//_delay_us(25);
}
return (data);
}
// Sends reset pulse
static uint8 ds18b20_Reset(void) {
TSENS_DIR |= TSENS_BV; // output
TSENS_SBIT = 0;
_delay_us(500);
TSENS_DIR &= ~TSENS_BV; // input
_delay_us(70);
uint8 i = TSENS_SBIT;
_delay_us(200);
TSENS_SBIT = 1;
TSENS_DIR |= TSENS_BV; // output
_delay_us(500);
return i;
}
static void ds18b20_GroudPins(void) {
// TSENS_SBIT = 0;
TSENS_DIR &= ~TSENS_BV; // input
}
static void ds18b20_setResolution(uint8 resolution) {
ds18b20_Reset();
ds18b20_send_byte(DS18B20_SKIP_ROM);
ds18b20_send_byte(DS18B20_WRITE_SCRATCHPAD);
// two dummy values for LOW & HIGH ALARM
ds18b20_send_byte(0);
ds18b20_send_byte(100);
ds18b20_send_byte(resolution);
ds18b20_Reset();
}
static int16 ds18b20_convertTemperature(uint8 temp1, uint8 temp2, uint8 resolution) {
float temperature = 0;
uint8 ignoreMask = 0;
switch (resolution) {
case DS18B20_TEMP_9_BIT:
ignoreMask = (BV(0) | BV(1) | BV(2));
break;
case DS18B20_TEMP_10_BIT:
ignoreMask = (BV(0) | BV(1));
break;
case DS18B20_TEMP_11_BIT:
ignoreMask = (BV(0));
break;
case DS18B20_TEMP_12_BIT:
ignoreMask = 0;
break;
default:
break;
}
temperature = (uint16)temp1 | (uint16)(ignoreMask ? temp2 & ignoreMask : temp2) << 8;
// neg. temp
if (temp2 & (BV(3))) {
temperature = temperature / 16.0 - 128.0;
}
// pos. temp
else {
temperature = temperature / 16.0;
}
return (int16)(temperature * 100);
}
int16 readTemperature(void) {
uint8 temp1, temp2, retry_count = DS18B20_RETRY_COUNT;
ds18b20_setResolution(DS18B20_RESOLUTION);
ds18b20_Reset();
ds18b20_send_byte(DS18B20_SKIP_ROM);
ds18b20_send_byte(DS18B20_CONVERT_T);
while (retry_count) {
_delay_ms(DS18B20_RETRY_DELAY);
ds18b20_Reset();
ds18b20_send_byte(DS18B20_SKIP_ROM);
ds18b20_send_byte(DS18B20_READ_SCRATCHPAD);
temp1 = ds18b20_read_byte();
temp2 = ds18b20_read_byte();
ds18b20_Reset();
if (temp1 == 0xff && temp2 == 0xff) {
// No sensor found.
ds18b20_GroudPins();
return 1;
}
if (temp1 == 0x50 && temp2 == 0x05) {
// Power-up State, not ready yet
retry_count--;
continue;
}
ds18b20_GroudPins();
return ds18b20_convertTemperature(temp1, temp2, DS18B20_RESOLUTION);
}
ds18b20_GroudPins();
return 1;
}