Сб дек 03, 2022 20:47:29
typedef struct {
uint8_t update; // флаг того что данные обновились
uint8_t rx_buffer_uart[256]; // буфер по максимальному размеру пакета MODBUS
uint8_t size; // размер принятных данных
} receive_data;
HAL_UARTEx_ReceiveToIdle_DMA(&huart1, (uint8_t*)receive_data_slave.rx_buffer_uart, BUFFER_SIZE); // разрешить ожидание приёма пакета
while (1)
{
if (receive_data_slave.update == 1) // если данные обновились
{
uint8_t response[256] = {0}; // создать пустой массив для ответа
process_receive_slave(&receive_data_slave, &slave_hold_reg, &response); // передать в обработчик полученные данные, регистры для чтения/записи, указатель на массив для ответа
if (response[0] != 0) // если массив для ответа не пустой
while(HAL_UART_Transmit_DMA(&huart1, (uint8_t*)response, sizeof(response)) == HAL_BUSY); // отправить ответ
receive_data_slave.update = 0; // данные обработаны, снимаю флаг обновления
HAL_UARTEx_ReceiveToIdle_DMA(&huart1, (uint8_t*)receive_data_slave.rx_buffer_uart, BUFFER_SIZE); // разрешаю приём следующих данных
}
}
void process_receive_slave (receive_data* data, uint16_t *reg, uint8_t *response)
{
if (data->rx_buffer_uart[0] != SLAVE_ADDRESS) // если данные не для нашего адреса - сразу выходим
return;
int crc;
crc = crc_chk(data->rx_buffer_uart, (data->size)-2);
if ((data->rx_buffer_uart[(data->size)-1] == (crc & 0xFF00) >> 8) && //проверка чек-суммы пакета
(data->rx_buffer_uart[(data->size)-2] == (crc & 0x00FF)))
{
uint16_t addr_reg, quantity;
addr_reg = ((data->rx_buffer_uart[2]) << 8) + (data->rx_buffer_uart[3]); // определение адреса регистра указанного в пакете
switch(data->rx_buffer_uart[1]) {
case 3: // если команда на чтение
quantity = ((data->rx_buffer_uart[4]) << 8) + (data->rx_buffer_uart[5]); // сколько запрошено регистров считать
response[0] = SLAVE_ADDRESS; // далее формирование ответа
response[1] = 0x03; // команда
response[2] = quantity * 2;
uint8_t i = 0;
uint8_t j = 3;
while(i < quantity)
{
response[j] = (reg[addr_reg-SLAVE_REG_START+i] & 0xFF00) >> 8;
j++;
response[j] = reg[addr_reg-SLAVE_REG_START+i] & 0x00FF;
j++;
i++;
}
crc = crc_chk(response, j);
response[j] = crc & 0x00FF;
j++;
response[j] = (crc & 0xFF00) >> 8;
break;
case 6: // если команда на запись
reg[addr_reg-SLAVE_REG_START] = ((data->rx_buffer_uart[4]) << 8) + (data->rx_buffer_uart[5]); // записать данные в регистр
for (int i=0; i < data->size; i++) // сформировать ответ - копия запроса
{
response[i] = data->rx_buffer_uart[i];
}
break;
default:
break;
}
}
}
if (response[0] != 0)
while(HAL_UART_Transmit_DMA(&huart1, (uint8_t*)response, sizeof(response)) == HAL_BUSY);
Вс дек 04, 2022 08:55:01
uint8_t rx_buffer_uart[256];
HAL_UARTEx_ReceiveToIdle_DMA(&huart1, (uint8_t*)receive_data_slave.rx_buffer_uart, BUFFER_SIZE);
uint8_t response[256] = {0}; // создать пустой массив для ответа
while(HAL_UART_Transmit_DMA(&huart1, (uint8_t*)response, sizeof(response)) == HAL_BUSY);
crc = crc_chk(data->rx_buffer_uart, (data->size)-2);
я иногда получаю ответ состоящий из всех нулей