1 | //#################################################################################
|
2 | //#################################################################################
|
3 | //#################################################################################
|
4 | /* Library to use ds18x20 with ATMEL Atmega family.
|
5 | For short ds18x20 wires there is no need for an external pullup resistor.
|
6 | If the wire length exceeds one meter you should use a 4.7k pullup resistor
|
7 | on the data line. This library does not work for parasite power.
|
8 | You can just use one ds18x20 per Atmega Pin.
|
9 |
|
10 | Copyright (C) 2010 Stefan Sicklinger
|
11 |
|
12 | For support check out http://www.sicklinger.com
|
13 |
|
14 | This library is free software: you can redistribute it and/or modify
|
15 | it under the terms of the GNU General Public License as published by
|
16 | the Free Software Foundation, either version 3 of the License, or
|
17 | (at your option) any later version.
|
18 |
|
19 | This program is distributed in the hope that it will be useful,
|
20 | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
21 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
22 | GNU General Public License for more details.
|
23 |
|
24 | You should have received a copy of the GNU General Public License
|
25 | along with this program. If not, see <http://www.gnu.org/licenses/>.*/
|
26 | //#################################################################################
|
27 | //#################################################################################
|
28 | //#################################################################################
|
29 |
|
30 | #include "ds18x20lib.h"
|
31 |
|
32 |
|
33 | //----------------------------------------
|
34 | // Reset DS18S20
|
35 | //----------------------------------------
|
36 | uint8_t ds1820_reset(uint8_t used_pin)
|
37 | {
|
38 | uint8_t err=100;
|
39 | DS1820_DDR |= 1<<used_pin; // define as ouput
|
40 | DS1820_PORT &= ~(1<<used_pin); //Pull low
|
41 | delay_us(480); ; // 480 us
|
42 | DS1820_DDR &= ~(1<<used_pin); // define as input
|
43 | DS1820_PORT |= 1<<used_pin; //Pullup on
|
44 | delay_us(66); // 66 us
|
45 | err = (DS1820_PIN & (1<<used_pin)) >> used_pin; // no presence detect --> err=1 otherwise err=0
|
46 | delay_us(240); // 240 us
|
47 | if( (DS1820_PIN & (1<<used_pin)) == 0 ){ // short circuit --> err=2
|
48 | err = 2;
|
49 | }
|
50 | return err;
|
51 | }
|
52 | //-----------------------------------------
|
53 | // Write one bit to DS18S20
|
54 | //-----------------------------------------
|
55 | void ds1820_wr_bit(uint8_t wrbit,uint8_t used_pin)
|
56 | {
|
57 | if (wrbit ==0) {
|
58 | DS1820_DDR |= 1<<used_pin; // define as ouput
|
59 | DS1820_PORT &= ~(1<<used_pin); //Pull low
|
60 | delay_us(60);
|
61 | DS1820_DDR &= ~(1<<used_pin); // define as input
|
62 | DS1820_PORT |= 1<<used_pin; //Pullup on
|
63 | delay_us(4);
|
64 | }
|
65 | if (wrbit ==1) {
|
66 | DS1820_DDR |= 1<<used_pin; // define as ouput
|
67 | DS1820_PORT &= ~(1<<used_pin); //Pull low
|
68 | delay_us(10);
|
69 | DS1820_DDR &= ~(1<<used_pin); // define as input
|
70 | DS1820_PORT |= 1<<used_pin; //Pullup on
|
71 | delay_us(54);
|
72 | }
|
73 | }
|
74 | //-----------------------------------------
|
75 | // Read one bit from DS18S20
|
76 | //-----------------------------------------
|
77 | uint8_t ds1820_re_bit(uint8_t used_pin)
|
78 | {
|
79 | uint8_t rebit;
|
80 | DS1820_DDR |= 1<<used_pin; // define as ouput
|
81 | DS1820_PORT &= ~(1<<used_pin); //Pull low
|
82 | delay_us(1);
|
83 | DS1820_DDR &= ~(1<<used_pin); // define as input
|
84 | DS1820_PORT |= 1<<used_pin; //Pullup on
|
85 | delay_us(10);
|
86 | rebit = (DS1820_PIN & (1<<used_pin)) >> used_pin; //Read bit
|
87 | delay_us(50);
|
88 | return rebit;
|
89 | }
|
90 | //-----------------------------------------
|
91 | // Read 1 byte from DS18S20
|
92 | //-----------------------------------------
|
93 | uint8_t ds1820_re_byte(uint8_t used_pin)
|
94 | {
|
95 | uint8_t rebyte =0x00;
|
96 | uint8_t rebit;
|
97 | uint8_t i;
|
98 |
|
99 | for (i=0;i<8;i++)
|
100 | {
|
101 | rebit=ds1820_re_bit(used_pin);
|
102 | //delay_us(2); //be on the save side
|
103 | if (rebit==1){
|
104 | rebyte|=(1<<i);
|
105 | }
|
106 | }
|
107 | return(rebyte);
|
108 | }
|
109 | //-----------------------------------------
|
110 | // Write 1 byte to DS18S20
|
111 | //-----------------------------------------
|
112 | void ds1820_wr_byte(uint8_t wrbyte,uint8_t used_pin)
|
113 | {
|
114 | uint8_t i;
|
115 | for (i=0; i<8; i++) // writes byte, one bit at a time
|
116 | {
|
117 | ds1820_wr_bit((wrbyte & 0b00000001),used_pin);
|
118 | wrbyte = wrbyte >> 1;
|
119 | }
|
120 | delay_us(5);
|
121 | }
|
122 | //-----------------------------------------
|
123 | // Read temperature
|
124 | //-----------------------------------------
|
125 | float ds1820_read_temp(uint8_t used_pin)
|
126 | {
|
127 | uint8_t error,i;
|
128 | uint16_t j=0;
|
129 | uint8_t scratchpad[9];
|
130 | float temp=0;
|
131 | scratchpad[0]=0;
|
132 | scratchpad[1]=0;
|
133 | scratchpad[2]=0;
|
134 | scratchpad[3]=0;
|
135 | scratchpad[4]=0;
|
136 | scratchpad[5]=0;
|
137 | scratchpad[6]=0;
|
138 | scratchpad[7]=0;
|
139 | scratchpad[8]=0;
|
140 | error=ds1820_reset(used_pin); //1. Reset
|
141 | if (error==0){
|
142 | ds1820_wr_byte(0xCC,used_pin); //2. skip ROM
|
143 | ds1820_wr_byte(0x44,used_pin); //3. ask for temperature conversion
|
144 | while (ds1820_re_byte(used_pin)==0xFF && j<1000){ //4. wait until conversion is finished
|
145 | _delay_us(1);
|
146 | j++;
|
147 | }
|
148 | error=ds1820_reset(used_pin); //5. Reset
|
149 | ds1820_wr_byte(0xCC,used_pin); //6. skip ROM
|
150 | ds1820_wr_byte(0xBE,used_pin); //7. Read entire scratchpad 9 bytes
|
151 |
|
152 | for (i=0; i<9; i++) //8. Get scratchpad byte by byte
|
153 | {
|
154 | scratchpad[i]=ds1820_re_byte(used_pin); //9. read one DS18S20 byte
|
155 | }
|
156 | }
|
157 | if(scratchpad[1]==0x00 && scratchpad[7]!=0){ //Value pos.
|
158 | scratchpad[0]=scratchpad[0] >> 1;
|
159 | temp=(scratchpad[0]-0.25f+(((float)scratchpad[7]-(float)scratchpad[6])/(float)scratchpad[7]));
|
160 | temp = (floor(temp*10.0+0.5)/10); //Round value .x
|
161 |
|
162 | }
|
163 | if(scratchpad[1]!=0x00){ //Value negative
|
164 | uint8_t tmp;
|
165 | tmp =scratchpad[0]; //Save Kommabit
|
166 | tmp= ~ tmp;
|
167 | tmp= tmp >> 1;
|
168 | temp = (-1)*(tmp+1);
|
169 | if ((scratchpad[0]&0b00000001)==1){
|
170 | temp=temp+0.5;
|
171 | }
|
172 |
|
173 | }
|
174 |
|
175 | return temp;
|
176 | }
|
177 | //-----------------------------------------
|
178 | // Initialize DS18S20
|
179 | //-----------------------------------------
|
180 | void ds1820_init(uint8_t used_pin)
|
181 | {
|
182 | uint8_t error;
|
183 | uint16_t i =0;
|
184 | error=ds1820_reset(used_pin); //1. Reset
|
185 | if (error==0){
|
186 | ds1820_wr_byte(0xCC,used_pin); //2. skip ROM
|
187 | ds1820_wr_byte(0x44,used_pin); //3. ask for temperature conversion
|
188 | while (ds1820_re_byte(used_pin)==0xFF && i<1000){ //4. wait until conversion is finished
|
189 | _delay_us(1);
|
190 | i++;
|
191 | }
|
192 | error=ds1820_reset(used_pin); //5. Reset
|
193 | ds1820_wr_byte(0xCC,used_pin); //6. skip ROM
|
194 | ds1820_wr_byte(0xBE,used_pin); //7. Read entire scratchpad 9 bytes
|
195 | }
|
196 |
|
197 |
|
198 | }
|