temper.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. /*
  2. * temper.c
  3. *
  4. * Created on: 22.04.2016
  5. * Author: pavel
  6. */
  7. #include "common_config.h"
  8. #include "onewire.h"
  9. #include "gpio.h"
  10. #include "temper.h"
  11. #include <stdint.h>
  12. #include <stdlib.h>
  13. #ifdef PRINTF_STDLIB
  14. #include <stdio.h>
  15. #endif
  16. #ifdef PRINTF_CUSTOM
  17. #include "tinystdio.h"
  18. #endif
  19. #include "FreeRTOS.h"
  20. #include "task.h"
  21. #include "semphr.h"
  22. #define ERRORS_LIMIT 5
  23. #undef DBG
  24. #define DBG if(0)
  25. const unsigned char crc_table[] = {
  26. 0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,
  27. 157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220,
  28. 35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98,
  29. 190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255,
  30. 70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7,
  31. 219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154,
  32. 101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36,
  33. 248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185,
  34. 140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205,
  35. 17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80,
  36. 175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238,
  37. 50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115,
  38. 202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139,
  39. 87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22,
  40. 233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168,
  41. 116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53
  42. };
  43. static uint8_t tBufExt[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
  44. static uint16_t tempInt = 0;
  45. /**
  46. * @brief Cтруктура датчиков температуры (измерения, состояния, счетчики ошибок)
  47. */
  48. TEMPERATURE_SENSORS_t sTemperSensors[MAX_T_SENSORS];
  49. /**
  50. * @brief Временные флаги инициализации данных
  51. */
  52. static bool fReady[MAX_T_SENSORS];
  53. /**
  54. * @brief Глобальный флаг инициализации данных температурных датчиков
  55. */
  56. bool fTemperDataReady = false;
  57. uint8_t CheckCRC(uint8_t *data, uint8_t len)
  58. {
  59. uint8_t crc = 0;
  60. while (len--) crc = crc_table[crc ^ *data++];
  61. return crc;
  62. }
  63. /**
  64. * @brief Чтение температуры из датчика
  65. */
  66. bool GetTemperature(uint8_t sensor)
  67. {
  68. float temperature = 85.0;
  69. static uint8_t state;
  70. bool dataReady = false;
  71. /* Запускаем преобразование температуры */
  72. #ifdef DALLAS_TWO_LINE_SWITCH
  73. DALLAS_OutSetAsTX(sensor);
  74. #endif
  75. state = DALLAS_Send(sensor, DALLAS_SEND_RESET, (uint8_t *)"\xcc\x44", 2, NULL, 0, DALLAS_NO_READ);
  76. if ((state == DALLAS_ERROR) || (state == DALLAS_NO_DEVICE)) {
  77. sTemperSensors[sensor].ErrorCounter++;
  78. }
  79. #ifdef DALLAS_TWO_LINE_SWITCH
  80. DALLAS_OutSetAsPower(sensor);
  81. #endif
  82. /* Ждем пока датчики закончат преобразование */
  83. vTaskDelay(800);
  84. /* Clear CRC byte */
  85. tBufExt[8] = 0;
  86. /* Чтение температуры */
  87. #ifdef DALLAS_TWO_LINE_SWITCH
  88. DALLAS_OutSetAsTX(sensor);
  89. #endif
  90. state = DALLAS_Send(sensor, DALLAS_SEND_RESET,
  91. (uint8_t *)"\xcc\xbe\xff\xff\xff\xff\xff\xff\xff\xff\xff", 11, tBufExt, 9, 2);
  92. if ((state == DALLAS_ERROR) || (state == DALLAS_NO_DEVICE)) {
  93. sTemperSensors[sensor].ErrorCounter++;
  94. }
  95. /* Check CRC */
  96. if (state == DALLAS_OK) {
  97. /* Sometimes we get DALLAS_OK, and empty tBufExt,
  98. * while sensor surely not connected. For zero filled tBufExt
  99. * CRC is always ok. To detect this, furst check if buffer is empty */
  100. uint8_t sum = 0;
  101. for (uint8_t i = 0; i < sizeof(tBufExt); i++) {
  102. sum |= tBufExt[i];
  103. }
  104. uint8_t crc = CheckCRC(tBufExt, 9);
  105. if ((crc != 0) || (sum == 0)) {
  106. sTemperSensors[sensor].ErrorCounter++;
  107. }
  108. DBG { printf("Sensor %d: ", sensor);
  109. for (uint8_t i = 0; i < 9; i++) printf("0x%X ", tBufExt[i]);
  110. crc ? printf("CRC Fail\r\n") : printf("CRC OK\r\n"); }
  111. }
  112. /* ---------------------------------------------------------------------- */
  113. /* Расчет температуры датчика */
  114. if (!sTemperSensors[sensor].ErrorCounter)
  115. {
  116. tempInt = tBufExt[0];
  117. tempInt |= tBufExt[1] << 8;
  118. /* Если число в дополнительном коде */
  119. if ((tempInt & 0x8000))
  120. {
  121. tempInt = ~tempInt + 1;
  122. temperature = -1*(tempInt/16.0);
  123. }
  124. else {
  125. temperature = tempInt/16.0;
  126. }
  127. DBG printf("temperature: %0.1f\r\n", temperature);
  128. if ((temperature != 85.0) && (temperature != -0.0625)) {
  129. sTemperSensors[sensor].Temperature = temperature;
  130. sTemperSensors[sensor].SensorState = 0;
  131. dataReady = true;
  132. }
  133. sTemperSensors[sensor].ErrorCycle = 0;
  134. }
  135. /* Если были ошибки, то показания тепературы не обновляем */
  136. else
  137. {
  138. sTemperSensors[sensor].ErrorCycle++;
  139. sTemperSensors[sensor].ErrorCounter = 0;
  140. /* Произошло несколько ошибочных циклов общения с датчиком */
  141. /* Выставляем признак отказа датчика */
  142. if (sTemperSensors[sensor].ErrorCycle == ERRORS_LIMIT)
  143. {
  144. sTemperSensors[sensor].SensorState = 1; // Неисправность!
  145. sTemperSensors[sensor].ErrorCycle = 0;
  146. dataReady = true;
  147. }
  148. }
  149. DBG printf("Temperature sensor %d: %0.1f State = %d\r\n\r\n", sensor,
  150. sTemperSensors[sensor].Temperature, sTemperSensors[sensor].SensorState);
  151. return dataReady;
  152. }
  153. /**
  154. * @brief Опрос датчиков температуры
  155. */
  156. void RequestSensors(void) {
  157. bool ready = true;
  158. for (uint8_t i = 0; i < MAX_T_SENSORS; i++) {
  159. ready &= GetTemperature(i);
  160. }
  161. /* Установка глобального флага готовности данных */
  162. if (ready) {
  163. fTemperDataReady = true;
  164. }
  165. }
  166. /**
  167. * @brief Задача чтения температуры 1-wire
  168. */
  169. void vTaskOwire(void *pvParameters)
  170. {
  171. (void)pvParameters;
  172. uint8_t i;
  173. for (i = 0; i < MAX_T_SENSORS; i++) {
  174. sTemperSensors[i].Temperature = 0.0;
  175. sTemperSensors[i].ErrorCounter = 0;
  176. sTemperSensors[i].ErrorCycle = 0;
  177. sTemperSensors[i].SensorState = 1; // По умолчанию устанавливаем признак неисправности
  178. }
  179. DALLAS_Init();
  180. for (;;)
  181. {
  182. RequestSensors();
  183. vTaskDelay(1000);
  184. }
  185. }
  186. void OW_Init(void) {
  187. xTaskCreate(vTaskOwire, "vTaskOwire", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL);
  188. }