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