release 0.3.2 Фиксы:
- Data Access API расширено функциями для чтения/записи регистров - API для реквестов MB_RespGet.. перенесено в modbus_master - Мастер: коллбек реквеста вызывается и при таймауте - В коллбеке можно понять статус реквеста по hmodbus->RS_STATUS
This commit is contained in:
@@ -53,6 +53,203 @@ int MB_RespGet_RegisterValue(RS_MsgTypeDef *modbus_msg, uint16_t reg_addr, uint1
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Получить состояние coil в ответе по его адресу
|
||||
* @param modbus_msg Указатель на структуру сообщения
|
||||
* @param coil_addr Адрес coil, состояние которого нужно получить
|
||||
* @param coil_state Указатель для состояния coil (1 - ON, 0 - OFF)
|
||||
* @return 1 - успех, 0 - ошибка или coil_addr вне диапазона запроса
|
||||
*/
|
||||
int MB_RespGet_CoilState(RS_MsgTypeDef *modbus_msg, uint16_t coil_addr, int *coil_state)
|
||||
{
|
||||
if(modbus_msg == NULL || coil_state == NULL)
|
||||
return 0;
|
||||
|
||||
// Проверяем что ответ связан с коилами
|
||||
if(modbus_msg->Func_Code != MB_R_COILS)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Проверяем что coil_addr в пределах запрошенного диапазона
|
||||
if(coil_addr < modbus_msg->Addr || coil_addr >= modbus_msg->Addr + modbus_msg->Qnt)
|
||||
return 0;
|
||||
|
||||
// Вычисляем индекс coil в полученных данных
|
||||
uint16_t coil_index = coil_addr - modbus_msg->Addr;
|
||||
|
||||
// Вычисляем байт и бит
|
||||
uint8_t byte_index = coil_index / 8;
|
||||
uint8_t data_index = coil_index / 16;
|
||||
uint8_t bit_index = coil_index % 16;
|
||||
|
||||
// Проверяем что байт существует в данных
|
||||
if(byte_index >= modbus_msg->ByteCnt)
|
||||
return 0;
|
||||
|
||||
// Получаем байт и проверяем бит
|
||||
if(bit_index < 8)
|
||||
*coil_state = (modbus_msg->DATA[data_index] >> (bit_index+8)) & 0x01;
|
||||
else
|
||||
*coil_state = (modbus_msg->DATA[data_index] >> bit_index) & 0x01;
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Получить количество объектов в сообщении
|
||||
* @param modbus_msg Указатель на структуру сообщения
|
||||
* @return int Количество объектов
|
||||
*/
|
||||
int MB_RespGet_NumberOfObjects(RS_MsgTypeDef *modbus_msg)
|
||||
{
|
||||
if(modbus_msg == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
// Проверяем что ответ связан с диагностикой
|
||||
if(modbus_msg->Func_Code != MB_R_DEVICE_INFO)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return modbus_msg->DevId.NumbOfObj;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Найти объект по ID в сообщении
|
||||
* @param modbus_msg Указатель на структуру сообщения
|
||||
* @param obj_id ID искомого объекта
|
||||
* @param obj_data Буфер для данных объекта (может быть NULL)
|
||||
* @param obj_length Указатель для длины объекта
|
||||
* @return int Найден ли объект (1 - да, 0 - нет)
|
||||
*/
|
||||
int MB_RespGet_ObjectById(RS_MsgTypeDef *modbus_msg, uint8_t obj_id, char *obj_data, uint8_t *obj_length)
|
||||
{
|
||||
if((modbus_msg == NULL) || (obj_data == NULL))
|
||||
return 0;
|
||||
|
||||
// Проверяем что ответ связан с диагностикой
|
||||
if(modbus_msg->Func_Code != MB_R_DEVICE_INFO)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t *data = (uint8_t*)modbus_msg->DATA;
|
||||
unsigned ind = 0;
|
||||
|
||||
for(int i = 0; i < modbus_msg->DevId.NumbOfObj; i++)
|
||||
{
|
||||
uint8_t current_id = data[ind++];
|
||||
uint8_t current_length = data[ind++];
|
||||
|
||||
if(current_id == obj_id)
|
||||
{
|
||||
if(obj_length)
|
||||
*obj_length = current_length;
|
||||
|
||||
for(int j = 0; j < current_length; j++)
|
||||
{
|
||||
obj_data[j] = data[ind++];
|
||||
}
|
||||
obj_data[current_length] = '\0'; // добавляем \0
|
||||
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Пропускаем данные этого объекта
|
||||
ind += current_length;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Получить объект по индексу в сообщении
|
||||
* @param modbus_msg Указатель на структуру сообщения
|
||||
* @param index Индекс объекта (0..N-1)
|
||||
* @param obj_id Указатель для ID объекта
|
||||
* @param obj_data Буфер для данных объекта
|
||||
* @param obj_length Указатель для длины объекта
|
||||
* @return int Успешность получения (1 - получен, 0 - не найден)
|
||||
*/
|
||||
int MB_RespGet_ObjectByIndex(RS_MsgTypeDef *modbus_msg, int index, uint8_t *obj_id, char *obj_data, uint8_t *obj_length)
|
||||
{
|
||||
if((modbus_msg == NULL) || (obj_data == NULL))
|
||||
return 0;
|
||||
|
||||
// Проверяем что ответ связан с диагностикой
|
||||
if(modbus_msg->Func_Code != MB_R_DEVICE_INFO)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(index >= modbus_msg->DevId.NumbOfObj)
|
||||
return 0;
|
||||
|
||||
uint8_t *data = (uint8_t*)modbus_msg->DATA;
|
||||
unsigned ind = 0;
|
||||
|
||||
for(int i = 0; i <= index; i++)
|
||||
{
|
||||
uint8_t current_id = data[ind++];
|
||||
uint8_t current_length = data[ind++];
|
||||
|
||||
if(obj_id)
|
||||
*obj_id = current_id;
|
||||
if(obj_length)
|
||||
*obj_length = current_length;
|
||||
|
||||
if(i == index)
|
||||
{
|
||||
for(int j = 0; j < current_length; j++)
|
||||
{
|
||||
obj_data[j] = data[ind++];
|
||||
}
|
||||
obj_data[current_length] = '\0'; // добавляем \0
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Пропускаем данные этого объекта
|
||||
ind += current_length;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Получить данные диагностики из сообщения (DATA[1])
|
||||
* @param modbus_msg Указатель на структуру сообщения
|
||||
* @param data Указатель куда положить данные
|
||||
* @return 1 - успех, 0 - ошибка
|
||||
*/
|
||||
int MB_RespGet_Diagnostic(RS_MsgTypeDef *modbus_msg, uint16_t *data)
|
||||
{
|
||||
if(modbus_msg == NULL || data == NULL)
|
||||
return 0;
|
||||
|
||||
// Проверяем что ответ связан с диагностикой
|
||||
if(modbus_msg->Func_Code != MB_R_DIAGNOSTIC)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
*data = modbus_msg->DATA[1];
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Определить размер модбас запроса (МАСТЕР версия).
|
||||
* @param hRS Указатель на хендлер RS.
|
||||
@@ -487,6 +684,11 @@ RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_SPECIFIC(uint8_t slave_addr, uint8_t obj
|
||||
RS_MsgTypeDef msg_dummy = {0};
|
||||
|
||||
int MB_RespGet_RegisterValue(RS_MsgTypeDef *modbus_msg, uint16_t reg_addr, uint16_t *reg_value) {return 0;}
|
||||
int MB_RespGet_CoilState(RS_MsgTypeDef *modbus_msg, uint16_t coil_addr, int *coil_state) {return 0;}
|
||||
int MB_RespGet_NumberOfObjects(RS_MsgTypeDef *modbus_msg) {return 0;}
|
||||
int MB_RespGet_ObjectById(RS_MsgTypeDef *modbus_msg, uint8_t obj_id, char *obj_data, uint8_t *obj_length) {return 0;}
|
||||
int MB_RespGet_ObjectByIndex(RS_MsgTypeDef *modbus_msg, int index, uint8_t *obj_id, char *obj_data, uint8_t *obj_length) {return 0;}
|
||||
int MB_RespGet_Diagnostic(RS_MsgTypeDef *modbus_msg, uint16_t *data) {return 0;}
|
||||
|
||||
RS_MsgTypeDef MB_REQUEST_READ_COILS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity) {return msg_dummy;}
|
||||
RS_MsgTypeDef MB_REQUEST_READ_DISCRETE_INPUTS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity) {return msg_dummy;}
|
||||
|
||||
Reference in New Issue
Block a user