Доработки и рефакторинг
This commit is contained in:
115
README.md
115
README.md
@@ -3,7 +3,7 @@
|
||||
Библиотека реализует Modbus RTU Slave для STM32 с использованием HAL. Работает в прерываниях с детектированием конца фрейма по IDLE линии и таймаутами через прерывание таймера.
|
||||
|
||||
## Быстрый старт
|
||||
_Note: Здесь описано подключение просто архива c исходниками. Если надо подключить библиотеку как субмодуль: см. ветку release в этом репозитории._
|
||||
_Note: Здесь описано подключение просто архива c исходниками. Если надо подключить библиотеку как субмодуль: см. ветку **release** в этом репозитории._
|
||||
|
||||
### 1. Настройка периферии
|
||||
|
||||
@@ -55,37 +55,77 @@ void TIMx_IRQHandler(void)
|
||||
// Периферия
|
||||
#define mb_huart huart1 // Удобный дефайн для модбасовского UART
|
||||
#define mb_htim htim3 // Удобный дефайн для модбасовского таймера
|
||||
|
||||
// Модули modbus
|
||||
#define MODBUS_ENABLE_SLAVE ///< Включить обработку МАСТЕР режима
|
||||
//#define MODBUS_ENABLE_MASTER ///< Включить обработку СЛЕЙВ режима
|
||||
|
||||
#define MODBUS_ENABLE_COILS ///< Включить обработку коилов
|
||||
#define MODBUS_ENABLE_HOLDINGS ///< Включить обработку регистров хранения
|
||||
#define MODBUS_ENABLE_INPUTS ///< Включить обработку входных регистров
|
||||
#define MODBUS_ENABLE_DEVICE_IDENTIFICATIONS ///< Включить обработку идентификаторы устройства
|
||||
#define MODBUS_ENABLE_DIAGNOSTICS ///< Включить обработку диагностики модбас
|
||||
|
||||
```
|
||||
|
||||
### 4. Инициализация в коде
|
||||
|
||||
В `main()` после инициализации HAL:
|
||||
Чтобы настроить Slave-режим `main()` после инициализации HAL:
|
||||
|
||||
```c
|
||||
#include "modbus.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// Инициализация HAL
|
||||
HAL_Init();
|
||||
SystemClock_Config();
|
||||
MX_GPIO_Init();
|
||||
MX_USART1_UART_Init();
|
||||
MX_TIM3_Init();
|
||||
|
||||
// Инициализация Modbus
|
||||
MODBUS_SetupHardware(&hmodbus1, &mb_huart, &mb_htim);
|
||||
|
||||
// Запуск приема Modbus
|
||||
MODBUS_SlaveStart(&hmodbus1, &MODBUS_MSG);
|
||||
|
||||
while (1)
|
||||
{
|
||||
// Основной цикл
|
||||
}
|
||||
// Инициализация HAL
|
||||
HAL_Init();
|
||||
SystemClock_Config();
|
||||
MX_GPIO_Init();
|
||||
MX_USART1_UART_Init();
|
||||
MX_TIM3_Init();
|
||||
|
||||
// Инициализация Modbus
|
||||
MODBUS_FirstInit(&hmodbus1, &mb_huart, &mb_htim);
|
||||
MODBUS_Config(&hmodbus1, 1, 1000, MODBUS_MODE_SLAVE);
|
||||
|
||||
// Запуск приема Modbus
|
||||
MODBUS_SlaveStart(&hmodbus1, NULL);
|
||||
|
||||
while (1)
|
||||
{
|
||||
// Основной цикл
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Чтобы настроить Master-режим `main()` после инициализации HAL:
|
||||
|
||||
```c
|
||||
#include "modbus.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// Инициализация HAL
|
||||
HAL_Init();
|
||||
SystemClock_Config();
|
||||
MX_GPIO_Init();
|
||||
MX_USART1_UART_Init();
|
||||
MX_TIM3_Init();
|
||||
|
||||
// Инициализация Modbus
|
||||
MODBUS_FirstInit(&hmodbus1, &mb_huart, &mb_htim);
|
||||
MODBUS_Config(&hmodbus1, 0, 1000, MODBUS_MODE_MASTER);
|
||||
|
||||
// Запуск приема Modbus
|
||||
// Запрос на 1 ID, считать холдинг регистры с 0 адреса 10 штук
|
||||
RS_MsgTypeDef msg = MB_MASTER_READ_HOLDING_REGS(1, 0, 10);
|
||||
MODBUS_MasterRequest(&hmodbus1, &msg, &callback_func);
|
||||
void callback_func(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg)
|
||||
{
|
||||
// MB_RespGet_... Чтобы достать нужные данные из ответа
|
||||
}
|
||||
}
|
||||
```
|
||||
### 5. Настройка карты данных
|
||||
|
||||
В `modbus_data.h` настройте регистры и coils под ваше устройство:
|
||||
@@ -134,6 +174,7 @@ typedef struct
|
||||
|
||||
### 6. Доступ к данным в коде
|
||||
|
||||
В режиме слейва есть дефайны для удобного выставления Коилов. На случай если они не упакованы в битовые поля
|
||||
```c
|
||||
// Чтение входных регистров
|
||||
uint16_t temp = MB_DATA.InRegs.Temperature;
|
||||
@@ -151,6 +192,41 @@ if (MB_Read_Coil_Local(&MB_DATA.Coils, 2)) {
|
||||
}
|
||||
```
|
||||
|
||||
В режиме мастера есть функции для получения информации из ответа `MB_RespGet_...()`
|
||||
```c
|
||||
// Чтение регистров: Получить запрошенные регистры
|
||||
uint16_t value;
|
||||
if(MB_RespGet_RegisterValue(&MODBUS_MSG, 105, ®_value))
|
||||
{
|
||||
printf("Register 105 value: %d\n", reg_value);
|
||||
}
|
||||
// Чтение коилов: Получить запрошенные коилы
|
||||
int state;
|
||||
if(MB_RespGet_CoilState(&MODBUS_MSG, 25, &coil_state))
|
||||
{
|
||||
printf("Coil 25 state: %s\n", coil_state ? "ON" : "OFF");
|
||||
}
|
||||
// Чтение диагностики: Получить запрошенныую диагностику
|
||||
uint16_t counter_value;
|
||||
if(MB_RespGet_DiagnosticResponse(&MODBUS_MSG, &counter_value))
|
||||
{
|
||||
printf("Counter value: %d\n", counter_value);
|
||||
}
|
||||
// Чтение идентификаторов: Получить запрошенные идентификаторы
|
||||
uint8_t length;
|
||||
char vendor_name[64];
|
||||
if(MB_RespGet_ObjectById(&MODBUS_MSG, 0x00, vendor_name, &length))
|
||||
{
|
||||
printf("Vendor Name: %s (length: %d)\n", vendor_name, length);
|
||||
}
|
||||
|
||||
uint8_t obj_id, obj_length;
|
||||
char obj_data[64];
|
||||
if(MB_RespGet_ObjectByIndex(&MODBUS_MSG, 0x00, &obj_id, obj_data, &obj_length))
|
||||
{
|
||||
printf("First object - ID: 0x%02X, Data: %s\n", obj_id, obj_data);
|
||||
}
|
||||
```
|
||||
## Поддерживаемые функции Modbus
|
||||
|
||||
| Функция | Код | Описание |
|
||||
@@ -160,6 +236,7 @@ if (MB_Read_Coil_Local(&MB_DATA.Coils, 2)) {
|
||||
| Read Holding Registers | 0x03 | Чтение регистров хранения |
|
||||
| Write Single Coil | 0x05 | Запись одиночного coil |
|
||||
| Write Single Register | 0x06 | Запись одиночного регистра |
|
||||
| Diagnostics (Serial Line only) | 0x08 | Чтение диагностически и управление режимом работы |
|
||||
| Write Multiple Coils | 0x0F | Запись множественных coils |
|
||||
| Write Multiple Registers | 0x10 | Запись множественных регистров |
|
||||
| Read Device Identification | 0x2B | Чтение идентификации устройства |
|
||||
|
||||
Reference in New Issue
Block a user