oneWire.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. #include "stm32f1xx_hal.h"
  2. #include "oneWireDriver.h"
  3. #include<stdio.h>
  4. #include<stdbool.h>
  5. // global search state
  6. static unsigned char ROM_NO[8];
  7. static uint8_t LastDiscrepancy;
  8. static uint8_t LastFamilyDiscrepancy;
  9. static bool LastDeviceFlag;
  10. void reset_oneWireSearch()
  11. {
  12. // reset the search state
  13. LastDiscrepancy = 0;
  14. LastDeviceFlag = false;
  15. LastFamilyDiscrepancy = 0;
  16. for(int i = 7; ; i--) {
  17. ROM_NO[i] = 0;
  18. if ( i == 0) break;
  19. }
  20. }
  21. bool oneWireSearch(uint64_t *newAddr )
  22. {
  23. const bool search_mode = true;
  24. uint8_t id_bit_number;
  25. uint8_t last_zero, rom_byte_number;
  26. bool search_result;
  27. uint8_t id_bit, cmp_id_bit;
  28. unsigned char rom_byte_mask, search_direction;
  29. // initialize for search
  30. id_bit_number = 1;
  31. last_zero = 0;
  32. rom_byte_number = 0;
  33. rom_byte_mask = 1;
  34. search_result = false;
  35. // if the last call was not the last one
  36. if (!LastDeviceFlag) {
  37. // 1-Wire reset
  38. if (!oneWire_init()) {
  39. // reset the search
  40. LastDiscrepancy = 0;
  41. LastDeviceFlag = false;
  42. LastFamilyDiscrepancy = 0;
  43. return false;
  44. }
  45. // issue the search command
  46. if (search_mode == true) {
  47. writeByte(0xF0); // NORMAL SEARCH
  48. } else {
  49. writeByte(0xEC); // CONDITIONAL SEARCH
  50. }
  51. // loop to do the search
  52. do
  53. {
  54. // read a bit and its complement
  55. id_bit = readSlot();
  56. cmp_id_bit = readSlot();
  57. // check for no devices on 1-wire
  58. if ((id_bit == 1) && (cmp_id_bit == 1)) {
  59. break;
  60. } else {
  61. // all devices coupled have 0 or 1
  62. if (id_bit != cmp_id_bit) {
  63. search_direction = id_bit; // bit write value for search
  64. } else {
  65. // if this discrepancy if before the Last Discrepancy
  66. // on a previous next then pick the same as last time
  67. if (id_bit_number < LastDiscrepancy) {
  68. search_direction = ((ROM_NO[rom_byte_number] & rom_byte_mask) > 0);
  69. } else {
  70. // if equal to last pick 1, if not then pick 0
  71. search_direction = (id_bit_number == LastDiscrepancy);
  72. }
  73. // if 0 was picked then record its position in LastZero
  74. if (search_direction == 0) {
  75. last_zero = id_bit_number;
  76. // check for Last discrepancy in family
  77. if (last_zero < 9)
  78. LastFamilyDiscrepancy = last_zero;
  79. }
  80. }
  81. // set or clear the bit in the ROM byte rom_byte_number
  82. // with mask rom_byte_mask
  83. if (search_direction == 1)
  84. ROM_NO[rom_byte_number] |= rom_byte_mask;
  85. else
  86. ROM_NO[rom_byte_number] &= ~rom_byte_mask;
  87. // serial number search direction write bit
  88. writeSlot(search_direction);
  89. // increment the byte counter id_bit_number
  90. // and shift the mask rom_byte_mask
  91. id_bit_number++;
  92. rom_byte_mask <<= 1;
  93. // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask
  94. if (rom_byte_mask == 0) {
  95. rom_byte_number++;
  96. rom_byte_mask = 1;
  97. }
  98. }
  99. }
  100. while(rom_byte_number < 8); // loop until through all ROM bytes 0-7
  101. // if the search was successful then
  102. if (!(id_bit_number < 65)) {
  103. // search successful so set LastDiscrepancy,LastDeviceFlag,search_result
  104. LastDiscrepancy = last_zero;
  105. // check for last device
  106. if (LastDiscrepancy == 0) {
  107. LastDeviceFlag = true;
  108. }
  109. search_result = true;
  110. }
  111. }
  112. // if no device found then reset counters so next 'search' will be like a first
  113. if (!search_result || !ROM_NO[0]) {
  114. LastDiscrepancy = 0;
  115. LastDeviceFlag = false;
  116. LastFamilyDiscrepancy = 0;
  117. search_result = false;
  118. } else {
  119. for (int i = 0; i < 8; i++) {
  120. (*newAddr)<<=8;
  121. (*newAddr) |= ROM_NO[i];
  122. }
  123. }
  124. return search_result;
  125. }
  126. static void sendROMCode(const uint64_t adr){
  127. for( uint8_t i = 8; i>0; i--) writeByte( (uint8_t)(adr >> ((i-1)*8))&0xFF );
  128. }
  129. static uint32_t initReadTemp(const uint64_t adr)
  130. {
  131. uint32_t noOfSlots = 0;
  132. oneWire_init();
  133. writeByte(0x55); // match ROM
  134. sendROMCode(adr);
  135. writeByte(0x44); // convert t
  136. while( readSlot() == 0 ) {
  137. noOfSlots++;
  138. us_delay(1000);
  139. }
  140. return noOfSlots;
  141. }
  142. float readTemperature(const uint64_t adr)
  143. {
  144. uint32_t time_ms = initReadTemp(adr);
  145. oneWire_init();
  146. writeByte(0x55); // skip ROM
  147. sendROMCode(adr);
  148. writeByte(0xBE); // Read Scratchpad
  149. uint8_t b0 = readByte();
  150. uint8_t b1 = readByte();
  151. uint8_t b2 = readByte();
  152. uint8_t b3 = readByte();
  153. uint8_t b4 = readByte();
  154. uint8_t b5 = readByte();
  155. uint8_t b6 = readByte();
  156. uint8_t b7 = readByte();
  157. uint16_t raw = (int16_t)((b1 << 8) | b0);
  158. uint16_t cfg = (b4 & 0x60);
  159. // at lower res, the low bits are undefined, so let's zero them
  160. if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms
  161. else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
  162. else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
  163. //// default is 12 bit resolution, 750 ms conversion time
  164. float temperature = (float)raw / 16.0;
  165. printf("%lumS : %02X %02X %02X %02X %02X",time_ms,b0,b1,b2,b3,b4);
  166. printf(" %02X %02X %02X = %.02f\n",b5,b6,b7,temperature);
  167. return temperature;
  168. }