/** ****************************************************************************** * @file pch_sensors.c * @brief Работа с датчиками температуры DS18B20 в ПЧ *****************************************************************************/ /* Includes ----------------------------------------------------------------*/ #include "PY32module_main.h" #include "rs_message.h" /* Declarations and definitions --------------------------------------------*/ PCHSens_TypeDef pchsens; PCHSens_DallasBusHandle DallasBus; static uint8_t scan_cnt; /* Functions ---------------------------------------------------------------*/ void PYModule_FillResponse(PCHSens_SensorTypeDef* sensor, Sensor_ResponseStatusTypeDef status); void PYModule_CheckModuleLosted(PCHSens_ModuleTypeDef *module, uint8_t *losted_flag); void PYModule_StoreModuleToModbus(PCHSens_ModuleTypeDef *module); void PYModule_main(void) { if(MB_DATA.Coils.RunConvertions) { if(DS18B20_WaitForEndConvertion_NonBlocking(hdallas1.onewire) == HAL_OK) { PCHSens_StartCovert(&DallasBus); GPIOA->ODR ^= GPIO_LED_2; } } if(MB_DATA.Coils.ReadSensor) { PYModule_ReadSensor(&hdallas1, &pchsens); MB_DATA.Coils.ReadSensor = 0; } // if(MB_DATA.Coils.ScanSensors) // { // PYModule_ScanSensor(&DallasBus); // } // else // { // scan_cnt = 0; // } if(MB_DATA.Coils.InitSensor) { PYModule_InitSensor(&pchsens); MB_DATA.Coils.InitSensor = 0; } if(MB_DATA.Coils.DeInitSensor != NULL) { PYModule_DeInitSensor(&pchsens); MB_DATA.Coils.DeInitSensor = 0; } PYModule_CheckLosted(&pchsens); if(MB_DATA.Coils.RunConvertions) { if(DS18B20_WaitForEndConvertion_NonBlocking(hdallas1.onewire) == HAL_OK) { PCHSens_ModuleReadTemperature(&pchsens.module1); // PCHSens_ModuleReadTemperature(&pchsens.module2); // PCHSens_ModuleReadTemperature(&pchsens.module3); // PCHSens_ModuleReadTemperature(&pchsens.module4); // PCHSens_ModuleReadTemperature(&pchsens.module5); // PCHSens_ModuleReadTemperature(&pchsens.module6); PYModule_StoreModbus(&pchsens); } } } void PYModule_FirstInit(void) { OW.DataPin = DS_Pin; OW.DataPort = DS_GPIO_Port; /* Инициализация onewire и поиск датчиков*/ DS = (DS18B20_Drv_t *)&MB_DATA.InRegs.AllROMs; OneWire_Init(&OW); DS18B20_Search(DS, &OW); /* Инициализация modbus */ MODBUS_FirstInit(); RS_Receive_IT(&hmodbus1, &MODBUS_MSG); /* Инициализация структур датчиков ПЧ */ DallasBus.hdallas = &hdallas1; DallasBus.hdallas->onewire = &OW; DallasBus.hdallas->ds_devices = DS; PCHSens_InitModule(&hdallas1, &pchsens.module1, REG_PCH_NUMB_11|REG_PCH_DIODE_NUMB_1); // PCHSens_InitModule(&hdallas1, &pchsens.module2, REG_PCH_NUMB_12|REG_PCH_DIODE_NUMB_1); // PCHSens_InitModule(&hdallas1, &pchsens.module3, REG_PCH_NUMB_21|REG_PCH_DIODE_NUMB_1); // PCHSens_InitModule(&hdallas1, &pchsens.module4, REG_PCH_NUMB_22|REG_PCH_DIODE_NUMB_1); // PCHSens_InitModule(&hdallas1, &pchsens.module5, REG_PCH_NUMB_31|REG_PCH_DIODE_NUMB_1); // PCHSens_InitModule(&hdallas1, &pchsens.module6, REG_PCH_NUMB_32|REG_PCH_DIODE_NUMB_1); /* Поиск неизвестных сенсоров */ PCHSens_FindUnknownSensors(&DallasBus); MB_DATA.Coils.RunConvertions = 1; } void PYModule_ScanSensor(PCHSens_DallasBusHandle *hbus) { PCHSens_SensorTypeDef sensor; sensor.sens.hdallas = hbus->hdallas; sensor.sens.sensROM = *(uint64_t *)(hbus->hdallas->ds_devices->DevAddr[scan_cnt]); if (scan_cnt >= hbus->hdallas->onewire->RomCnt) { scan_cnt = hbus->hdallas->onewire->RomCnt; PYModule_FillResponse(&sensor, STATUS_SCAN_END); return; } if(Dallas_ReadScratchpad(&sensor.sens) == HAL_OK) { PYModule_FillResponse(&sensor, STATUS_OK); } else { PYModule_FillResponse(&sensor, STATUS_ERR_SCAN); } } void PYModule_IncrementScanSensor(void) { if(MB_DATA.Coils.ScanSensors) { scan_cnt++; } } void PYModule_ReadSensor(DALLAS_HandleTypeDef *hdallas, PCHSens_TypeDef *pchsens) { // чтение по локации if(MB_DATA.HoldRegs.InitStruct.Location != 0) // если локация не равна нулю { PCHSens_SensorTypeDef *sensor; if(PCHSens_GetSensorByLocation(pchsens, (PCHSens_LocationTypeDef)MB_DATA.HoldRegs.InitStruct.Location, &sensor) != HAL_OK) return; if(Dallas_ReadScratchpad(&sensor->sens) == HAL_OK) { PYModule_FillResponse(sensor, STATUS_OK); } else { PYModule_FillResponse(sensor, STATUS_ERR_READ_LOCATION); } } // чтение по ROM else if(MB_DATA.HoldRegs.InitStruct.ROM[0] | MB_DATA.HoldRegs.InitStruct.ROM[1] | // если РОМ не равен нулю MB_DATA.HoldRegs.InitStruct.ROM[2] | MB_DATA.HoldRegs.InitStruct.ROM[3] != 0) { PCHSens_SensorTypeDef sensor; sensor.sens.hdallas = hdallas; sensor.sens.sensROM = *(uint64_t *)MB_DATA.HoldRegs.InitStruct.ROM; if(Dallas_ReadScratchpad(&sensor.sens) == HAL_OK) { PYModule_FillResponse(&sensor, STATUS_OK); } else { PYModule_FillResponse(&sensor, STATUS_ERR_READ_ROM); } } } void PYModule_InitSensor(PCHSens_TypeDef *pchsens) { if( (MB_DATA.HoldRegs.InitStruct.Location != 0) && // если локация не равна нулю (MB_DATA.HoldRegs.InitStruct.ROM[0] | MB_DATA.HoldRegs.InitStruct.ROM[1] | // И если РОМ не равен нулю MB_DATA.HoldRegs.InitStruct.ROM[2] | MB_DATA.HoldRegs.InitStruct.ROM[3] != 0) ) { PCHSens_SensorTypeDef *sensor; if(PCHSens_GetSensorByLocation(pchsens, (PCHSens_LocationTypeDef)MB_DATA.HoldRegs.InitStruct.Location, &sensor) != HAL_OK) return; uint64_t connectROM = 0; connectROM = ((uint64_t)(__REV16(MB_DATA.HoldRegs.InitStruct.ROM[0])))<<48; connectROM |= ((uint64_t)(__REV16(MB_DATA.HoldRegs.InitStruct.ROM[1])))<<32; connectROM |= ((uint64_t)(__REV16(MB_DATA.HoldRegs.InitStruct.ROM[2])))<<16; connectROM |= ((uint64_t)(__REV16(MB_DATA.HoldRegs.InitStruct.ROM[3]))); if(PCHSens_InitNewSensor(&hdallas1, sensor, connectROM) == HAL_OK) { PYModule_FillResponse(sensor, STATUS_OK); } else { PYModule_FillResponse(sensor, STATUS_ERR_INIT); } } } void PYModule_DeInitSensor(PCHSens_TypeDef *pchsens) { if(MB_DATA.HoldRegs.InitStruct.Location != 0) // если локация не равна нулю { PCHSens_SensorTypeDef *sensor; if(PCHSens_GetSensorByLocation(pchsens, (PCHSens_LocationTypeDef)MB_DATA.HoldRegs.InitStruct.Location, &sensor) != HAL_OK) return; if(PCHSens_UndefineSensor(sensor) == HAL_OK) { PYModule_FillResponse(sensor, STATUS_OK); } else { PYModule_FillResponse(sensor, STATUS_ERR_DEINIT); } } } void PYModule_CheckLosted(PCHSens_TypeDef *pchsens) { uint8_t losted = 0; // module1 PYModule_CheckModuleLosted(&pchsens->module1, &losted); PYModule_CheckModuleLosted(&pchsens->module2, &losted); PYModule_CheckModuleLosted(&pchsens->module3, &losted); PYModule_CheckModuleLosted(&pchsens->module4, &losted); PYModule_CheckModuleLosted(&pchsens->module5, &losted); PYModule_CheckModuleLosted(&pchsens->module6, &losted); if(losted) MB_DATA.Coils.LostedSensors = 1; else MB_DATA.Coils.LostedSensors = 0; } void PYModule_StoreModbus(PCHSens_TypeDef *pchsens) { uint8_t losted = 0; // module1 PYModule_StoreModuleToModbus(&pchsens->module1); PYModule_StoreModuleToModbus(&pchsens->module2); PYModule_StoreModuleToModbus(&pchsens->module3); PYModule_StoreModuleToModbus(&pchsens->module4); PYModule_StoreModuleToModbus(&pchsens->module5); PYModule_StoreModuleToModbus(&pchsens->module6); MB_DATA.Coils.ConvertionDone |= 1; } void PYModule_FillResponse(PCHSens_SensorTypeDef* sensor, Sensor_ResponseStatusTypeDef status) { switch(status) { // successfull response case STATUS_OK: // fil with sensor data MB_DATA.InRegs.Response.Location = *(uint16_t *)&sensor->sens.hdallas->scratchpad.tHighRegister; MB_DATA.InRegs.Response.Config = sensor->sens.hdallas->scratchpad.ConfigRegister; MB_DATA.InRegs.Response.ROM[0] = __REV16((sensor->sens.sensROM) & 0xFFFF); MB_DATA.InRegs.Response.ROM[1] = __REV16((sensor->sens.sensROM >> 16) & 0xFFFF); MB_DATA.InRegs.Response.ROM[2] = __REV16((sensor->sens.sensROM >> 32) & 0xFFFF); MB_DATA.InRegs.Response.ROM[3] = __REV16((sensor->sens.sensROM >> 48) & 0xFFFF); MB_DATA.InRegs.Response.Status = status; break; case STATUS_SCAN_END: MB_DATA.InRegs.Response.Location = 0; MB_DATA.InRegs.Response.Config = 0; MB_DATA.InRegs.Response.ROM[0] = 0; MB_DATA.InRegs.Response.ROM[1] = 0; MB_DATA.InRegs.Response.ROM[2] = 0; MB_DATA.InRegs.Response.ROM[3] = 0; MB_DATA.InRegs.Response.Status = status; break; // error read by location case STATUS_ERR_READ_LOCATION: // fill only location from holdreg MB_DATA.InRegs.Response.Location = MB_DATA.HoldRegs.InitStruct.Location; MB_DATA.InRegs.Response.Config = 0; MB_DATA.InRegs.Response.ROM[0] = 0; MB_DATA.InRegs.Response.ROM[1] = 0; MB_DATA.InRegs.Response.ROM[2] = 0; MB_DATA.InRegs.Response.ROM[3] = 0; MB_DATA.InRegs.Response.Status = status; break; // error read by ROM case STATUS_ERR_READ_ROM: // fill only ROM from holdreg MB_DATA.InRegs.Response.Location = 0; MB_DATA.InRegs.Response.Config = 0; MB_DATA.InRegs.Response.ROM[0] = MB_DATA.HoldRegs.InitStruct.ROM[0]; MB_DATA.InRegs.Response.ROM[1] = MB_DATA.HoldRegs.InitStruct.ROM[1]; MB_DATA.InRegs.Response.ROM[2] = MB_DATA.HoldRegs.InitStruct.ROM[2]; MB_DATA.InRegs.Response.ROM[3] = MB_DATA.HoldRegs.InitStruct.ROM[3]; MB_DATA.InRegs.Response.Status = status; break; // error init case STATUS_ERR_INIT: // fill ROM and location from holdreg MB_DATA.InRegs.Response.Location = MB_DATA.HoldRegs.InitStruct.Location; MB_DATA.InRegs.Response.Config = 0; MB_DATA.InRegs.Response.ROM[0] = MB_DATA.HoldRegs.InitStruct.ROM[0]; MB_DATA.InRegs.Response.ROM[1] = MB_DATA.HoldRegs.InitStruct.ROM[1]; MB_DATA.InRegs.Response.ROM[2] = MB_DATA.HoldRegs.InitStruct.ROM[2]; MB_DATA.InRegs.Response.ROM[3] = MB_DATA.HoldRegs.InitStruct.ROM[3]; MB_DATA.InRegs.Response.Status = status; break; // error deinit case STATUS_ERR_DEINIT: // fill with sensor data MB_DATA.InRegs.Response.Location = *(uint16_t *)&sensor->sens.hdallas->scratchpad.tHighRegister; MB_DATA.InRegs.Response.Config = sensor->sens.hdallas->scratchpad.ConfigRegister; MB_DATA.InRegs.Response.ROM[0] = __REV16((sensor->sens.sensROM) & 0xFFFF); MB_DATA.InRegs.Response.ROM[1] = __REV16((sensor->sens.sensROM >> 16) & 0xFFFF); MB_DATA.InRegs.Response.ROM[2] = __REV16((sensor->sens.sensROM >> 32) & 0xFFFF); MB_DATA.InRegs.Response.ROM[3] = __REV16((sensor->sens.sensROM >> 48) & 0xFFFF); MB_DATA.InRegs.Response.Status = status; break; // error deinit case STATUS_ERR_SCAN: // fill with sensor data MB_DATA.InRegs.Response.Location = 0; MB_DATA.InRegs.Response.Config = 0; MB_DATA.InRegs.Response.ROM[0] = __REV16((sensor->sens.sensROM) & 0xFFFF); MB_DATA.InRegs.Response.ROM[1] = __REV16((sensor->sens.sensROM >> 16) & 0xFFFF); MB_DATA.InRegs.Response.ROM[2] = __REV16((sensor->sens.sensROM >> 32) & 0xFFFF); MB_DATA.InRegs.Response.ROM[3] = __REV16((sensor->sens.sensROM >> 48) & 0xFFFF); MB_DATA.InRegs.Response.Status = status; break; default: MB_DATA.InRegs.Response.Location = 0; MB_DATA.InRegs.Response.Config = 0; MB_DATA.InRegs.Response.ROM[0] = 0; MB_DATA.InRegs.Response.ROM[1] = 0; MB_DATA.InRegs.Response.ROM[2] = 0; MB_DATA.InRegs.Response.ROM[3] = 0; MB_DATA.InRegs.Response.Status = 0; break; } } void PYModule_CheckModuleLosted(PCHSens_ModuleTypeDef *module, uint8_t *losted_flag) { if(module->sens1.not_found) *losted_flag |= 1; if(module->sens2.not_found) *losted_flag |= 1; if(module->sens3.not_found) *losted_flag |= 1; if(module->sens4.not_found) *losted_flag |= 1; } void PYModule_StoreModuleToModbus(PCHSens_ModuleTypeDef *module) { uint8_t mb_location; uint8_t pch_numb = (module->refLocation.param.PCHdig1 - 1)*3 + (module->refLocation.param.PCHdig2 - 1); pch_numb *= 4; mb_location = pch_numb + module->sens1.Location.param.Location; if (mb_location < DS18B20_DEVICE_AMOUNT) MB_DATA.InRegs.SensTemperature[mb_location] = module->sens1.sens.temperature*100; mb_location = pch_numb + module->sens2.Location.param.Location; if (mb_location < DS18B20_DEVICE_AMOUNT) MB_DATA.InRegs.SensTemperature[mb_location] = module->sens2.sens.temperature*100; mb_location = pch_numb + module->sens3.Location.param.Location; if (mb_location < DS18B20_DEVICE_AMOUNT) MB_DATA.InRegs.SensTemperature[mb_location] = module->sens3.sens.temperature*100; mb_location = pch_numb + module->sens4.Location.param.Location; if (mb_location < DS18B20_DEVICE_AMOUNT) MB_DATA.InRegs.SensTemperature[mb_location] = module->sens4.sens.temperature*100; }