MAX31850, DS18B20, DS2450, thermocouple
DS18X20.cpp@0:5d39f2521173, 2015-03-09 (annotated)
- Committer:
- fblanc
- Date:
- Mon Mar 09 11:55:54 2015 +0000
- Revision:
- 0:5d39f2521173
MAX31850
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
fblanc | 0:5d39f2521173 | 1 | /** |
fblanc | 0:5d39f2521173 | 2 | * @file DS18x20.c |
fblanc | 0:5d39f2521173 | 3 | * @brief library of DS18X20 1-Wire digital thermometer (http://www.maxim-ic.com/datasheet/index.mvp/id/2812) |
fblanc | 0:5d39f2521173 | 4 | * @author Maciej Rajtar (Published 10 May 2010 www.mbed.org) |
fblanc | 0:5d39f2521173 | 5 | * @author Frederic BLANC (Published 01/03/2012 www.mbed.org) |
fblanc | 0:5d39f2521173 | 6 | */ |
fblanc | 0:5d39f2521173 | 7 | #include "mbed.h" |
fblanc | 0:5d39f2521173 | 8 | #include "onewire.h" |
fblanc | 0:5d39f2521173 | 9 | #include "DS18X20.h" |
fblanc | 0:5d39f2521173 | 10 | #include "crc8.h" |
fblanc | 0:5d39f2521173 | 11 | #include "utils.h" |
fblanc | 0:5d39f2521173 | 12 | //********************************************************************************************************** |
fblanc | 0:5d39f2521173 | 13 | //* DS18X20_show_temp |
fblanc | 0:5d39f2521173 | 14 | //********************************************************************************************************** |
fblanc | 0:5d39f2521173 | 15 | |
fblanc | 0:5d39f2521173 | 16 | /** |
fblanc | 0:5d39f2521173 | 17 | * @brief DS18X20_show_temp |
fblanc | 0:5d39f2521173 | 18 | * @param [in] id[] = rom_code |
fblanc | 0:5d39f2521173 | 19 | * @param [in] n number of id[n] |
fblanc | 0:5d39f2521173 | 20 | * @param [out] text temp in degre celsius |
fblanc | 0:5d39f2521173 | 21 | |
fblanc | 0:5d39f2521173 | 22 | * @date 20/06/2011 |
fblanc | 0:5d39f2521173 | 23 | */ |
fblanc | 0:5d39f2521173 | 24 | void DS18X20_show_temp(uint8_t subzero, uint8_t cel, uint8_t cel_frac_bits,char *text) { |
fblanc | 0:5d39f2521173 | 25 | uint16_t decicelsius; |
fblanc | 0:5d39f2521173 | 26 | char s[10]; |
fblanc | 0:5d39f2521173 | 27 | float temperature; |
fblanc | 0:5d39f2521173 | 28 | sprintf(text,""); |
fblanc | 0:5d39f2521173 | 29 | sprintf(s,"%s", (subzero)?"-":""); |
fblanc | 0:5d39f2521173 | 30 | strcat(text,s); |
fblanc | 0:5d39f2521173 | 31 | decicelsius = DS18X20_temp_to_decicel(subzero, cel, cel_frac_bits); |
fblanc | 0:5d39f2521173 | 32 | temperature = decicelsius; |
fblanc | 0:5d39f2521173 | 33 | temperature = temperature/10; |
fblanc | 0:5d39f2521173 | 34 | sprintf(s,"%4.1f", temperature); |
fblanc | 0:5d39f2521173 | 35 | strcat(text,s); |
fblanc | 0:5d39f2521173 | 36 | |
fblanc | 0:5d39f2521173 | 37 | } |
fblanc | 0:5d39f2521173 | 38 | /** |
fblanc | 0:5d39f2521173 | 39 | * @brief DS18X20_show_temp |
fblanc | 0:5d39f2521173 | 40 | * @param [in] id[] = rom_code |
fblanc | 0:5d39f2521173 | 41 | * @param [in] n number of id[n] |
fblanc | 0:5d39f2521173 | 42 | * @return temp in degre celsius |
fblanc | 0:5d39f2521173 | 43 | |
fblanc | 0:5d39f2521173 | 44 | * @date 21/10/2011 |
fblanc | 0:5d39f2521173 | 45 | */ |
fblanc | 0:5d39f2521173 | 46 | float DS18X20_temp(uint8_t subzero, uint8_t cel, uint8_t cel_frac_bits) { |
fblanc | 0:5d39f2521173 | 47 | return ((subzero)?-1:1)*DS18X20_temp_to_decicel(subzero, cel, cel_frac_bits)/10; |
fblanc | 0:5d39f2521173 | 48 | } |
fblanc | 0:5d39f2521173 | 49 | //********************************************************************************************************** |
fblanc | 0:5d39f2521173 | 50 | //* DS18X20_get_power_status |
fblanc | 0:5d39f2521173 | 51 | //********************************************************************************************************** |
fblanc | 0:5d39f2521173 | 52 | |
fblanc | 0:5d39f2521173 | 53 | /** |
fblanc | 0:5d39f2521173 | 54 | * @brief get power status of DS18x20 |
fblanc | 0:5d39f2521173 | 55 | * @param [in] id[] = rom_code |
fblanc | 0:5d39f2521173 | 56 | * @return DS18X20_POWER_EXTERN or DS18X20_POWER_PARASITE |
fblanc | 0:5d39f2521173 | 57 | * @date 20/06/2011 |
fblanc | 0:5d39f2521173 | 58 | */ |
fblanc | 0:5d39f2521173 | 59 | uint8_t DS18X20_get_power_status(uint8_t id[]) { |
fblanc | 0:5d39f2521173 | 60 | uint8_t pstat; |
fblanc | 0:5d39f2521173 | 61 | ow_reset(); |
fblanc | 0:5d39f2521173 | 62 | ow_command(DS18X20_READ_POWER_SUPPLY, id); |
fblanc | 0:5d39f2521173 | 63 | pstat=ow_bit_io(1); // pstat 0=is parasite/ !=0 ext. powered |
fblanc | 0:5d39f2521173 | 64 | ow_reset(); |
fblanc | 0:5d39f2521173 | 65 | return (pstat) ? DS18X20_POWER_EXTERN:DS18X20_POWER_PARASITE; |
fblanc | 0:5d39f2521173 | 66 | } |
fblanc | 0:5d39f2521173 | 67 | |
fblanc | 0:5d39f2521173 | 68 | /** |
fblanc | 0:5d39f2521173 | 69 | * @brief get power status of DS18x20 |
fblanc | 0:5d39f2521173 | 70 | * @param [in] n num bus onewire |
fblanc | 0:5d39f2521173 | 71 | * @param [in] id[] = rom_code |
fblanc | 0:5d39f2521173 | 72 | * @return DS18X20_POWER_EXTERN or DS18X20_POWER_PARASITE |
fblanc | 0:5d39f2521173 | 73 | * @date 6/09/2011 |
fblanc | 0:5d39f2521173 | 74 | */ |
fblanc | 0:5d39f2521173 | 75 | uint8_t DS18X20_get_power_status(uint8_t n,uint8_t id[]) { |
fblanc | 0:5d39f2521173 | 76 | uint8_t pstat; |
fblanc | 0:5d39f2521173 | 77 | ow_reset(n); |
fblanc | 0:5d39f2521173 | 78 | ow_command(n,DS18X20_READ_POWER_SUPPLY, id); |
fblanc | 0:5d39f2521173 | 79 | pstat=ow_bit_io(n,1); // pstat 0=is parasite/ !=0 ext. powered |
fblanc | 0:5d39f2521173 | 80 | ow_reset(n); |
fblanc | 0:5d39f2521173 | 81 | return (pstat) ? DS18X20_POWER_EXTERN:DS18X20_POWER_PARASITE; |
fblanc | 0:5d39f2521173 | 82 | } |
fblanc | 0:5d39f2521173 | 83 | //********************************************************************************************************** |
fblanc | 0:5d39f2521173 | 84 | //* DS18X20_start_meas |
fblanc | 0:5d39f2521173 | 85 | //********************************************************************************************************** |
fblanc | 0:5d39f2521173 | 86 | /** |
fblanc | 0:5d39f2521173 | 87 | * @brief reads temperature (scratchpad) of sensor with rom-code id |
fblanc | 0:5d39f2521173 | 88 | output: subzero==1 if temp.<0, cel: full celsius, mcel: frac |
fblanc | 0:5d39f2521173 | 89 | in millicelsius*0.1 |
fblanc | 0:5d39f2521173 | 90 | i.e.: subzero=1, cel=18, millicel=5000 = -18,5000�C |
fblanc | 0:5d39f2521173 | 91 | * @param [in] n num bus onewire |
fblanc | 0:5d39f2521173 | 92 | * @param [in] id[] = rom_code |
fblanc | 0:5d39f2521173 | 93 | * @param [out] temperature |
fblanc | 0:5d39f2521173 | 94 | * @return DS18X20_OK or DS18X20_ERROR_CRC |
fblanc | 0:5d39f2521173 | 95 | * @date 07/12/2012 |
fblanc | 0:5d39f2521173 | 96 | */ |
fblanc | 0:5d39f2521173 | 97 | uint8_t DS18X20_read_meas(uint8_t n,uint8_t id[], float* temperature) { |
fblanc | 0:5d39f2521173 | 98 | uint8_t i; |
fblanc | 0:5d39f2521173 | 99 | uint8_t sp[DS18X20_SP_SIZE]; |
fblanc | 0:5d39f2521173 | 100 | uint8_t subzero; |
fblanc | 0:5d39f2521173 | 101 | uint8_t cel; |
fblanc | 0:5d39f2521173 | 102 | uint8_t cel_frac_bits; |
fblanc | 0:5d39f2521173 | 103 | |
fblanc | 0:5d39f2521173 | 104 | ow_reset(n); |
fblanc | 0:5d39f2521173 | 105 | ow_command(n,DS18X20_READ, id); |
fblanc | 0:5d39f2521173 | 106 | for ( i=0 ; i< DS18X20_SP_SIZE; i++ ) |
fblanc | 0:5d39f2521173 | 107 | sp[i]=ow_byte_rd(n); |
fblanc | 0:5d39f2521173 | 108 | if ( crc8( &sp[0], DS18X20_SP_SIZE ) ){ |
fblanc | 0:5d39f2521173 | 109 | if ((sp[DS18X20_SP_SIZE-1]==0xFF) && (sp[DS18X20_SP_SIZE-2]==0xFF)) |
fblanc | 0:5d39f2521173 | 110 | return OW_ERROR; // bus error |
fblanc | 0:5d39f2521173 | 111 | return DS18X20_ERROR_CRC; // data error |
fblanc | 0:5d39f2521173 | 112 | } |
fblanc | 0:5d39f2521173 | 113 | |
fblanc | 0:5d39f2521173 | 114 | DS18X20_meas_to_cel(id[0], sp, &subzero, &cel, &cel_frac_bits); |
fblanc | 0:5d39f2521173 | 115 | *temperature = cel_frac_bits*.0625; |
fblanc | 0:5d39f2521173 | 116 | *temperature += cel; |
fblanc | 0:5d39f2521173 | 117 | if (subzero) |
fblanc | 0:5d39f2521173 | 118 | *temperature *= -1; |
fblanc | 0:5d39f2521173 | 119 | return DS18X20_OK; |
fblanc | 0:5d39f2521173 | 120 | } |
fblanc | 0:5d39f2521173 | 121 | /** |
fblanc | 0:5d39f2521173 | 122 | * @brief start measurement (CONVERT_T) for all sensors if input id==NULL |
fblanc | 0:5d39f2521173 | 123 | or for single sensor. then id is the rom-code |
fblanc | 0:5d39f2521173 | 124 | * @param [in] with_power_extern |
fblanc | 0:5d39f2521173 | 125 | * @param [in] rom_code |
fblanc | 0:5d39f2521173 | 126 | * @return DS18X20_OK or DS18X20_START_FAIL |
fblanc | 0:5d39f2521173 | 127 | * @date 20/06/2011 |
fblanc | 0:5d39f2521173 | 128 | */ |
fblanc | 0:5d39f2521173 | 129 | uint8_t DS18X20_start_meas( uint8_t with_power_extern, uint8_t id[]) { |
fblanc | 0:5d39f2521173 | 130 | ow_reset(); //** |
fblanc | 0:5d39f2521173 | 131 | if ( ow_test_pin() ) { // only send if bus is "idle" = high |
fblanc | 0:5d39f2521173 | 132 | ow_command( DS18X20_CONVERT_T, id ); |
fblanc | 0:5d39f2521173 | 133 | if (with_power_extern != DS18X20_POWER_EXTERN) |
fblanc | 0:5d39f2521173 | 134 | ow_parasite_enable(); |
fblanc | 0:5d39f2521173 | 135 | return DS18X20_OK; |
fblanc | 0:5d39f2521173 | 136 | } |
fblanc | 0:5d39f2521173 | 137 | return DS18X20_START_FAIL; |
fblanc | 0:5d39f2521173 | 138 | |
fblanc | 0:5d39f2521173 | 139 | } |
fblanc | 0:5d39f2521173 | 140 | /** |
fblanc | 0:5d39f2521173 | 141 | * @brief start measurement (CONVERT_T) for all sensors if input id==NULL |
fblanc | 0:5d39f2521173 | 142 | or for single sensor. then id is the rom-code |
fblanc | 0:5d39f2521173 | 143 | * @param [in] n num bus onewire |
fblanc | 0:5d39f2521173 | 144 | * @param [in] with_power_extern |
fblanc | 0:5d39f2521173 | 145 | * @param [in] rom_code |
fblanc | 0:5d39f2521173 | 146 | * @return DS18X20_OK or DS18X20_START_FAIL |
fblanc | 0:5d39f2521173 | 147 | * @date 06/09/2011 |
fblanc | 0:5d39f2521173 | 148 | */ |
fblanc | 0:5d39f2521173 | 149 | uint8_t DS18X20_start_meas(uint8_t n, uint8_t with_power_extern, uint8_t id[]) { |
fblanc | 0:5d39f2521173 | 150 | ow_reset(n); //** |
fblanc | 0:5d39f2521173 | 151 | if ( ow_test_pin(n) ) { // only send if bus is "idle" = high |
fblanc | 0:5d39f2521173 | 152 | ow_command(n, DS18X20_CONVERT_T, id ); |
fblanc | 0:5d39f2521173 | 153 | if (with_power_extern != DS18X20_POWER_EXTERN) |
fblanc | 0:5d39f2521173 | 154 | ow_parasite_enable(n); |
fblanc | 0:5d39f2521173 | 155 | return DS18X20_OK; |
fblanc | 0:5d39f2521173 | 156 | } |
fblanc | 0:5d39f2521173 | 157 | return DS18X20_START_FAIL; |
fblanc | 0:5d39f2521173 | 158 | |
fblanc | 0:5d39f2521173 | 159 | } |
fblanc | 0:5d39f2521173 | 160 | //********************************************************************************************************** |
fblanc | 0:5d39f2521173 | 161 | //* DS18X20_read_meas |
fblanc | 0:5d39f2521173 | 162 | //********************************************************************************************************** |
fblanc | 0:5d39f2521173 | 163 | |
fblanc | 0:5d39f2521173 | 164 | /** |
fblanc | 0:5d39f2521173 | 165 | * @brief reads temperature (scratchpad) of sensor with rom-code id |
fblanc | 0:5d39f2521173 | 166 | output: subzero==1 if temp.<0, cel: full celsius, mcel: frac |
fblanc | 0:5d39f2521173 | 167 | in millicelsius*0.1 |
fblanc | 0:5d39f2521173 | 168 | i.e.: subzero=1, cel=18, millicel=5000 = -18,5000�C |
fblanc | 0:5d39f2521173 | 169 | * @param [in] id[] = rom_code |
fblanc | 0:5d39f2521173 | 170 | * @param [out] subzero |
fblanc | 0:5d39f2521173 | 171 | * @param [out] cel |
fblanc | 0:5d39f2521173 | 172 | * @param [out] cel_frac_bits |
fblanc | 0:5d39f2521173 | 173 | * @return DS18X20_OK or DS18X20_ERROR_CRC |
fblanc | 0:5d39f2521173 | 174 | * @date 20/06/2011 |
fblanc | 0:5d39f2521173 | 175 | */ |
fblanc | 0:5d39f2521173 | 176 | uint8_t DS18X20_read_meas(uint8_t id[], uint8_t *subzero, |
fblanc | 0:5d39f2521173 | 177 | uint8_t *cel, uint8_t *cel_frac_bits) { |
fblanc | 0:5d39f2521173 | 178 | uint8_t i; |
fblanc | 0:5d39f2521173 | 179 | uint8_t sp[DS18X20_SP_SIZE]; |
fblanc | 0:5d39f2521173 | 180 | |
fblanc | 0:5d39f2521173 | 181 | ow_reset(); |
fblanc | 0:5d39f2521173 | 182 | ow_command(DS18X20_READ, id); |
fblanc | 0:5d39f2521173 | 183 | for ( i=0 ; i< DS18X20_SP_SIZE; i++ ) |
fblanc | 0:5d39f2521173 | 184 | sp[i]=ow_byte_rd(); |
fblanc | 0:5d39f2521173 | 185 | if ( crc8( &sp[0], DS18X20_SP_SIZE ) ){ |
fblanc | 0:5d39f2521173 | 186 | if ((sp[DS18X20_SP_SIZE-1]==0xFF) && (sp[DS18X20_SP_SIZE-2]==0xFF)) |
fblanc | 0:5d39f2521173 | 187 | return OW_ERROR; // bus error |
fblanc | 0:5d39f2521173 | 188 | return DS18X20_ERROR_CRC; // data error |
fblanc | 0:5d39f2521173 | 189 | } |
fblanc | 0:5d39f2521173 | 190 | |
fblanc | 0:5d39f2521173 | 191 | DS18X20_meas_to_cel(id[0], sp, subzero, cel, cel_frac_bits); |
fblanc | 0:5d39f2521173 | 192 | return DS18X20_OK; |
fblanc | 0:5d39f2521173 | 193 | } |
fblanc | 0:5d39f2521173 | 194 | /** |
fblanc | 0:5d39f2521173 | 195 | * @brief reads temperature (scratchpad) of sensor with rom-code id |
fblanc | 0:5d39f2521173 | 196 | output: subzero==1 if temp.<0, cel: full celsius, mcel: frac |
fblanc | 0:5d39f2521173 | 197 | in millicelsius*0.1 |
fblanc | 0:5d39f2521173 | 198 | i.e.: subzero=1, cel=18, millicel=5000 = -18,5000�C |
fblanc | 0:5d39f2521173 | 199 | * @param [in] n num bus onewire |
fblanc | 0:5d39f2521173 | 200 | * @param [in] id[] = rom_code |
fblanc | 0:5d39f2521173 | 201 | * @param [out] subzero |
fblanc | 0:5d39f2521173 | 202 | * @param [out] cel |
fblanc | 0:5d39f2521173 | 203 | * @param [out] cel_frac_bits |
fblanc | 0:5d39f2521173 | 204 | * @return DS18X20_OK or DS18X20_ERROR_CRC |
fblanc | 0:5d39f2521173 | 205 | * @date 06/09/2011 |
fblanc | 0:5d39f2521173 | 206 | */ |
fblanc | 0:5d39f2521173 | 207 | uint8_t DS18X20_read_meas(uint8_t n,uint8_t id[], uint8_t *subzero, |
fblanc | 0:5d39f2521173 | 208 | uint8_t *cel, uint8_t *cel_frac_bits) { |
fblanc | 0:5d39f2521173 | 209 | uint8_t i; |
fblanc | 0:5d39f2521173 | 210 | uint8_t sp[DS18X20_SP_SIZE]; |
fblanc | 0:5d39f2521173 | 211 | |
fblanc | 0:5d39f2521173 | 212 | ow_reset(n); |
fblanc | 0:5d39f2521173 | 213 | ow_command(n,DS18X20_READ, id); |
fblanc | 0:5d39f2521173 | 214 | for ( i=0 ; i< DS18X20_SP_SIZE; i++ ) |
fblanc | 0:5d39f2521173 | 215 | sp[i]=ow_byte_rd(n); |
fblanc | 0:5d39f2521173 | 216 | if ( crc8( &sp[0], DS18X20_SP_SIZE ) ){ |
fblanc | 0:5d39f2521173 | 217 | if ((sp[DS18X20_SP_SIZE-1]==0xFF) && (sp[DS18X20_SP_SIZE-2]==0xFF)) |
fblanc | 0:5d39f2521173 | 218 | return OW_ERROR; // bus error |
fblanc | 0:5d39f2521173 | 219 | return DS18X20_ERROR_CRC; // data error |
fblanc | 0:5d39f2521173 | 220 | } |
fblanc | 0:5d39f2521173 | 221 | |
fblanc | 0:5d39f2521173 | 222 | DS18X20_meas_to_cel(id[0], sp, subzero, cel, cel_frac_bits); |
fblanc | 0:5d39f2521173 | 223 | return DS18X20_OK; |
fblanc | 0:5d39f2521173 | 224 | } |
fblanc | 0:5d39f2521173 | 225 | /** |
fblanc | 0:5d39f2521173 | 226 | * @brief convert raw value from DS18x20 to Celsius |
fblanc | 0:5d39f2521173 | 227 | input is: |
fblanc | 0:5d39f2521173 | 228 | - familycode fc (0x10/0x28 see header) |
fblanc | 0:5d39f2521173 | 229 | - scratchpad-buffer |
fblanc | 0:5d39f2521173 | 230 | output is: |
fblanc | 0:5d39f2521173 | 231 | - cel full celsius |
fblanc | 0:5d39f2521173 | 232 | - fractions of celsius in millicelsius*(10^-1)/625 (the 4 LS-Bits) |
fblanc | 0:5d39f2521173 | 233 | - subzero =0 positiv / 1 negativ |
fblanc | 0:5d39f2521173 | 234 | always returns DS18X20_OK |
fblanc | 0:5d39f2521173 | 235 | TODO invalid-values detection (but should be covered by CRC) |
fblanc | 0:5d39f2521173 | 236 | * @param [in] fc |
fblanc | 0:5d39f2521173 | 237 | * @param [in] sp |
fblanc | 0:5d39f2521173 | 238 | * @param [out] subzero |
fblanc | 0:5d39f2521173 | 239 | * @param [out] cel |
fblanc | 0:5d39f2521173 | 240 | * @param [out] cel_frac_bits |
fblanc | 0:5d39f2521173 | 241 | * @return DS18X20_OK |
fblanc | 0:5d39f2521173 | 242 | * @date 20/06/2011 |
fblanc | 0:5d39f2521173 | 243 | */ |
fblanc | 0:5d39f2521173 | 244 | uint8_t DS18X20_meas_to_cel( uint8_t fc, uint8_t *sp, |
fblanc | 0:5d39f2521173 | 245 | uint8_t* subzero, uint8_t* cel, uint8_t* cel_frac_bits) { |
fblanc | 0:5d39f2521173 | 246 | uint16_t meas; |
fblanc | 0:5d39f2521173 | 247 | uint8_t i; |
fblanc | 0:5d39f2521173 | 248 | |
fblanc | 0:5d39f2521173 | 249 | meas = sp[0]; // LSB |
fblanc | 0:5d39f2521173 | 250 | meas |= ((uint16_t)sp[1])<<8; // MSB |
fblanc | 0:5d39f2521173 | 251 | //meas = 0xff5e; meas = 0xfe6f; |
fblanc | 0:5d39f2521173 | 252 | |
fblanc | 0:5d39f2521173 | 253 | // only work on 12bit-base |
fblanc | 0:5d39f2521173 | 254 | if ( fc == DS18S20_ID ) { // 9 -> 12 bit if 18S20 |
fblanc | 0:5d39f2521173 | 255 | /* Extended measurements for DS18S20 contributed by Carsten Foss */ |
fblanc | 0:5d39f2521173 | 256 | meas &= (uint16_t) 0xfffe; // Discard LSB , needed for later extended precicion calc |
fblanc | 0:5d39f2521173 | 257 | meas <<= 3; // Convert to 12-bit , now degrees are in 1/16 degrees units |
fblanc | 0:5d39f2521173 | 258 | meas += (16 - sp[6]) - 4; // Add the compensation , and remember to subtract 0.25 degree (4/16) |
fblanc | 0:5d39f2521173 | 259 | } |
fblanc | 0:5d39f2521173 | 260 | |
fblanc | 0:5d39f2521173 | 261 | // check for negative |
fblanc | 0:5d39f2521173 | 262 | if ( meas & 0x8000 ) { |
fblanc | 0:5d39f2521173 | 263 | *subzero=1; // mark negative |
fblanc | 0:5d39f2521173 | 264 | meas ^= 0xffff; // convert to positive => (twos complement)++ |
fblanc | 0:5d39f2521173 | 265 | meas++; |
fblanc | 0:5d39f2521173 | 266 | } else *subzero=0; |
fblanc | 0:5d39f2521173 | 267 | |
fblanc | 0:5d39f2521173 | 268 | // clear undefined bits for B != 12bit |
fblanc | 0:5d39f2521173 | 269 | if ( fc == DS18B20_ID ) { // check resolution 18B20 |
fblanc | 0:5d39f2521173 | 270 | i = sp[DS18B20_CONF_REG]; |
fblanc | 0:5d39f2521173 | 271 | if ( (i & DS18B20_12_BIT) == DS18B20_12_BIT ) ; |
fblanc | 0:5d39f2521173 | 272 | else if ( (i & DS18B20_11_BIT) == DS18B20_11_BIT ) |
fblanc | 0:5d39f2521173 | 273 | meas &= ~(DS18B20_11_BIT_UNDF); |
fblanc | 0:5d39f2521173 | 274 | else if ( (i & DS18B20_10_BIT) == DS18B20_10_BIT ) |
fblanc | 0:5d39f2521173 | 275 | meas &= ~(DS18B20_10_BIT_UNDF); |
fblanc | 0:5d39f2521173 | 276 | else { // if ( (i & DS18B20_9_BIT) == DS18B20_9_BIT ) { |
fblanc | 0:5d39f2521173 | 277 | meas &= ~(DS18B20_9_BIT_UNDF); |
fblanc | 0:5d39f2521173 | 278 | } |
fblanc | 0:5d39f2521173 | 279 | } |
fblanc | 0:5d39f2521173 | 280 | |
fblanc | 0:5d39f2521173 | 281 | *cel = (uint8_t)(meas >> 4); |
fblanc | 0:5d39f2521173 | 282 | *cel_frac_bits = (uint8_t)(meas & 0x000F); |
fblanc | 0:5d39f2521173 | 283 | |
fblanc | 0:5d39f2521173 | 284 | return DS18X20_OK; |
fblanc | 0:5d39f2521173 | 285 | } |
fblanc | 0:5d39f2521173 | 286 | |
fblanc | 0:5d39f2521173 | 287 | /** |
fblanc | 0:5d39f2521173 | 288 | * @brief converts to decicelsius |
fblanc | 0:5d39f2521173 | 289 | input is ouput from meas_to_cel |
fblanc | 0:5d39f2521173 | 290 | i.e.: sz=0, c=28, frac=15 returns 289 (=28.9�C) |
fblanc | 0:5d39f2521173 | 291 | 0 0 0 |
fblanc | 0:5d39f2521173 | 292 | 1 625 625 1 |
fblanc | 0:5d39f2521173 | 293 | 2 1250 250 |
fblanc | 0:5d39f2521173 | 294 | 3 1875 875 3 |
fblanc | 0:5d39f2521173 | 295 | 4 2500 500 4 |
fblanc | 0:5d39f2521173 | 296 | 5 3125 125 |
fblanc | 0:5d39f2521173 | 297 | 6 3750 750 6 |
fblanc | 0:5d39f2521173 | 298 | 7 4375 375 |
fblanc | 0:5d39f2521173 | 299 | 8 5000 0 |
fblanc | 0:5d39f2521173 | 300 | 9 5625 625 9 |
fblanc | 0:5d39f2521173 | 301 | 10 6250 250 |
fblanc | 0:5d39f2521173 | 302 | 11 6875 875 11 |
fblanc | 0:5d39f2521173 | 303 | 12 7500 500 12 |
fblanc | 0:5d39f2521173 | 304 | 13 8125 125 |
fblanc | 0:5d39f2521173 | 305 | 14 8750 750 14 |
fblanc | 0:5d39f2521173 | 306 | 15 9375 375 |
fblanc | 0:5d39f2521173 | 307 | * @param [in] subzero |
fblanc | 0:5d39f2521173 | 308 | * @param [in] cel |
fblanc | 0:5d39f2521173 | 309 | * @param [in] cel_frac_bits |
fblanc | 0:5d39f2521173 | 310 | * @return absolute value of temperatur in decicelsius |
fblanc | 0:5d39f2521173 | 311 | * @date 20/06/2011 |
fblanc | 0:5d39f2521173 | 312 | */ |
fblanc | 0:5d39f2521173 | 313 | uint16_t DS18X20_temp_to_decicel(uint8_t subzero, uint8_t cel, |
fblanc | 0:5d39f2521173 | 314 | uint8_t cel_frac_bits) { |
fblanc | 0:5d39f2521173 | 315 | uint16_t h; |
fblanc | 0:5d39f2521173 | 316 | uint8_t i; |
fblanc | 0:5d39f2521173 | 317 | uint8_t need_rounding[] = { 1, 3, 4, 6, 9, 11, 12, 14 }; |
fblanc | 0:5d39f2521173 | 318 | |
fblanc | 0:5d39f2521173 | 319 | h = cel_frac_bits*DS18X20_FRACCONV/1000; |
fblanc | 0:5d39f2521173 | 320 | h += cel*10; |
fblanc | 0:5d39f2521173 | 321 | if (!subzero) { |
fblanc | 0:5d39f2521173 | 322 | for (i=0; i<sizeof(need_rounding); i++) { |
fblanc | 0:5d39f2521173 | 323 | if ( cel_frac_bits == need_rounding[i] ) { |
fblanc | 0:5d39f2521173 | 324 | h++; |
fblanc | 0:5d39f2521173 | 325 | break; |
fblanc | 0:5d39f2521173 | 326 | } |
fblanc | 0:5d39f2521173 | 327 | } |
fblanc | 0:5d39f2521173 | 328 | } |
fblanc | 0:5d39f2521173 | 329 | return h; |
fblanc | 0:5d39f2521173 | 330 | } |
fblanc | 0:5d39f2521173 | 331 | /** |
fblanc | 0:5d39f2521173 | 332 | * @brief compare temperature values (full celsius only) |
fblanc | 0:5d39f2521173 | 333 | * @param [in] subzero1 |
fblanc | 0:5d39f2521173 | 334 | * @param [in] cel1 |
fblanc | 0:5d39f2521173 | 335 | * @param [in] subzero2 |
fblanc | 0:5d39f2521173 | 336 | * @param [in] cel2 |
fblanc | 0:5d39f2521173 | 337 | * @return -1 if param-pair1 < param-pair2 |
fblanc | 0:5d39f2521173 | 338 | 0 if == |
fblanc | 0:5d39f2521173 | 339 | 1 if > |
fblanc | 0:5d39f2521173 | 340 | * @date 20/06/2011 |
fblanc | 0:5d39f2521173 | 341 | */ |
fblanc | 0:5d39f2521173 | 342 | int8_t DS18X20_temp_cmp(uint8_t subzero1, uint16_t cel1, |
fblanc | 0:5d39f2521173 | 343 | uint8_t subzero2, uint16_t cel2) { |
fblanc | 0:5d39f2521173 | 344 | int16_t t1 = (subzero1) ? (cel1*(-1)) : (cel1); |
fblanc | 0:5d39f2521173 | 345 | int16_t t2 = (subzero2) ? (cel2*(-1)) : (cel2); |
fblanc | 0:5d39f2521173 | 346 | |
fblanc | 0:5d39f2521173 | 347 | if (t1<t2) return -1; |
fblanc | 0:5d39f2521173 | 348 | if (t1>t2) return 1; |
fblanc | 0:5d39f2521173 | 349 | return 0; |
fblanc | 0:5d39f2521173 | 350 | } |