更新:整机逻辑、ID指示器驱动、动态Modbus地址、指令文档
This commit is contained in:
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user