| 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);}
 |