Modbus 0.3
Библиотека Modbus для STM
Loading...
Searching...
No Matches
modbus_slave.c
Go to the documentation of this file.
1/**
2*******************************************************************************
3* @file modbus_slave.c
4* @brief Модуль для реализации слейв MODBUS.
5*******************************************************************************
6* @details
7Файл содержит реализацию функций для работы Modbus в режиме слейва.
8
9@section slave Функции и макросы
10
11- MB_Slave_Response() — Ответ на запрос
12- MB_Slave_Collect_Message() — Сбор сообщения в режиме слейва.
13- MB_Slave_Parse_Message() — Парс сообщения в режиме слейва.
14******************************************************************************/
15#include "modbus.h"
16
17#ifdef MODBUS_ENABLE_SLAVE
18/**
19 * @brief Ответ на сообщение в режиме слейва.
20 * @param hmodbus Указатель на хендлер RS.
21 * @param modbus_msg Указатель на структуру сообщения.
22 * @return RS_RES Статус о результате ответа на комманду.
23 */
25{
26 RS_StatusTypeDef MB_RES = 0;
27 hmodbus->f.MessageHandled = 0;
28 hmodbus->f.EchoResponse = 0;
29 RS_Reset_TX_Flags(hmodbus); // reset flag for correct transmit
30
32 if(hmodbus->ID == 0 || modbus_msg->MbAddr == 0)
33 {
34 MB_Diagnostics_SlaveNoResponseCnt(); // <-- Устройство не отвечает на широковещательные сообщения
35 hmodbus->RS_STATUS = RS_SKIP;
36 return RS_Handle_Receive_Start(hmodbus, modbus_msg);
37 }
39
40 if(modbus_msg->FuncCode < FC_ERR_VALUES_START)// if no errors after parsing
41 {
42 switch (modbus_msg->FuncCode)
43 {
44 // Read Coils
45 case FC_R_COILS:
47 break;
48
49 // Read Hodling Registers
50 case FC_R_HOLD_REGS:
52 break;
53 case FC_R_IN_REGS:
55 break;
56
57
58 // Write Single Coils
59 case FC_W_COIL:
61 if(hmodbus->f.MessageHandled)
62 {
63 hmodbus->f.DataUpdated = 1;
64 hmodbus->f.EchoResponse = 1;
65 hmodbus->RS_Message_Size -= 2; // echo response if write ok (minus 2 cause of two CRC bytes)
66 }
67 break;
68
69 case FC_W_HOLD_REG:
71 if(hmodbus->f.MessageHandled)
72 {
73 hmodbus->f.DataUpdated = 1;
74 hmodbus->f.EchoResponse = 1;
75 hmodbus->RS_Message_Size -= 2; // echo response if write ok (minus 2 cause of two CRC bytes)
76 }
77 break;
78
79 // Write Multiple Coils
80 case FC_W_COILS:
82 if(hmodbus->f.MessageHandled)
83 {
84 hmodbus->f.DataUpdated = 1;
85 hmodbus->f.EchoResponse = 1;
86 hmodbus->RS_Message_Size = 6; // echo response if write ok (withous data bytes)
87 }
88 break;
89
90 // Write Multiple Registers
91 case FC_W_HOLD_REGS:
93 if(hmodbus->f.MessageHandled)
94 {
95 hmodbus->f.DataUpdated = 1;
96 hmodbus->f.EchoResponse = 1;
97 hmodbus->RS_Message_Size = 6; // echo response if write ok (withous data bytes)
98 }
99 break;
100
101 case FC_R_DEVICE_ID:
103 break;
104
105 // Добавить в switch-case после других case:
106 case FC_R_DIAGNOSTICS:
108 break;
109
110 /* unknown func code */
111 default:
112 modbus_msg->Except_Code = 0x01; /* set exception code: illegal function */
113 }
114
115
116 // Проверяем режим устройства - если Listen Only, не обрабатываем команды
117 if (MB_GetDeviceMode() == MODBUS_LISTEN_ONLY_MODE)
118 {
120 hmodbus->RS_STATUS = RS_SKIP;
121 return RS_Handle_Receive_Start(hmodbus, modbus_msg);;
122 }
123
124 // Проверяем статус обработки запроса
125 if(hmodbus->f.MessageHandled == 0)
126 {
128 TrackerCnt_Warn(hmodbus->rs_err);
129 modbus_msg->FuncCode |= FC_ERR_VALUES_START;
130 }
131 else
132 {
133 TrackerCnt_Ok(hmodbus->rs_err);
134 }
135
136
137 }
138
139 // if we need response - check that transmit isnt busy
140 if( RS_Is_TX_Busy(hmodbus) )
141 RS_Abort(hmodbus, ABORT_TX); // if tx busy - set it free
142
143 // Transmit right there, or sets (fDeferredResponse) to transmit response in main code
144 if(hmodbus->f.DeferredResponse == 0)
145 {
146 MB_RES = RS_Handle_Transmit_Start(hmodbus, modbus_msg);
147 }
148 else
149 {
150 RS_Handle_Receive_Start(hmodbus, modbus_msg);
151 hmodbus->f.DeferredResponse = 0;
152 }
153
154 hmodbus->RS_STATUS = MB_RES;
155 return MB_RES;
156}
157
158
159
160/**
161 * @brief Сбор сообщения в буфер UART в режиме слейв (фрейм слейва из msg -> uart).
162 * @param hmodbus Указатель на хендлер RS.
163 * @param modbus_msg Указатель на структуру сообщения.
164 * @param modbus_uart_buff Указатель на буффер UART.
165 * @return RS_RES Статус о результате заполнения буфера.
166 */
167RS_StatusTypeDef MB_Slave_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, uint8_t *modbus_uart_buff)
168{
169 int ind = 0; // ind for modbus-uart buffer
170
171 if(hmodbus->f.EchoResponse && hmodbus->f.MessageHandled) // if echo response need
172 ind = hmodbus->RS_Message_Size;
173 else
174 {
175 //------INFO ABOUT DATA/MESSAGE------
176#ifdef MODBUS_PROTOCOL_TCP
177 modbus_uart_buff[ind++] = modbus_msg->TransactionID >> 8;
178 modbus_uart_buff[ind++] = modbus_msg->TransactionID& 0xFF;
179
180 modbus_uart_buff[ind++] = modbus_msg->ProtocolID >> 8;
181 modbus_uart_buff[ind++] = modbus_msg->ProtocolID& 0xFF;
182
183 modbus_uart_buff[ind++] = modbus_msg->PDULength >> 8;
184 modbus_uart_buff[ind++] = modbus_msg->PDULength& 0xFF;
185#endif
186 //-----------[first bytes]-----------
187 // set ID of message/user
188 modbus_uart_buff[ind++] = modbus_msg->MbAddr;
189
190 // set dat or err response
191 modbus_uart_buff[ind++] = modbus_msg->FuncCode;
192
193 if (modbus_msg->FuncCode < FC_ERR_VALUES_START) // if no error occur
194 {
195 // fill modbus header
196 if(0) {}
197#ifdef MODBUS_ENABLE_DEVICE_IDENTIFICATIONS
198 else if(modbus_msg->FuncCode == FC_R_DEVICE_ID) // devide identifications header
199 {
200 modbus_uart_buff[ind++] = modbus_msg->DevId.MEI_Type;
201 modbus_uart_buff[ind++] = modbus_msg->DevId.ReadDevId;
202 modbus_uart_buff[ind++] = modbus_msg->DevId.Conformity;
203 modbus_uart_buff[ind++] = modbus_msg->DevId.MoreFollows;
204 modbus_uart_buff[ind++] = modbus_msg->DevId.NextObjId;
205 modbus_uart_buff[ind++] = modbus_msg->DevId.NumbOfObj;
206
207 if (modbus_msg->ByteCnt > DATA_SIZE*2) // if ByteCnt less than DATA_SIZE
208 {
209 TrackerCnt_Err(hmodbus->rs_err);
210 return RS_COLLECT_MSG_ERR;
211 }
212
213
214 //---------------DATA----------------
215 //-----------[data bytes]------------
216 uint8_t *tmp_data_addr = (uint8_t *)modbus_msg->MbData;
217 for(int i = 0; i < modbus_msg->ByteCnt; i++) // filling buffer with data
218 { // set data
219 modbus_uart_buff[ind++] = *tmp_data_addr;
220 tmp_data_addr++;
221 }
222
223 }
224#endif //MODBUS_ENABLE_DEVICE_IDENTIFICATIONS
225#ifdef MODBUS_ENABLE_DIAGNOSTICS
226 else if(modbus_msg->FuncCode == FC_R_DIAGNOSTICS)
227 {
228 // Diagnostics special format: [SubFunc_HI][SubFunc_LO][Data_HI][Data_LO]
229 modbus_uart_buff[ind++] = modbus_msg->MbData[0] >> 8; // Sub-function HI
230 modbus_uart_buff[ind++] = modbus_msg->MbData[0] & 0xFF; // Sub-function LO
231 modbus_uart_buff[ind++] = modbus_msg->MbData[1] >> 8; // Data HI
232 modbus_uart_buff[ind++] = modbus_msg->MbData[1] & 0xFF; // Data LO
233 }
234#endif //MODBUS_ENABLE_DIAGNOSTICS
235 else // modbus data header
236 {
237 // set size of received data
238 if (modbus_msg->ByteCnt <= DATA_SIZE*2) // if ByteCnt less than DATA_SIZE
239 modbus_uart_buff[ind++] = modbus_msg->ByteCnt;
240 else // otherwise return data_size err
241 {
242 TrackerCnt_Err(hmodbus->rs_err);
243 return RS_COLLECT_MSG_ERR;
244 }
245
246 //---------------DATA----------------
247 //-----------[data bytes]------------
248 uint16_t *tmp_data_addr = (uint16_t *)modbus_msg->MbData;
249 for(int i = 0; i < modbus_msg->ByteCnt; i++) // filling buffer with data
250 { // set data
251 if (i%2 == 0) // HI byte
252 modbus_uart_buff[ind++] = (*tmp_data_addr)>>8;
253 else // LO byte
254 {
255 modbus_uart_buff[ind++] = *tmp_data_addr;
256 tmp_data_addr++;
257 }
258 }
259
260 }
261
262 }
263 else // if some error occur
264 { // send expection code
265 modbus_uart_buff[ind++] = modbus_msg->Except_Code;
266 }
267 }
268 if(ind < 0)
269 return RS_COLLECT_MSG_ERR;
270
271 //---------------CRC----------------
272 //---------[last 16 bytes]----------
273#ifndef MODBUS_PROTOCOL_TCP
274 // calc crc of received data
275 uint16_t CRC_VALUE = crc16(modbus_uart_buff, ind);
276 // write crc to message structure and modbus-uart buffer
277 modbus_msg->MbCRC = CRC_VALUE;
278 modbus_uart_buff[ind++] = CRC_VALUE;
279 modbus_uart_buff[ind++] = CRC_VALUE >> 8;
280#endif
281
282 hmodbus->RS_Message_Size = ind;
283
284 return RS_OK; // returns ok
285}
286
287/**
288 * @brief Определить размер модбас запроса (СЛЕЙВ версия).
289 * @param hRS Указатель на хендлер RS.
290 * @param rx_data_size Указатель на переменную для записи кол-ва байт для принятия.
291 * @return RS_RES Статус о корректности рассчета кол-ва байт для принятия.
292 * @details Определение сколько байтов надо принять по протоколу.
293 */
295{
296 RS_StatusTypeDef MB_RES = 0;
297 int mb_func_size = 0;
298
299 if (modbus_msg->FuncCode == FC_R_DIAGNOSTICS)
300 {
301 mb_func_size = 1;
302 }
303 else if(modbus_msg->FuncCode == FC_R_DEVICE_ID)
304 {
305 mb_func_size = 0;
306 }
307 else if ((modbus_msg->FuncCode & ~FC_ERR_VALUES_START) < 0x0F)
308 {
309 mb_func_size = 1;
310 }
311 else
312 {
313 mb_func_size = modbus_msg->ByteCnt + 2;
314 }
315
316
317 mb_func_size = RX_FIRST_PART_SIZE + mb_func_size; // size of whole message
318 return mb_func_size;
319}
320
321
322/**
323 * @brief Парс сообщения в режиме слейв (фрейм мастера из uart -> msg).
324 * @param hmodbus Указатель на хендлер RS.
325 * @param modbus_msg Указатель на структуру сообщения.
326 * @param modbus_uart_buff Указатель на буффер UART.
327 * @return RS_RES Статус о результате заполнения структуры.
328 * @details Заполнение структуры сообщения из буффера UART.
329 */
330RS_StatusTypeDef MB_Slave_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, uint8_t *modbus_uart_buff)
331{
332 uint32_t check_empty_buff;
333 int ind = 0; // ind for modbus-uart buffer
334 hmodbus->f.RX_Continue = 0;
335 int expected_size = 0;
336 //-----INFO ABOUT DATA/MESSAGE-------
337#ifdef MODBUS_PROTOCOL_TCP
338 modbus_msg->TransactionID =modbus_uart_buff[ind++]<<8;
339 modbus_msg->TransactionID |=modbus_uart_buff[ind++];
340
341 modbus_msg->ProtocolID =modbus_uart_buff[ind++]<<8;
342 modbus_msg->ProtocolID |=modbus_uart_buff[ind++];
343
344 modbus_msg->PDULength =modbus_uart_buff[ind++]<<8;
345 modbus_msg->PDULength |=modbus_uart_buff[ind++];
346#endif
347 //-----------[first bits]------------
348 // get ID of message/user
349 if(modbus_uart_buff[ind] != hmodbus->ID)
350 {
351 modbus_msg->MbAddr = 0;
352 ind++;
353 }
354 else
355 {
356 modbus_msg->MbAddr = modbus_uart_buff[ind++];
357 }
358
359 // get func code
360 modbus_msg->FuncCode = modbus_uart_buff[ind++];
361 if(modbus_msg->FuncCode & FC_ERR_VALUES_START) // явная херня
362 {
364 modbus_msg->MbAddr = 0;
365 return RS_SKIP;
366 }
367
368 if(0) {}
369#ifdef MODBUS_ENABLE_DEVICE_IDENTIFICATIONS
370 else if(modbus_msg->FuncCode == FC_R_DEVICE_ID) // if it device identifications request
371 {
372 modbus_msg->DevId.MEI_Type = modbus_uart_buff[ind++];
373 modbus_msg->DevId.ReadDevId = modbus_uart_buff[ind++];
374 modbus_msg->DevId.NextObjId = modbus_uart_buff[ind++];
375 modbus_msg->ByteCnt = 0;
376 }
377#endif //MODBUS_ENABLE_DEVICE_IDENTIFICATIONS
378#ifdef MODBUS_ENABLE_DIAGNOSTICS
379 else if(modbus_msg->FuncCode == FC_R_DIAGNOSTICS)
380 {
381 // Diagnostics: читаем 4 байта в MbData[0] и MbData[1]
382 // Sub-function
383 modbus_msg->MbData[0] = modbus_uart_buff[ind++] << 8;
384 modbus_msg->MbData[0] |= modbus_uart_buff[ind++];
385 // Data
386 modbus_msg->MbData[1] = modbus_uart_buff[ind++] << 8;
387 modbus_msg->MbData[1] |= modbus_uart_buff[ind++];
388 modbus_msg->Addr = 0; // не использует Addr
389 modbus_msg->Qnt = 0; // не использует Qnt
390 }
391#endif //MODBUS_ENABLE_DIAGNOSTICS
392 else // if its classic modbus request
393 {
394 // get address from CMD
395 modbus_msg->Addr = modbus_uart_buff[ind++] << 8;
396 modbus_msg->Addr |= modbus_uart_buff[ind++];
397
398 // get address from CMD
399 modbus_msg->Qnt = modbus_uart_buff[ind++] << 8;
400 modbus_msg->Qnt |= modbus_uart_buff[ind++];
401 }
402
403 if((hmodbus->pMessagePtr->FuncCode == 0x0F) || (hmodbus->pMessagePtr->FuncCode == 0x10))
404 hmodbus->pMessagePtr->ByteCnt = modbus_uart_buff[ind++];
405 else
406 hmodbus->pMessagePtr->ByteCnt = 0;
407
408 expected_size = MB_Define_Size_of_Function(hmodbus, modbus_msg);
409 // если размер меньше ожидаемого - продолжаем принимать
410 if(hmodbus->RS_Message_Size < expected_size)
411 {
412 hmodbus->f.RX_Continue = 1;
413 return RS_SKIP;
414 }
415 // если больше Ошибка
416 else if (hmodbus->RS_Message_Size > expected_size)
417 {
419 return RS_PARSE_MSG_ERR;
420 }
421
422 //---------------DATA----------------
423 // (optional)
424 if (modbus_msg->ByteCnt != 0)
425 {
426 //check that data size is correct
427 if (modbus_msg->ByteCnt > DATA_SIZE*2)
428 {
429 TrackerCnt_Err(hmodbus->rs_err);
430 modbus_msg->FuncCode |= FC_ERR_VALUES_START;
432 return RS_PARSE_MSG_ERR;
433 }
434 uint16_t *tmp_data_addr = (uint16_t *)modbus_msg->MbData;
435 for(int i = 0; i < modbus_msg->ByteCnt; i++)
436 { // set data
437 if (i%2 == 0)
438 *tmp_data_addr = ((uint16_t)modbus_uart_buff[ind++] << 8);
439 else
440 {
441 *tmp_data_addr |= modbus_uart_buff[ind++];
442 tmp_data_addr++;
443 }
444 }
445 }
446
447 //---------------CRC----------------
448 //----------[last 16 bits]----------
449#ifndef MODBUS_PROTOCOL_TCP
450 // calc crc of received data
451 uint16_t CRC_VALUE = crc16(modbus_uart_buff, ind);
452 // get crc of received data
453 modbus_msg->MbCRC = modbus_uart_buff[ind++];
454 modbus_msg->MbCRC |= modbus_uart_buff[ind++] << 8;
455 // compare crc
456 if (modbus_msg->MbCRC != CRC_VALUE)
457 {
459 TrackerCnt_Err(hmodbus->rs_err);
460 modbus_msg->FuncCode |= FC_ERR_VALUES_START;
461 }
462#endif
463
464 return RS_OK;
465}
466
467#endif //MODBUS_ENABLE_SLAVE
uint8_t MB_Process_Write_Single_Reg(RS_MsgTypeDef *modbus_msg)
Обработать функцию Write Single Register (06 - 0x06).
uint8_t MB_Process_Read_Device_Identifications(RS_MsgTypeDef *modbus_msg)
Обработать функцию Read Device Identifications (43/14 - 0x2B/0E).
uint8_t MB_Process_Read_Coils(RS_MsgTypeDef *modbus_msg)
Обработать функцию Read Coils (01 - 0x01).
uint8_t MB_Process_Diagnostics(RS_MsgTypeDef *modbus_msg)
Обработать функцию Diagnostics (Serial Line only) (0x08)
Definition modbus_diag.c:75
uint8_t MB_Process_Write_Miltuple_Coils(RS_MsgTypeDef *modbus_msg)
Обработать функцию Write Multiple Coils (15 - 0x0F).
uint8_t MB_Process_Write_Single_Coil(RS_MsgTypeDef *modbus_msg)
Обработать функцию Write Single Coils (05 - 0x05).
uint8_t MB_Process_Write_Miltuple_Regs(RS_MsgTypeDef *modbus_msg)
Обработать функцию Write Multiple Registers (16 - 0x10).
uint8_t MB_Process_Read_Hold_Regs(RS_MsgTypeDef *modbus_msg)
Обработать функцию Read Holding Registers (03 - 0x03).
uint8_t MB_Process_Read_Input_Regs(RS_MsgTypeDef *modbus_msg)
Обработать функцию Read Input Registers (04 - 0x04).
void MB_Diagnostics_CommunicationErrorCnt(void)
Увеличивает счетчик ошибок связи
void MB_Diagnostics_SlaveMessageCnt(void)
Увеличивает счетчик отсутствия ответов
void MB_Diagnostics_SlaveNAKCnt(void)
Увеличивает счетчик NAK ответов
void MB_Diagnostics_ExceptionErrorCnt(void)
Увеличивает счетчик исключений
void MB_Diagnostics_SlaveNoResponseCnt(void)
Увеличивает счетчик отсутствия ответов
void MB_Diagnostics_BusMessageCnt(void)
Увеличивает счетчик сообщений на шине
MB_DeviceModeTypeDef MB_GetDeviceMode(void)
Получение текущего режима устройства
#define RX_FIRST_PART_SIZE
Size of first part of message that will be received first receive info part of message,...
Definition modbus_core.h:66
#define FC_ERR_VALUES_START
from this value starts error func codes
Definition modbus_core.h:88
#define DATA_SIZE
maximum number of data: DWORD (NOT MESSAGE SIZE)
Definition modbus_core.h:53
@ FC_W_HOLD_REG
Запись одиночного регистра
@ FC_R_DEVICE_ID
Чтение информации об устройстве
@ FC_R_COILS
Чтение битовых ячеек
Definition modbus_core.h:97
@ FC_W_COILS
Запись нескольких битовых ячеек
@ FC_R_IN_REGS
Чтение регистров хранения
@ FC_W_COIL
Запись битовой ячейки
@ FC_R_DIAGNOSTICS
Чтение диагностической информации устройства
@ FC_R_HOLD_REGS
Чтение входных регистров
@ FC_W_HOLD_REGS
Запись нескольких регистров
RS_StatusTypeDef MB_Slave_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, uint8_t *modbus_uart_buff)
Сбор сообщения в буфер UART в режиме слейв (фрейм слейва из msg -> uart).
RS_StatusTypeDef MB_Slave_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg)
Ответ на сообщение в режиме слейва.
RS_StatusTypeDef MB_Slave_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, uint8_t *modbus_uart_buff)
Парс сообщения в режиме слейв (фрейм мастера из uart -> msg).
#define TrackerCnt_Ok(_cntstruct_)
Инкрементировать переменную - успешных событий
Definition rs_message.h:106
#define TrackerCnt_Err(_cntstruct_)
Инкрементировать переменную - ошибок
Definition rs_message.h:108
#define TrackerCnt_Warn(_cntstruct_)
Инкрементировать переменную - предупреждений
Definition rs_message.h:110
RS_StatusTypeDef RS_Abort(RS_HandleTypeDef *hRS, RS_AbortTypeDef AbortMode)
Отменить прием/передачу RS/UART.
Definition rs_message.c:193
RS_StatusTypeDef RS_Handle_Transmit_Start(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg)
Обработчик для начала передачи.
Definition rs_message.c:269
RS_StatusTypeDef
Enums for respond CMD about RS status.
Definition rs_message.h:164
RS_StatusTypeDef RS_Handle_Receive_Start(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg)
Обработчик для начала приема.
Definition rs_message.c:237
@ ABORT_TX
Отменить передачу
Definition rs_message.h:194
Главный заголовочный файл Modbus библиотеки
static int MB_Define_Size_of_Function(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg)
Определить размер модбас запроса (СЛЕЙВ версия).
uint8_t Conformity
Identification conformity level of the device and type of supported access MODBUS_DEVICE_CONFORMITY.
MB_MEITypeDef MEI_Type
MEI Type assigned number for Device Identifications Interface.
unsigned RX_Continue
0 - Продолжить принимать, 0 - Начать прием сначала
Definition rs_message.h:214
unsigned DataUpdated
1 - Данные были обновлены
Definition rs_message.h:218
unsigned EchoResponse
1 - Ответить эхом, 0 - Ответить своим сообщением
Definition rs_message.h:216
unsigned DeferredResponse
1 - Не начинать передачу в IT, 0 - Ответить в прерывании
Definition rs_message.h:217
unsigned MessageHandled
1 - Обработка запроса успешна, 0 - Обработка запроса в процессе или ошибка
Definition rs_message.h:215
Handle for RS communication.
Definition rs_message.h:228
uint8_t ID
ID хендла
Definition rs_message.h:230
int32_t RS_Message_Size
size of whole message, not only data
Definition rs_message.h:233
RS_MsgTypeDef * pMessagePtr
Указатель на структуру протокола
Definition rs_message.h:231
RS_FlagsTypeDef f
Флаги для контроля приема/передачи
Definition rs_message.h:243
RS_StatusTypeDef RS_STATUS
Статус RS.
Definition rs_message.h:247
Structure for modbus messsage.
MB_FunctonTypeDef FuncCode
Modbus Function Code.
uint16_t Qnt
Quantity of modbus data.
uint8_t MbAddr
Modbus Slave Address.
MB_ExceptionTypeDef Except_Code
Exception Code for the command.
uint16_t MbCRC
Modbus CRC.
MB_DevIdMsgTypeDef DevId
Read Device Identifications Header struct.
uint8_t ByteCnt
Quantity of bytes of data in message to transmit/receive.
uint16_t MbData[DATA_SIZE]
Modbus Data.
uint16_t Addr
Modbus Address of data.