From 8c97955b0664837b9fdff30bc1f2867d74216437 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D1=8F=D1=87=D0=B5=D1=81=D0=BB=D0=B0=D0=B2=20=D0=A8?= =?UTF-8?q?=D1=82=D0=B5=D0=B9=D0=B1=D0=B5=D0=B7=D0=B0=D0=BD=D0=B4=D1=82?= Date: Wed, 8 Jul 2026 15:12:58 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=BE=20=D1=82=D1=80=D0=B8=20=D0=B2=D0=B0=D1=80=D0=B8?= =?UTF-8?q?=D0=B0=D0=BD=D1=82=D0=B0=20=D0=BF=D1=80=D0=B8=D1=91=D0=BC=D0=B0?= =?UTF-8?q?=20CAN=20(=D0=91=D0=B5=D1=81=D0=BA=D0=BE=D0=BD=D0=B5=D1=87?= =?UTF-8?q?=D0=BD=D1=8B=D0=B9,=20=D0=B2=D1=81=D0=B5=20=D1=81=D0=BE=D0=BE?= =?UTF-8?q?=D0=B1=D1=89=D0=B5=D0=BD=D0=B8=D1=8F,=20=D0=BE=D0=B4=D0=BD?= =?UTF-8?q?=D0=BE=20=D1=81=D0=BE=D0=BE=D0=B1=D1=89=D0=B5=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Core/Inc/protocan.h | 6 +- Core/Src/main.c | 2 +- Core/Src/protocan.c | 219 ++++++++++++++++++++++++++++++---------- MDK-ARM/F103C8T6/main.o | Bin 5588 -> 5600 bytes 4 files changed, 172 insertions(+), 55 deletions(-) diff --git a/Core/Inc/protocan.h b/Core/Inc/protocan.h index 55a225c..99fa270 100644 --- a/Core/Inc/protocan.h +++ b/Core/Inc/protocan.h @@ -275,7 +275,9 @@ PROTOCAN_INIT_StatusTypeDef PROTOCAN_INIT(CAN_HandleTypeDef *tmp_hcan, TIM_HandleTypeDef *tmp_tim); void PROTOCAN_DEINIT(uint8_t stage); void PROTOCAN_FILTERS(void); -void PROTOCAN_LOOP(void); +void PROTOCAN_LoopProcessRxMsgs(void); +PROTOCAN_StatusTypeDef PROTOCAN_ProcessAllRxMsgs(void); +PROTOCAN_StatusTypeDef PROTOCAN_ProcessSingleRxMsg(void); PROTOCAN_StatusTypeDef PROTOCAN_SEND(ProtoCanId_t id, ProtoCanData_t data); void ProtoCanPulseCallback(TIM_HandleTypeDef *htim); @@ -305,7 +307,7 @@ PROTOCAN_StatusTypeDef ProtoCanMsgToAnalogTSens(struct RXMsg _rxMsg); PROTOCAN_StatusTypeDef ProtoCanMsgToGeneralAddressSpace(struct RXMsg _rxMsg); -PROTOCAN_StatusTypeDef CanRequestError(struct RXMsg _rxMsg); +PROTOCAN_StatusTypeDef PROTOCAN_RequestError(struct RXMsg _rxMsg); PROTOCAN_StatusTypeDef PROTOCAN_ModbusProcessing(struct RXMsg _rxMsg); PROTOCAN_StatusTypeDef ProtoCanMsgToModbusCoil(struct RXMsg _rxMsg); diff --git a/Core/Src/main.c b/Core/Src/main.c index 6c96e2d..96b2ff5 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -96,7 +96,7 @@ int main(void) { HAL_CAN_Start(&hcan); HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING | CAN_IT_ERROR | CAN_IT_BUSOFF | CAN_IT_LAST_ERROR_CODE); - PROTOCAN_LOOP(); + PROTOCAN_LoopProcessRxMsgs(); } /* USER CODE END 2 */ diff --git a/Core/Src/protocan.c b/Core/Src/protocan.c index 2d4f861..b5dcb5a 100644 --- a/Core/Src/protocan.c +++ b/Core/Src/protocan.c @@ -111,50 +111,165 @@ PROTOCAN_INIT_StatusTypeDef PROTOCAN_INIT(CAN_HandleTypeDef *tmp_hcan, RTC_Handl } /** -* @brief Функция с обработкой полученных запросов -* @details В бесконечном цикле функция ожидает приёма сообщения. После этого сообщение распределяется в зависимости от DataType. -* Обработка запроса аналоговых значений - PROTOCAN_AnalogProcessing(). -* Обработка широковещательных запросов - PROTOCAN_BroadcastProcessing(). -* Обработка запроса дискретных значений - PROTOCAN_DiscreticProcessing(). -* Обработка запроса к общему адресному пространству - PROTOCAN_GeneralAddressSpace_Answer(). -* Обработка Modbus - PROTOCAN_ModbusProcessing(). -*/ -void PROTOCAN_LOOP(void) + * @brief Бесконечный цикл обработки входящих CAN-сообщений. + * + * Эта функция постоянно проверяет наличие доступных сообщений в буфере CAN и + * вызывает соответствующие обработчики в зависимости от типа полученного сообщения. + * Обрабатываемые типы сообщений: + * - Аналоговые данные + * - Широковещательные сообщения + * - Дискретные данные + * - Общее адресное пространство + * - Модбас сообщения + * - Ошибки + * + * Обработка сообщений осуществляется внутри бесконечного цикла с использованием + * функции AvailableCanRxMsg() для определения наличия новых сообщений. + * + * В конце каждого обработанного сообщения индекс текущего элемента буфера инкрементируется + * с учетом размера буфера через операцию по модулю. + */ +void PROTOCAN_LoopProcessRxMsgs(void) { - while(1) + while(1) + { + if(AvailableCanRxMsg()) + { + if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_ANALOG) + { + PROTOCAN_AnalogProcessing(rxMsg[CurrentStep]); + } + else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_BROADCAST) + { + PROTOCAN_BroadcastProcessing(rxMsg[CurrentStep]); + } + else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_DISCRETE) + { + PROTOCAN_DiscreticProcessing(rxMsg[CurrentStep]); + } + else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_GENERAL_ADDRESS_SPACE) + { + ProtoCanMsgToGeneralAddressSpace(rxMsg[CurrentStep]); + } + else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_MODBUS_COIL || + rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_MODBUS_DISCRETE || + rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_MODBUS_HOLDING || + rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_MODBUS_INPUT) + { + PROTOCAN_ModbusProcessing(rxMsg[CurrentStep]); + } + else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_ERROR) + { + PROTOCAN_RequestError(rxMsg[CurrentStep]); + } + // Обновление индекса текущего сообщения с циклическим масштабированием + CurrentStep = (uint16_t)(CurrentStep + 1) % PROTOCAN_RX_BUFFER_SIZE; + } + } +} + +/** + * @brief Обрабатывает все доступные входящие CAN-сообщения. + * + * Эта функция последовательно обрабатывает все сообщения, доступные в буфере, + * вызывая соответствующие функции обработчики в зависимости от типа сообщения. + * После обработки каждого сообщения индекс текущего элемента буфера обновляется + * циклически. + * + * @return PROTOCAN_OK, если все сообщения были обработаны успешно. + * В противном случае возвращается код ошибки, полученный при обработке сообщения. + * + * Обработка происходит до тех пор, пока есть доступные сообщения, полученные функцией + * AvailableCanRxMsg(). + */ +PROTOCAN_StatusTypeDef PROTOCAN_ProcessAllRxMsgs(void) +{ + PROTOCAN_StatusTypeDef result = PROTOCAN_TIMEOUT; + while(AvailableCanRxMsg()) { - if(AvailableCanRxMsg()) + if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_ANALOG) { - if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_ANALOG) - { - PROTOCAN_AnalogProcessing(rxMsg[CurrentStep]); - } - else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_BROADCAST) - { - PROTOCAN_BroadcastProcessing(rxMsg[CurrentStep]); - } - else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_DISCRETE) - { - PROTOCAN_DiscreticProcessing(rxMsg[CurrentStep]); - } - else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_GENERAL_ADDRESS_SPACE) - { - ProtoCanMsgToGeneralAddressSpace(rxMsg[CurrentStep]); - } - else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_MODBUS_COIL || - rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_MODBUS_DISCRETE || - rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_MODBUS_HOLDING || - rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_MODBUS_INPUT) - { - PROTOCAN_ModbusProcessing(rxMsg[CurrentStep]); - } - else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_ERROR) - { - CanRequestError(rxMsg[CurrentStep]); - } - CurrentStep = (uint16_t)(CurrentStep + 1) % PROTOCAN_RX_BUFFER_SIZE; + result = PROTOCAN_AnalogProcessing(rxMsg[CurrentStep]); + } + else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_BROADCAST) + { + result = PROTOCAN_BroadcastProcessing(rxMsg[CurrentStep]); + } + else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_DISCRETE) + { + result = PROTOCAN_DiscreticProcessing(rxMsg[CurrentStep]); + } + else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_GENERAL_ADDRESS_SPACE) + { + result = ProtoCanMsgToGeneralAddressSpace(rxMsg[CurrentStep]); + } + else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_MODBUS_COIL || + rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_MODBUS_DISCRETE || + rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_MODBUS_HOLDING || + rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_MODBUS_INPUT) + { + result = PROTOCAN_ModbusProcessing(rxMsg[CurrentStep]); + } + else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_ERROR) + { + result = PROTOCAN_RequestError(rxMsg[CurrentStep]); + } + CurrentStep = (uint16_t)(CurrentStep + 1) % PROTOCAN_RX_BUFFER_SIZE; + if(result != PROTOCAN_OK) + { + return result; } } + return result; +} + +/** + * @brief Обрабатывает одно доступное CAN-сообщение. + * + * Эта функция проверяет наличие доступных сообщений в буфере и, если таковое есть, + * выполняет обработку текущего сообщения в зависимости от его типа. После обработки + * индекс текущего сообщения обновляется циклически. + * + * @return Прошедший статус обработки: + * - PROTOCAN_OK, если сообщение успешно обработано, + * - PROTOCAN_TIMEOUT, если сообщений не было, + * - или код ошибки, возвращенный функцией обработки. + */ +PROTOCAN_StatusTypeDef PROTOCAN_ProcessSingleRxMsg(void) +{ + PROTOCAN_StatusTypeDef result = PROTOCAN_TIMEOUT; + if(AvailableCanRxMsg()) + { + if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_ANALOG) + { + result = PROTOCAN_AnalogProcessing(rxMsg[CurrentStep]); + } + else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_BROADCAST) + { + result = PROTOCAN_BroadcastProcessing(rxMsg[CurrentStep]); + } + else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_DISCRETE) + { + result = PROTOCAN_DiscreticProcessing(rxMsg[CurrentStep]); + } + else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_GENERAL_ADDRESS_SPACE) + { + result = ProtoCanMsgToGeneralAddressSpace(rxMsg[CurrentStep]); + } + else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_MODBUS_COIL || + rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_MODBUS_DISCRETE || + rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_MODBUS_HOLDING || + rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_MODBUS_INPUT) + { + result = PROTOCAN_ModbusProcessing(rxMsg[CurrentStep]); + } + else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_ERROR) + { + result = PROTOCAN_RequestError(rxMsg[CurrentStep]); + } + CurrentStep = (uint16_t)(CurrentStep + 1) % PROTOCAN_RX_BUFFER_SIZE; + } + return result; } /** @@ -568,10 +683,10 @@ __weak PROTOCAN_StatusTypeDef ProtoCanMsgToAnalogUSens(struct RXMsg _rxMsg) msg.Body = _rxMsg.eID.Fields.MsgBody; data[0] = 'U'; data[1] = 'S'; - data[2] = 47 + msg.Fields.SensorID / 1000; - data[3] = 47 + msg.Fields.SensorID / 100 % 10; - data[4] = 47 + msg.Fields.SensorID / 10 % 10; - data[5] = 47 + msg.Fields.SensorID % 10; + data[2] = '0' + msg.Fields.SensorID / 1000; + data[3] = '0' + msg.Fields.SensorID / 100 % 10; + data[4] = '0' + msg.Fields.SensorID / 10 % 10; + data[5] = '0' + msg.Fields.SensorID % 10; return (PROTOCAN_StatusTypeDef)HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox); } @@ -598,10 +713,10 @@ __weak PROTOCAN_StatusTypeDef ProtoCanMsgToAnalogISens(struct RXMsg _rxMsg) msg.Body = _rxMsg.eID.Fields.MsgBody; data[0] = 'I'; data[1] = 'S'; - data[2] = 47 + msg.Fields.SensorID / 1000; - data[3] = 47 + msg.Fields.SensorID / 100 % 10; - data[4] = 47 + msg.Fields.SensorID / 10 % 10; - data[5] = 47 + msg.Fields.SensorID % 10; + data[2] = '0' + msg.Fields.SensorID / 1000; + data[3] = '0' + msg.Fields.SensorID / 100 % 10; + data[4] = '0' + msg.Fields.SensorID / 10 % 10; + data[5] = '0' + msg.Fields.SensorID % 10; return (PROTOCAN_StatusTypeDef)HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox); } @@ -628,10 +743,10 @@ __weak PROTOCAN_StatusTypeDef ProtoCanMsgToAnalogTSens(struct RXMsg _rxMsg) msg.Body = _rxMsg.eID.Fields.MsgBody; data[0] = 'T'; data[1] = 'S'; - data[2] = 47 + msg.Fields.SensorID / 1000; - data[3] = 47 + msg.Fields.SensorID / 100 % 10; - data[4] = 47 + msg.Fields.SensorID / 10 % 10; - data[5] = 47 + msg.Fields.SensorID % 10; + data[2] = '0' + msg.Fields.SensorID / 1000; + data[3] = '0' + msg.Fields.SensorID / 100 % 10; + data[4] = '0' + msg.Fields.SensorID / 10 % 10; + data[5] = '0' + msg.Fields.SensorID % 10; return (PROTOCAN_StatusTypeDef)HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox); } @@ -1085,7 +1200,7 @@ PROTOCAN_StatusTypeDef PROTOCAN_SEND_MODBUS(const ProtoCanId_t id, const struct * @param _rxMsg Структура входящего сообщения RXMsg, данными которого формируется ответ-ошибка. * @return HAL_StatusTypeDef Статус выполнения команды CAN. */ -__weak PROTOCAN_StatusTypeDef CanRequestError(struct RXMsg _rxMsg) +__weak PROTOCAN_StatusTypeDef PROTOCAN_RequestError(struct RXMsg _rxMsg) { CAN_TxHeaderTypeDef TxHeader; uint32_t TxMailBox = 0; diff --git a/MDK-ARM/F103C8T6/main.o b/MDK-ARM/F103C8T6/main.o index 0854f375ee4f06ae4494e6b3344f3fd417d810c7..d43b5c68c92f84c98ac7aee879dc441a8a76ddc2 100644 GIT binary patch delta 452 zcmcbj{Xlzy0%OER#lxITQcRPdamq2qPiEzkXN;Px3M4}(yK=<~x-c>@01-nP5DPIe zGi;r_l`G!R6C?x$0zg`n3C3e!0P+3N_=b~Rx#jCw&~$YnG=X*5qv6;x-mn*0_>s!kRaQfE}0YzrjUPfi7r zt0(sY$&Sfefn>|%yFl{6WL9By#%q&xf#jvhp~B^iKPI0AvcF9J3M6+#+Z5p^aGrpbJwYD_Fllg&icfcj!ZLHb&Oq~_$cqUr!ozf-mV delta 422 zcmaE$eMNhM0;A7H#lxIT{~0GgaWMdfdP%srcV^GyC(jJyFs{vrO(j(+hz{{8`zjRgIe7}zE^3JNoZ zPo64h&8R&2qM$mX{N$fNl54V}kUAsVWKSSDWpW{qoG^JNkj$NY5J+ZDehDOxP8Jka zXWTv65=d^JoG4t*cz5zmAp7QIMiF(!d6PAP54X7_u6r^t=kmQ@ZQ&b%QK@3er