更新:整机逻辑、ID指示器驱动、动态Modbus地址、指令文档

This commit is contained in:
2026-05-11 22:00:49 +08:00
parent b49c9ab0c6
commit 20e3988eee
11 changed files with 614 additions and 64 deletions
+34
View File
@@ -0,0 +1,34 @@
#include "id_driver.h"
#include "gpio_driver.h"
#include "config.h"
static uint8_t current_id;
static uint8_t id_read_pins(void)
{
uint8_t val = 0;
if (gpio_get_level(ID_PORT, ID_PIN_1)) val |= 0x01;
if (gpio_get_level(ID_PORT, ID_PIN_2)) val |= 0x02;
if (gpio_get_level(ID_PORT, ID_PIN_3)) val |= 0x04;
if (gpio_get_level(ID_PORT, ID_PIN_4)) val |= 0x08;
return val;
}
ret_code_t id_driver_init(void)
{
current_id = id_read_pins();
return RET_OK;
}
uint8_t id_get_value(void)
{
return current_id;
}
uint8_t id_get_slave_address(void)
{
return ID_BASE_ADDR + current_id;
}
+14
View File
@@ -0,0 +1,14 @@
#ifndef ID_DRIVER_H__
#define ID_DRIVER_H__
#include "common_types.h"
#include <stdint.h>
#define ID_PIN_COUNT 4
#define ID_BASE_ADDR 0x40
ret_code_t id_driver_init(void);
uint8_t id_get_value(void);
uint8_t id_get_slave_address(void);
#endif
+127 -61
View File
@@ -5,40 +5,48 @@
#include "config.h"
#include <string.h>
#define MODBUS_RX_TIMEOUT_MS 5
#define MODBUS_TX_GUARD_US 2
#define MODBUS_RX_TIMEOUT_MS 5
#define MODBUS_TX_GUARD_US 2
#define MODBUS_EXCEPTION_ILLEGAL_FUNCTION 0x01
#define MODBUS_EXCEPTION_ILLEGAL_DATA_ADDR 0x02
#define MODBUS_EXCEPTION_ILLEGAL_DATA_VAL 0x03
#define MODBUS_EXCEPTION_ILLEGAL_FUNCTION 0x01
#define MODBUS_EXCEPTION_ILLEGAL_DATA_ADDR 0x02
#define MODBUS_EXCEPTION_ILLEGAL_DATA_VAL 0x03
#define MODBUS_ADDR_BROADCAST 0x00
#define MODBUS_ADDR_BROADCAST 0x00
#define REG_BUS_DATA_START 0x0000
#define REG_BUS_DATA_END 0x001F
#define REG_BUS_DATA_HIGH_START 0x0020
#define REG_BUS_DATA_HIGH_END 0x003F
#define REG_FLAG_LOW 0x0040
#define REG_FLAG_HIGH 0x0041
#define REG_BUS_DATA_START 0x0000
#define REG_BUS_DATA_END 0x001F
#define REG_BUS_DATA_HIGH_START 0x0020
#define REG_BUS_DATA_HIGH_END 0x003F
#define REG_FLAG_LOW 0x0040
#define REG_FLAG_HIGH 0x0041
#define REG_CMD 0x0042
#define REG_STATUS 0x0043
#define REG_ANGLE_TARGET 0x0044
static uint8_t slave_address;
static uint8_t slave_address;
static modbus_state_t state;
static uint8_t rx_buf[MODBUS_BUF_SIZE];
static uint16_t rx_len;
static uint32_t rx_tick_start;
static uint8_t initialized;
static uint8_t rx_buf[MODBUS_BUF_SIZE];
static uint16_t rx_len;
static uint32_t rx_tick_start;
static uint8_t initialized;
static uint16_t modbus_crc16_calc(const uint8_t *data, uint16_t len)
{
uint16_t crc = 0xFFFF;
uint16_t i, j;
for (i = 0; i < len; i++) {
for (i = 0; i < len; i++)
{
crc ^= data[i];
for (j = 0; j < 8; j++) {
if (crc & 0x0001) {
for (j = 0; j < 8; j++)
{
if (crc & 0x0001)
{
crc = (crc >> 1) ^ 0xA001;
} else {
}
else
{
crc = crc >> 1;
}
}
@@ -81,36 +89,61 @@ static void modbus_handle_read_holding(uint16_t reg_addr, uint16_t reg_count)
sys_data_bus_value_t bus_val;
uint32_t flags;
if (reg_count < 1 || reg_count > 125) {
if (reg_count < 1 || reg_count > 125)
{
modbus_send_exception(MODBUS_FUNC_READ_HOLDING, MODBUS_EXCEPTION_ILLEGAL_DATA_VAL);
return;
}
if ((reg_addr >= REG_BUS_DATA_START && (reg_addr + reg_count - 1) <= REG_BUS_DATA_END) ||
(reg_addr >= REG_BUS_DATA_HIGH_START && (reg_addr + reg_count - 1) <= REG_BUS_DATA_HIGH_END) ||
(reg_addr >= REG_FLAG_LOW && (reg_addr + reg_count - 1) <= REG_FLAG_HIGH)) {
(reg_addr >= REG_FLAG_LOW && (reg_addr + reg_count - 1) <= REG_ANGLE_TARGET))
{
resp[0] = slave_address;
resp[1] = MODBUS_FUNC_READ_HOLDING;
resp[2] = (uint8_t)(reg_count * 2);
for (i = 0; i < reg_count; i++) {
for (i = 0; i < reg_count; i++)
{
uint16_t addr = reg_addr + i;
uint16_t reg_val = 0;
if (addr <= REG_BUS_DATA_END) {
if (addr <= REG_BUS_DATA_END)
{
bus_val = sys_data_bus_read((sys_data_bus_id_t)addr);
reg_val = (uint16_t)(bus_val.u & 0xFFFF);
} else if (addr >= REG_BUS_DATA_HIGH_START && addr <= REG_BUS_DATA_HIGH_END) {
}
else if (addr >= REG_BUS_DATA_HIGH_START && addr <= REG_BUS_DATA_HIGH_END)
{
bus_val = sys_data_bus_read((sys_data_bus_id_t)(addr - REG_BUS_DATA_HIGH_START));
reg_val = (uint16_t)((bus_val.u >> 16) & 0xFFFF);
} else if (addr == REG_FLAG_LOW) {
}
else if (addr == REG_FLAG_LOW)
{
flags = 0;
reg_val = (uint16_t)(flags & 0xFFFF);
} else if (addr == REG_FLAG_HIGH) {
}
else if (addr == REG_FLAG_HIGH)
{
flags = 0;
reg_val = (uint16_t)((flags >> 16) & 0xFFFF);
}
else if (addr == REG_CMD)
{
bus_val = sys_data_bus_read(SYS_DATA_BUS_MOTOR_CMD);
reg_val = (uint16_t)(bus_val.u & 0xFFFF);
}
else if (addr == REG_STATUS)
{
bus_val = sys_data_bus_read(SYS_DATA_BUS_MOTOR_STATUS);
reg_val = (uint16_t)(bus_val.u & 0xFFFF);
}
else if (addr == REG_ANGLE_TARGET)
{
bus_val = sys_data_bus_read(SYS_DATA_BUS_ANGLE_TARGET);
reg_val = (uint16_t)(bus_val.u & 0xFFFF);
}
resp[3 + i * 2] = (uint8_t)((reg_val >> 8) & 0xFF);
resp[4 + i * 2] = (uint8_t)(reg_val & 0xFF);
@@ -122,7 +155,9 @@ static void modbus_handle_read_holding(uint16_t reg_addr, uint16_t reg_count)
resp[resp_len + 1] = (uint8_t)((crc >> 8) & 0xFF);
modbus_send_response(resp, resp_len + 2);
} else {
}
else
{
modbus_send_exception(MODBUS_FUNC_READ_HOLDING, MODBUS_EXCEPTION_ILLEGAL_DATA_ADDR);
}
}
@@ -132,14 +167,17 @@ static void modbus_handle_write_single_reg(uint16_t reg_addr, uint16_t reg_value
uint8_t resp[8];
uint16_t crc;
if (reg_addr <= REG_BUS_DATA_END) {
if (reg_addr <= REG_BUS_DATA_END)
{
sys_data_bus_value_t val;
sys_data_bus_value_t current;
current = sys_data_bus_read((sys_data_bus_id_t)reg_addr);
val.u = (current.u & 0xFFFF0000) | reg_value;
sys_data_bus_write((sys_data_bus_id_t)reg_addr, val);
} else if (reg_addr >= REG_BUS_DATA_HIGH_START && reg_addr <= REG_BUS_DATA_HIGH_END) {
}
else if (reg_addr >= REG_BUS_DATA_HIGH_START && reg_addr <= REG_BUS_DATA_HIGH_END)
{
sys_data_bus_value_t val;
sys_data_bus_value_t current;
uint8_t idx = (uint8_t)(reg_addr - REG_BUS_DATA_HIGH_START);
@@ -147,7 +185,21 @@ static void modbus_handle_write_single_reg(uint16_t reg_addr, uint16_t reg_value
current = sys_data_bus_read((sys_data_bus_id_t)idx);
val.u = (current.u & 0x0000FFFF) | ((uint32_t)reg_value << 16);
sys_data_bus_write((sys_data_bus_id_t)idx, val);
} else {
}
else if (reg_addr == REG_CMD)
{
sys_data_bus_value_t val;
val.u = reg_value;
sys_data_bus_write(SYS_DATA_BUS_MOTOR_CMD, val);
}
else if (reg_addr == REG_ANGLE_TARGET)
{
sys_data_bus_value_t val;
val.u = reg_value;
sys_data_bus_write(SYS_DATA_BUS_ANGLE_TARGET, val);
}
else
{
modbus_send_exception(MODBUS_FUNC_WRITE_SINGLE_REG, MODBUS_EXCEPTION_ILLEGAL_DATA_ADDR);
return;
}
@@ -170,12 +222,14 @@ static void modbus_process_frame(void)
{
uint16_t crc_recv, crc_calc;
if (rx_len < 4) {
if (rx_len < 4)
{
state = MODBUS_IDLE;
return;
}
if (rx_buf[0] != slave_address && rx_buf[0] != MODBUS_ADDR_BROADCAST) {
if (rx_buf[0] != slave_address && rx_buf[0] != MODBUS_ADDR_BROADCAST)
{
state = MODBUS_IDLE;
return;
}
@@ -183,7 +237,8 @@ static void modbus_process_frame(void)
crc_recv = (uint16_t)rx_buf[rx_len - 1] << 8 | rx_buf[rx_len - 2];
crc_calc = modbus_crc16_calc(rx_buf, rx_len - 2);
if (crc_recv != crc_calc) {
if (crc_recv != crc_calc)
{
state = MODBUS_IDLE;
return;
}
@@ -193,28 +248,31 @@ static void modbus_process_frame(void)
uint16_t reg_addr;
uint16_t reg_count;
switch (func) {
case MODBUS_FUNC_READ_HOLDING:
if (rx_len < 8) {
break;
}
reg_addr = (uint16_t)rx_buf[2] << 8 | rx_buf[3];
reg_count = (uint16_t)rx_buf[4] << 8 | rx_buf[5];
modbus_handle_read_holding(reg_addr, reg_count);
switch (func)
{
case MODBUS_FUNC_READ_HOLDING:
if (rx_len < 8)
{
break;
}
reg_addr = (uint16_t)rx_buf[2] << 8 | rx_buf[3];
reg_count = (uint16_t)rx_buf[4] << 8 | rx_buf[5];
modbus_handle_read_holding(reg_addr, reg_count);
break;
case MODBUS_FUNC_WRITE_SINGLE_REG:
if (rx_len < 8) {
break;
}
reg_addr = (uint16_t)rx_buf[2] << 8 | rx_buf[3];
reg_count = (uint16_t)rx_buf[4] << 8 | rx_buf[5];
modbus_handle_write_single_reg(reg_addr, reg_count);
case MODBUS_FUNC_WRITE_SINGLE_REG:
if (rx_len < 8)
{
break;
}
reg_addr = (uint16_t)rx_buf[2] << 8 | rx_buf[3];
reg_count = (uint16_t)rx_buf[4] << 8 | rx_buf[5];
modbus_handle_write_single_reg(reg_addr, reg_count);
break;
default:
modbus_send_exception(func, MODBUS_EXCEPTION_ILLEGAL_FUNCTION);
break;
default:
modbus_send_exception(func, MODBUS_EXCEPTION_ILLEGAL_FUNCTION);
break;
}
}
@@ -245,20 +303,25 @@ void modbus_slave_poll(void)
uint8_t byte;
uint32_t now;
if (!initialized) {
if (!initialized)
{
return;
}
available = uart_available(UART_ID_USART1);
if (available > 0) {
if (state == MODBUS_IDLE) {
if (available > 0)
{
if (state == MODBUS_IDLE)
{
state = MODBUS_RX_IN_PROGRESS;
rx_len = 0;
}
while (available > 0 && rx_len < MODBUS_BUF_SIZE) {
if (uart_receive(UART_ID_USART1, &byte, 1, 0) == RET_OK) {
while (available > 0 && rx_len < MODBUS_BUF_SIZE)
{
if (uart_receive(UART_ID_USART1, &byte, 1, 0) == RET_OK)
{
rx_buf[rx_len++] = byte;
}
available--;
@@ -267,14 +330,17 @@ void modbus_slave_poll(void)
rx_tick_start = system_get_tick();
}
if (state == MODBUS_RX_IN_PROGRESS && rx_len > 0) {
if (state == MODBUS_RX_IN_PROGRESS && rx_len > 0)
{
now = system_get_tick();
if ((now - rx_tick_start) >= MODBUS_RX_TIMEOUT_MS) {
if ((now - rx_tick_start) >= MODBUS_RX_TIMEOUT_MS)
{
state = MODBUS_RX_COMPLETE;
}
}
if (state == MODBUS_RX_COMPLETE) {
if (state == MODBUS_RX_COMPLETE)
{
modbus_process_frame();
}
}
+1 -1
View File
@@ -5,7 +5,7 @@
#include <stdint.h>
#define MODBUS_SLAVE_ADDR 0x01
#define MODBUS_MASTER_ADDR 0xF0
#define MODBUS_MASTER_ADDR 0xFE
#define MODBUS_BUF_SIZE 256
#define MODBUS_FUNC_READ_COILS 0x01