-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathds18b20.c
205 lines (171 loc) · 4.58 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
/*
ds18b20 lib
based on lib by Davide Gironi, 2012
Released under GPLv3.
Please refer to LICENSE file for licensing information.
without CRC check
modified 08-2017 by martin, used int as output, 12 bit resolution,...
*/
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "ds18b20.h"
//#include "lcd.h"
//check READ_ROM_CODE
/*
* ds18b20 init
*/
uint8_t ds18b20_reset(volatile unsigned char *Port, unsigned char Pin)
{
uint8_t i=0,j=0; // i- presence pulse, j- bus release
//low for 480us
*Port &= ~(1<<Pin); // pin low
*(Port-1)|=(1<<Pin); //pin as output
_delay_us(500); //480
//release line and wait for 60uS
*(Port-1) &= ~(1<<Pin); //pin as input without pullup
_delay_us(60); //60
//get value and wait 420us
if((*(Port-2))&(1<<Pin)) {i = 0;} else {i = 1;}
_delay_us(250); //device after 15-60us pull down line for 60-240us
if((*(Port-2))&(1<<Pin)) {j = 1;} else {j = 0;}
//return presence bit(0-no device,1-device OK)
return (i & j);
}
/*
* write one bit
*/
void ds18b20_writebit(volatile unsigned char *Port, unsigned char Pin, uint8_t bit)
{
//low for 1uS
*Port &= ~ (1<<Pin);
//output
*(Port-1)|=(1<<Pin);
_delay_us(1); //1uS
//if we want to write 1, release the line (if not will keep low)
if(bit)
*(Port-1) &= ~ (1<<Pin); //input
//wait 60uS and release the line
_delay_us(60); //60
*(Port-1) &= ~ (1<<Pin); //input
}
/*
* read one bit
*/
uint8_t ds18b20_readbit(volatile unsigned char *Port, unsigned char Pin)
{
uint8_t bit=0;
//low for 1uS
//low
*Port &= ~(1<<Pin);
//output
*(Port-1) |= (1<<Pin);
_delay_us(1); //1
//release line and wait for 14uS
//input
*(Port-1) &= ~(1<<Pin);
_delay_us(14); //10
//read the value
if( (*(Port-2)) & (1<<Pin) )
bit=1;
//wait 45uS and return read value
_delay_us(53); //53
return bit;
}
/*
* write one byte
*/
void ds18b20_writebyte(volatile unsigned char *Port, unsigned char Pin, uint8_t byte)
{
uint8_t i=8;
while(i--){
ds18b20_writebit(Port, Pin, byte&1);
byte >>= 1;
}
}
/*
* read one byte
*/
uint8_t ds18b20_readbyte(volatile unsigned char *Port, unsigned char Pin)
{
uint8_t i=8, n=0;
while(i--){
n >>= 1;
n |= (ds18b20_readbit(Port, Pin)<<7);
}
return n;
}
/*
* read ROM code from sensor, and print it on LCD on actual position
*/
void read_ROM_CODE(volatile unsigned char *Port, unsigned char Pin)
{
char i;
cli(); // disable interrupts
ds18b20_reset(Port, Pin); //reset OW bus
ds18b20_writebyte(Port, Pin, DS18B20_CMD_READROM); //read ROM
for(i=0;i<8;i++)
{
ROM_code[i] = ds18b20_readbyte(Port, Pin);
}
//sei(); // enable interrupts
// for project with LCD HD44780
//for(j=0;j<8;j++)
//{
// lcd_puthex_byte(ROM_code[j]);
//}
}
/*
* get temperature
*/
int16_t ds18b20_gettemp(volatile unsigned char *Port, unsigned char Pin)
{
uint8_t temperature_l;
uint8_t temperature_h;
uint16_t teplota;
uint8_t desatiny;
//double retd = 0;
uint8_t sign;
int16_t retd = 5;
//#if DS18B20_STOPINTERRUPTONREAD == 1
//cli(); //interrupt deny
//#endif
ds18b20_reset(Port, Pin); //reset
ds18b20_writebyte(Port, Pin, DS18B20_CMD_SKIPROM); //skip ROM
ds18b20_writebyte(Port, Pin, DS18B20_CMD_CONVERTTEMP); //start temperature conversion
while(!ds18b20_readbit(Port, Pin)); //wait until conversion is complete
ds18b20_reset(Port, Pin); //reset
ds18b20_writebyte(Port, Pin, DS18B20_CMD_SKIPROM); //skip ROM
ds18b20_writebyte(Port, Pin, DS18B20_CMD_RSCRATCHPAD); //read scratchpad
//read 2 byte from scratchpad
temperature_l = ds18b20_readbyte(Port, Pin);
temperature_h = ds18b20_readbyte(Port, Pin);
sign = (temperature_h >> 4) & 0x0F;
//#if DS18B20_STOPINTERRUPTONREAD == 1
//sei(); //interrupt allow
//#endif
if(sign == 0)
{
teplota = (temperature_l & 0xF0) >> 4 | (temperature_h & 0x0F) << 4 ; // signed teplota
desatiny = (temperature_l & 0x0F) * 0.625;
retd = 10 * teplota;
retd = retd + desatiny;
}
else
{
temperature_l =~ temperature_l;
temperature_h =~ temperature_h;
teplota = (temperature_l & 0xF0) >> 4 | (temperature_h & 0x0F) << 4 ; // signed teplota
desatiny = ((temperature_l + 1) & 0x0F) * 0.625;
retd = (teplota*10+desatiny)*(-1);
}
sei();
//******************* flash LED ******************
// command
//PORTB &= ~(1 << PB5); // set low
//_delay_ms(600);
//PORTB |= (1 << PB5); // set high
//_delay_ms(200);
//************************************************
return retd; // output in decicelsius *10
}