#include "temp.h" #include "cmsis_os.h" #include "log_and_debug.h" #include #define F_CODE_DS18S20 0x10 #define F_CODE_DS18B20 0x28 void vSensorTempTask(void *param); struct { TaskHandle_t handler; uint16_t value; }timer_struct = {0}; sensor_temp_typeDef Sensor_Temperature; TaskHandle_t Sensor_tempHandler; GPIO_InitTypeDef GPIO_Sensor_Temp = {0}; void temp_sensor_init(void) { __HAL_RCC_TIM7_CLK_ENABLE(); TIM7->SR = 0; TIM7->PSC = 83; TIM7->ARR = 1; TIM7->DIER |= TIM_DIER_UIE; NVIC_SetPriority(TIM7_IRQn, 5); HAL_GPIO_WritePin(TEMP_GPIO_Port, GPIO_Sensor_Temp.Pin, GPIO_PIN_SET); GPIO_Sensor_Temp.Pin = TEMP_Pin; GPIO_Sensor_Temp.Pull = GPIO_NOPULL; GPIO_Sensor_Temp.Mode = GPIO_MODE_OUTPUT_OD; GPIO_Sensor_Temp.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(TEMP_GPIO_Port, &GPIO_Sensor_Temp); xTaskCreate(vSensorTempTask, "SensorTempTask", 256, NULL, osPriorityNormal, &Sensor_tempHandler); // priority: above normal } void _delay_us(uint16_t delay) { timer_struct.handler = xTaskGetCurrentTaskHandle(); timer_struct.value = delay; ulTaskNotifyTake(pdTRUE, portMAX_DELAY); } void _Sensor_transmit(uint8_t *data, uint8_t size) { uint8_t byte = 0; for(uint8_t i = 0; i < size; i++){ byte = data[i]; for(uint8_t q = 0; q < 8; q++){ HAL_GPIO_WritePin(TEMP_GPIO_Port, GPIO_Sensor_Temp.Pin, GPIO_PIN_RESET); _delay_us(2); if(byte & 0x01) HAL_GPIO_WritePin(TEMP_GPIO_Port, GPIO_Sensor_Temp.Pin, GPIO_PIN_SET); _delay_us(58); HAL_GPIO_WritePin(TEMP_GPIO_Port, GPIO_Sensor_Temp.Pin, GPIO_PIN_SET); _delay_us(2); byte >>= 1; } } } void _Sensor_receive(uint8_t* pData, uint8_t size) { uint8_t byte = 0; for(uint8_t i = 0; i < size; i++){ for(uint8_t q = 0; q < 8; q++){ HAL_GPIO_WritePin(TEMP_GPIO_Port, GPIO_Sensor_Temp.Pin, GPIO_PIN_RESET); _delay_us(2); HAL_GPIO_WritePin(TEMP_GPIO_Port, GPIO_Sensor_Temp.Pin, GPIO_PIN_SET); _delay_us(10); byte |= (HAL_GPIO_ReadPin(TEMP_GPIO_Port, GPIO_Sensor_Temp.Pin) << 7); if(q != 7)byte >>= 1; _delay_us(60); } pData[i] = byte; byte = 0; } } _Bool _Sensor_reset(void) { _Bool fl = 0; HAL_GPIO_WritePin(TEMP_GPIO_Port, GPIO_Sensor_Temp.Pin, GPIO_PIN_RESET); _delay_us(480); HAL_GPIO_WritePin(TEMP_GPIO_Port, GPIO_Sensor_Temp.Pin, GPIO_PIN_SET); _delay_us(65); fl = !HAL_GPIO_ReadPin(TEMP_GPIO_Port, GPIO_Sensor_Temp.Pin); _delay_us(410); return fl; } unsigned char iButtonCRC(uint8_t *code, uint8_t num) { unsigned char j, i, Data, tmp, crc = 0; for (j = 0; j < num; j++){ Data = code[j]; for (i = 0; i < 8; i++){ tmp = 1 & (Data ^ crc); crc >>= 1; Data >>= 1; if (0 != tmp ) crc ^= 0x8c; } } return crc; } void IRQ_Timer_1us(void) { BaseType_t xHigherPriorityTaskWoken = pdFALSE; if(timer_struct.handler != NULL){ if(timer_struct.value != 0) timer_struct.value--; else { vTaskNotifyGiveFromISR(timer_struct.handler, &xHigherPriorityTaskWoken); timer_struct.handler = NULL; } } } void _Timer_1us_Start(void) { TIM7->SR = 0; TIM7->CNT = 0; TIM7->CR1 |= TIM_CR1_CEN; NVIC_ClearPendingIRQ(TIM7_IRQn); NVIC_EnableIRQ(TIM7_IRQn); } void _Timer_1us_Stop(void) { TIM7->CR1 &= ~TIM_CR1_CEN; NVIC_DisableIRQ(TIM7_IRQn); } void vSensorTempTask(void *param) { osDelay(15000); // ждем создание процессов, для правильный задержек таймера enum { STATE_RESET, STATE_READ_ROM, STATE_SKIP_ROM, STATE_TEMP_CONVERT, STATE_READ_TEMP }Sensor_State = STATE_RESET; struct { _Bool wait_convert: 1; _Bool rom_OK: 1; }SensorFlags; char sBuffer[64] = {0}; uint8_t ROM[8] = {0}, sBuffCnt = 0, Sensor_Buffer[16] = {0}; uint8_t DS_family_code = 0; for(;;){ switch(Sensor_State){ case STATE_RESET: // ресет _Timer_1us_Start(); Sensor_Temperature.presence = _Sensor_reset(); if(Sensor_Temperature.presence){ if(!SensorFlags.rom_OK)Sensor_State = STATE_READ_ROM; else Sensor_State = STATE_SKIP_ROM; } else { _Timer_1us_Stop(); SensorFlags.rom_OK = 0; SensorFlags.wait_convert = 0; osDelay(30000); // ждем 30 секунд и проверяем присутствие даитчика } break; case STATE_READ_ROM: Sensor_Buffer[0] = 0x33; _Sensor_transmit(Sensor_Buffer, 1); _Sensor_receive(ROM, 8); if(ROM[7] == iButtonCRC(ROM, 7)){ DS_family_code = ROM[0]; // запоминаем какой датчик установлен for(uint16_t i = 1; i < 7; i++)sBuffCnt += sprintf(&sBuffer[sBuffCnt], "%02X", ROM[i]); __debug(DEBUG_TEMP, "DS1820: Family code: %02X, serial number: %s\r\n", DS_family_code, sBuffer); SensorFlags.rom_OK = 1; } else { _Timer_1us_Stop(); __debug(DEBUG_TEMP, "DS1820: ROM error CRC.\r\n"); osDelay(10000); } Sensor_State = STATE_RESET; break; case STATE_SKIP_ROM: // пропуск ROM кода Sensor_Buffer[0] = 0xCC; _Sensor_transmit(Sensor_Buffer, 1); if(!SensorFlags.wait_convert)Sensor_State = STATE_TEMP_CONVERT; else Sensor_State = STATE_READ_TEMP; break; case STATE_TEMP_CONVERT: // Конвертация температуры Sensor_Buffer[0] = 0x44; _Sensor_transmit(Sensor_Buffer, 1); // Convert T _Timer_1us_Stop(); SensorFlags.wait_convert = 1; Sensor_State = STATE_RESET; osDelay(1000); break; case STATE_READ_TEMP: // Чтение температуры Sensor_Buffer[0] = 0xBE; _Sensor_transmit(Sensor_Buffer, 1); // Read Scratchpad _Sensor_receive(Sensor_Buffer, 9); _Timer_1us_Stop(); if (Sensor_Buffer[8] == (uint8_t)iButtonCRC(Sensor_Buffer, 8)){ switch(DS_family_code){ case F_CODE_DS18S20: Sensor_Temperature.sign = Sensor_Buffer[1]; if((Sensor_Buffer[0] & 0x01) == 0x01) Sensor_Temperature.share = 5; else Sensor_Temperature.share = 0; if(Sensor_Temperature.sign)Sensor_Temperature.info = ((Sensor_Buffer[0] ^ 0xFF) + 1) >> 1; // отрицательная else Sensor_Temperature.info = Sensor_Buffer[0] >> 1; break; case F_CODE_DS18B20: if((Sensor_Buffer[0] & 0x0F) == 0x08) Sensor_Temperature.share = 5; else Sensor_Temperature.share = 0; Sensor_Temperature.sign = Sensor_Buffer[1] >> 3; Sensor_Temperature.info = Sensor_Buffer[0] >> 4; Sensor_Temperature.info |= (Sensor_Buffer[1] << 4); if(Sensor_Temperature.sign) Sensor_Temperature.info ^= 0xFF; Sensor_Temperature.info &= ~0x80; break; } __debug(DEBUG_TEMP, "DS1820: Temperature %c%d.%d C\r\n", Sensor_Temperature.sign ? '-' : ' ', Sensor_Temperature.info, Sensor_Temperature.share); osDelay(60000); } else { __debug(DEBUG_TEMP, "DS1820: Temperature CRC error.\r\n"); osDelay(1000); } Sensor_State = STATE_RESET; SensorFlags.wait_convert = 0; break; } } }