@@ -27,6 +27,7 @@ extern "C" { | |||||
/* Includes ------------------------------------------------------------------*/ | /* Includes ------------------------------------------------------------------*/ | ||||
#include "main.h" | #include "main.h" | ||||
#include "usart.h" | |||||
/* USER CODE BEGIN Includes */ | /* USER CODE BEGIN Includes */ | ||||
@@ -61,10 +62,10 @@ extern TIM_HandleTypeDef htim14; | |||||
// 等待条件类型枚举 | // 等待条件类型枚举 | ||||
typedef enum { | typedef enum { | ||||
PLSR_WAIT_PLUSEEND = 0, // 脉冲发送完成 | PLSR_WAIT_PLUSEEND = 0, // 脉冲发送完成 | ||||
PLSR_WAIT_TIME = 1, // 等待时间 | |||||
PLSR_WAIT_TIME = 4, // 等待时间 | |||||
PLSR_WAIT_CONDITION = 2, // 等待条件 | PLSR_WAIT_CONDITION = 2, // 等待条件 | ||||
PLSR_WAIT_ACT_TIME = 3, // ACT时间 | PLSR_WAIT_ACT_TIME = 3, // ACT时间 | ||||
PLSR_WAIT_EXT_EVENT = 4, // 外部事件 | |||||
PLSR_WAIT_EXT_EVENT = 1, // 外部事件 | |||||
PLSR_WAIT_EXT_OR_END = 5 // 外部事件或结束 | PLSR_WAIT_EXT_OR_END = 5 // 外部事件或结束 | ||||
} PLSR_WaitType_t; | } PLSR_WaitType_t; | ||||
@@ -159,6 +160,7 @@ typedef struct { | |||||
uint32_t start_freq; // 起始频率 | uint32_t start_freq; // 起始频率 | ||||
uint32_t end_freq; // 结束频率 | uint32_t end_freq; // 结束频率 | ||||
uint8_t output_port; // 输出端口选择 | uint8_t output_port; // 输出端口选择 | ||||
uint8_t dir_port; //<方向端口选择 | |||||
PLSR_Mode_t mode; // 模式(相对/绝对) | PLSR_Mode_t mode; // 模式(相对/绝对) | ||||
PLSR_Direction_t direction; // 方向 | PLSR_Direction_t direction; // 方向 | ||||
PLSR_AccelConfig_t accel_config; // 加减速配置 | PLSR_AccelConfig_t accel_config; // 加减速配置 | ||||
@@ -171,6 +173,11 @@ typedef struct { | |||||
uint32_t freq_step; // 频率步长 | uint32_t freq_step; // 频率步长 | ||||
uint32_t wait_start_tick; // 等待开始时间 | uint32_t wait_start_tick; // 等待开始时间 | ||||
uint32_t act_start_tick; // ACT开始时间 | uint32_t act_start_tick; // ACT开始时间 | ||||
uint16_t dir_delay; //<方向延时时间 | |||||
uint16_t dir_logic; //<脉冲方向逻辑 | |||||
uint16_t section_num; //<脉冲总段数 | |||||
uint16_t start_section; //<起始段数 | |||||
uint32_t default_freq; //<脉冲默认速度 | |||||
PLSR_SectionConfig_t section[PLSR_MAX_SECTIONS]; // 段配置数组 | PLSR_SectionConfig_t section[PLSR_MAX_SECTIONS]; // 段配置数组 | ||||
} PLSR_RouteConfig_t; | } PLSR_RouteConfig_t; | ||||
@@ -212,6 +219,7 @@ void PLSR_TIM6_Stop(void); | |||||
// ==================== PLSR路径控制函数 ==================== | // ==================== PLSR路径控制函数 ==================== | ||||
void PLSR_Route_Init(PLSR_RouteConfig_t* route); //<路径初始化 | void PLSR_Route_Init(PLSR_RouteConfig_t* route); //<路径初始化 | ||||
void PLSR_Route_Set(PLSR_RouteConfig_t* route); | |||||
void PLSR_Route_Start(PLSR_RouteConfig_t* route); //<路径开始 | void PLSR_Route_Start(PLSR_RouteConfig_t* route); //<路径开始 | ||||
void PLSR_Route_Stop(PLSR_RouteConfig_t* route); //<路径停止 | void PLSR_Route_Stop(PLSR_RouteConfig_t* route); //<路径停止 | ||||
void PLSR_Section_Process(PLSR_RouteConfig_t* route); //<段处理 | void PLSR_Section_Process(PLSR_RouteConfig_t* route); //<段处理 | ||||
@@ -43,13 +43,9 @@ extern UART_HandleTypeDef huart1; | |||||
/* USER CODE BEGIN Private defines */ | /* USER CODE BEGIN Private defines */ | ||||
///> ==================== 寄存器配置 ==================== | ///> ==================== 寄存器配置 ==================== | ||||
#define MODBUS_HOLDING_REG_COUNT 1200 ///> 保持寄存器数量 (40001-49999) | |||||
#define MODBUS_COIL_COUNT 256 ///> 线圈数量 (00001-09999) | |||||
#define SRAM_HOLDING_REG_COUNT 256 ///> SRAM保持寄存器数量 (60001-69999) | |||||
#define SRAM_HOLDING_COIL_COUNT 1000 ///> SRAM保持寄存器数量 (60001-69999) | |||||
#define MODBUS_HOLDING_REG_COUNT 0x2500 ///> 保持寄存器数量 (40001-49999) | |||||
#define MODBUS_OFFSET 0x1000 | |||||
///> ==================== Modbus功能码定义 ==================== | |||||
#define MODBUS_FC_READ_COILS 0x01 ///> 读线圈状态 | |||||
#define MODBUS_FC_READ_HOLDING_REGS 0x03 ///> 读保持寄存器 | #define MODBUS_FC_READ_HOLDING_REGS 0x03 ///> 读保持寄存器 | ||||
#define MODBUS_FC_WRITE_REG 0x06 | #define MODBUS_FC_WRITE_REG 0x06 | ||||
#define MODBUS_FC_WRITE_MULTIPLE_COILS 0x0F ///> 写多个线圈 | #define MODBUS_FC_WRITE_MULTIPLE_COILS 0x0F ///> 写多个线圈 | ||||
@@ -71,7 +67,6 @@ typedef struct | |||||
{ | { | ||||
uint8_t slave_address; ///> 从机地址 | uint8_t slave_address; ///> 从机地址 | ||||
uint16_t holding_regs[MODBUS_HOLDING_REG_COUNT]; ///> 保持寄存器 (40001-49999) | uint16_t holding_regs[MODBUS_HOLDING_REG_COUNT]; ///> 保持寄存器 (40001-49999) | ||||
uint8_t coils[MODBUS_COIL_COUNT/8 + 1]; ///> 线圈状态 (00001-09999) | |||||
} ModbusSlave_t; | } ModbusSlave_t; | ||||
/* USER CODE END Private defines */ | /* USER CODE END Private defines */ | ||||
@@ -96,8 +91,6 @@ void Modbus_Init(uint8_t slave_addr); | |||||
void Modbus_Process(void); | void Modbus_Process(void); | ||||
void Modbus_SetHoldingRegister(uint16_t addr, uint16_t value); | void Modbus_SetHoldingRegister(uint16_t addr, uint16_t value); | ||||
uint16_t Modbus_GetHoldingRegister(uint16_t addr); | uint16_t Modbus_GetHoldingRegister(uint16_t addr); | ||||
void Modbus_SetCoil(uint16_t addr, uint8_t value); | |||||
uint8_t Modbus_GetCoil(uint16_t addr); | |||||
void Modbus_Handle_SendLog(uint8_t* frame, uint16_t length); | void Modbus_Handle_SendLog(uint8_t* frame, uint16_t length); | ||||
void Modbus_Process_Write_Reg(uint8_t *frame, uint16_t length); | void Modbus_Process_Write_Reg(uint8_t *frame, uint16_t length); | ||||
@@ -246,9 +246,22 @@ static void MODBUSTask(void *p_arg) | |||||
static void KeyTask(void *p_arg) | static void KeyTask(void *p_arg) | ||||
{ | { | ||||
(void)p_arg; | (void)p_arg; | ||||
uint8_t startflag = 0; | |||||
PLSR_Route_Start(&g_plsr_route); | PLSR_Route_Start(&g_plsr_route); | ||||
while (1) | while (1) | ||||
{ | { | ||||
// if(ModbusSlave.holding_regs[0x2000] == 1) //按下发送脉冲按钮后,向0x3000地址写1,松手写2,设置地址偏移为0x1000,所以这里值为0x2000 | |||||
// { | |||||
// startflag = 1; | |||||
// } | |||||
// if(startflag == 1) | |||||
// { | |||||
// PLSR_Route_Start(&g_plsr_route); | |||||
// } | |||||
// if(ModbusSlave.holding_regs[0x2000] == 2) | |||||
// { | |||||
// startflag = 0; | |||||
// } | |||||
OSTimeDlyHMSM(0, 0, 0, 10); /* 延时10ms */ | OSTimeDlyHMSM(0, 0, 0, 10); /* 延时10ms */ | ||||
} | } | ||||
@@ -537,11 +537,6 @@ void MX_TIM14_Init(void) | |||||
* @brief 定时器基础MSP初始化函数 | * @brief 定时器基础MSP初始化函数 | ||||
* @param tim_baseHandle: 定时器句柄指针 | * @param tim_baseHandle: 定时器句柄指针 | ||||
* @retval None | * @retval None | ||||
* @note 为不同的定时器实例配置时钟、GPIO和中断 | |||||
* - TIM2: 用作外部脉冲计数器,配置PA15为ETR输入 | |||||
* - TIM6: 用作PLSR系统定时器,配置中断优先级0 | |||||
* - TIM10: 用作PWM输出定时器,配置中断优先级5 | |||||
* - TIM11/TIM13/TIM14: 备用定时器,仅使能时钟 | |||||
*/ | */ | ||||
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle) | void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle) | ||||
{ | { | ||||
@@ -1187,44 +1182,48 @@ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) | |||||
} | } | ||||
// ==================== 路径控制函数实现 ==================== | |||||
void PLSR_Route_Set(PLSR_RouteConfig_t* route) | |||||
{ | |||||
route->output_port = ModbusSlave.holding_regs[0]; | |||||
route->dir_port = ModbusSlave.holding_regs[1]; | |||||
route->dir_delay = ModbusSlave.holding_regs[3]; | |||||
route->dir_logic = ModbusSlave.holding_regs[4]; | |||||
route->accel_config.accel_algorithm = ModbusSlave.holding_regs[5]; | |||||
route->mode = ModbusSlave.holding_regs[6]; //绝对/相对 | |||||
route->section_num = ModbusSlave.holding_regs[7]; //总段数 | |||||
route->start_section = ModbusSlave.holding_regs[8]; | |||||
route->default_freq = ModbusSlave.holding_regs[9]<<16|ModbusSlave.holding_regs[10]; | |||||
route->accel_config.accel_time_ms = ModbusSlave.holding_regs[11]; | |||||
route->accel_config.decel_time_ms = ModbusSlave.holding_regs[12]; | |||||
route->start_freq = 0; // 起始频率:0Hz | |||||
route->end_freq = 0; // 结束频率:0Hz | |||||
// 初始化所有段的配置 - 遍历并初始化每个段 | |||||
for (uint8_t i = 0; i < route->section_num; i++) | |||||
{ | |||||
route->section[i].section_num = i+1; | |||||
route->section[i].target_freq = (((uint32_t)ModbusSlave.holding_regs[256+(6*i)]) | (uint32_t)ModbusSlave.holding_regs[257+(6*i)]<<16); | |||||
route->section[i].target_pulse = (((uint32_t)ModbusSlave.holding_regs[258+(6*i)]) | (uint32_t)ModbusSlave.holding_regs[259+(6*i)]<<16); | |||||
route->section[i].wait_condition.wait_type = ModbusSlave.holding_regs[260+(6*i)]; | |||||
route->section[i].next_section = ModbusSlave.holding_regs[261+(6*i)]; | |||||
route->section[i].section_state = PLSR_SECTION_IDLE; | |||||
} | |||||
} | |||||
/** | |||||
* @brief 初始化PLSR路径控制参数 | |||||
* @param route 路径控制结构体指针 | |||||
* | |||||
* 该函数负责完整初始化PLSR路径控制系统的所有参数,为路径执行做好准备。 | |||||
* 包括路径基本参数、运行状态参数、所有段配置以及硬件资源的初始化。 | |||||
* | |||||
* 初始化内容: | |||||
* 1. 路径基本参数 - 设置初始状态、频率、模式等 | |||||
* 2. 运行状态参数 - 清零所有运行时计数和状态 | |||||
* 3. 段配置初始化 - 初始化所有10个段的默认配置 | |||||
* 4. 硬件资源重置 - 停止PWM和定时器,重置计数器 | |||||
* | |||||
* @note 该函数应在使用PLSR系统前调用,确保所有参数处于已知状态 | |||||
*/ | |||||
void PLSR_Route_Init(PLSR_RouteConfig_t* route) | void PLSR_Route_Init(PLSR_RouteConfig_t* route) | ||||
{ | { | ||||
// 参数有效性检查 | // 参数有效性检查 | ||||
if (route == NULL) return; | if (route == NULL) return; | ||||
// 初始化路径基本参数 | // 初始化路径基本参数 | ||||
route->route_state = PLSR_ROUTE_IDLE; // 路径状态:空闲 | route->route_state = PLSR_ROUTE_IDLE; // 路径状态:空闲 | ||||
route->current_section_num = 1; // 当前段号:从第1段开始 | |||||
route->current_freq = 0; // 当前频率:0Hz | route->current_freq = 0; // 当前频率:0Hz | ||||
route->target_freq = 0; // 目标频率:0Hz | route->target_freq = 0; // 目标频率:0Hz | ||||
route->pulse_count = 0; // 脉冲计数:清零 | |||||
route->start_freq = 0; // 起始频率:0Hz | |||||
route->end_freq = 0; // 结束频率:0Hz | |||||
route->output_port = 0; // 输出端口选择(预留功能) | |||||
route->mode = PLSR_MODE_RELATIVE; // 路径模式:默认相对模式 | |||||
route->direction = PLSR_DIR_FORWARD; // 运行方向:默认正向 | route->direction = PLSR_DIR_FORWARD; // 运行方向:默认正向 | ||||
// 初始化加减速配置 - 系统级配置 | |||||
route->accel_config.accel_time_ms = PLSR_DEFAULT_ACCEL_TIME_MS; // 默认加速时间 | |||||
route->accel_config.decel_time_ms = PLSR_DEFAULT_DECEL_TIME_MS; // 默认减速时间 | |||||
route->accel_config.accel_algorithm = PLSR_ACCEL_LINEAR; // 默认线性加减速 | |||||
// 初始化运行状态参数 - 清零所有运行时状态 | // 初始化运行状态参数 - 清零所有运行时状态 | ||||
route->run_state = PLSR_STATE_IDLE; // 运行状态:空闲 | route->run_state = PLSR_STATE_IDLE; // 运行状态:空闲 | ||||
@@ -1235,11 +1234,6 @@ void PLSR_Route_Init(PLSR_RouteConfig_t* route) | |||||
route->wait_start_tick = 0; // 等待开始时刻:清零 | route->wait_start_tick = 0; // 等待开始时刻:清零 | ||||
route->act_start_tick = 0; // ACT开始时刻:清零 | route->act_start_tick = 0; // ACT开始时刻:清零 | ||||
// 初始化所有段的配置 - 遍历并初始化每个段 | |||||
for (uint8_t i = 0; i < PLSR_MAX_SECTIONS; i++) { | |||||
PLSR_Section_Init(&route->section[i], i + 1); // 段号从1开始 | |||||
} | |||||
PLSR_PWM_Stop(); // 停止PWM输出 | PLSR_PWM_Stop(); // 停止PWM输出 | ||||
PLSR_TIM6_Stop(); // 停止TIM6定时器 | PLSR_TIM6_Stop(); // 停止TIM6定时器 | ||||
} | } | ||||
@@ -1267,14 +1261,13 @@ void PLSR_Route_Start(PLSR_RouteConfig_t* route) | |||||
// 状态检查 - 避免重复启动 | // 状态检查 - 避免重复启动 | ||||
if (route->route_state == PLSR_ROUTE_RUNNING) return; | if (route->route_state == PLSR_ROUTE_RUNNING) return; | ||||
//启动时初始化用户可配置参数. | |||||
PLSR_Route_Set(route); | |||||
// 路径状态初始化 | // 路径状态初始化 | ||||
route->route_state = PLSR_ROUTE_RUNNING; //< 设置路径状态为运行中 | |||||
route->current_section_num = 1; //< 从第1段开始执行 | |||||
route->current_freq = route->start_freq; //< 设置当前频率为起始频率 | |||||
route->pulse_count = 0; //< 清零脉冲计数 | |||||
// 重置脉冲计数器 - 现在使用软件计数 | |||||
route->pulse_count = 0; // 直接重置软件脉冲计数 | |||||
route->route_state = PLSR_ROUTE_RUNNING; //< 设置路径状态为运行中 | |||||
route->current_section_num = route->start_section; //< 从起始段开始执行 | |||||
route->current_freq = route->start_freq; //< 设置当前频率为起始频率 | |||||
route->pulse_count = 0; //< 清零脉冲计数 | |||||
// PWM输出初始化 - 根据起始频率决定是否启动 | // PWM输出初始化 - 根据起始频率决定是否启动 | ||||
if (route->start_freq > 0) { | if (route->start_freq > 0) { | ||||
@@ -1314,35 +1307,6 @@ void PLSR_Route_Stop(PLSR_RouteConfig_t* route) | |||||
// ==================== PLSR段控制函数实现 ==================== | |||||
/** | |||||
* @brief 初始化PLSR段配置 | |||||
* @param section: 段配置结构体指针 | |||||
* @param section_num: 段号(1-10) | |||||
* @retval None | |||||
* @note 初始化单个段的所有参数 | |||||
*/ | |||||
void PLSR_Section_Init(PLSR_SectionConfig_t* section, uint8_t section_num) | |||||
{ | |||||
if (section == NULL || section_num == 0 || section_num > PLSR_MAX_SECTIONS) return; | |||||
// 基本参数初始化 | |||||
section->section_num = section_num; | |||||
section->target_freq = section_num*1000; | |||||
section->target_pulse = 5000; | |||||
section->next_section = (section_num < PLSR_MAX_SECTIONS) ? (section_num + 1) : 0; | |||||
section->section_state = PLSR_SECTION_IDLE; | |||||
// 注意:加减速参数现在在路径级别配置,不在段级别 | |||||
// 等待条件初始化 | |||||
section->wait_condition.wait_type = PLSR_WAIT_PLUSEEND; | |||||
section->wait_condition.wait_time_ms = PLSR_DEFAULT_WAIT_TIME_MS; | |||||
section->wait_condition.act_time_ms = PLSR_DEFAULT_ACT_TIME_MS; | |||||
section->wait_condition.condition_flag = 0; | |||||
section->wait_condition.ext_event_flag = 0; | |||||
} | |||||
/** | /** | ||||
* @brief PLSR段处理主函数 | * @brief PLSR段处理主函数 | ||||
@@ -290,7 +290,6 @@ void Modbus_Init(uint8_t slave_addr) | |||||
{ | { | ||||
ModbusSlave.slave_address = slave_addr; | ModbusSlave.slave_address = slave_addr; | ||||
memset(ModbusSlave.holding_regs, 0, sizeof(ModbusSlave.holding_regs)); | memset(ModbusSlave.holding_regs, 0, sizeof(ModbusSlave.holding_regs)); | ||||
memset(ModbusSlave.coils, 0, sizeof(ModbusSlave.coils)); | |||||
} | } | ||||
/** | /** | ||||
@@ -326,15 +325,9 @@ void Modbus_Process(void) | |||||
switch(function_code) | switch(function_code) | ||||
{ | { | ||||
case MODBUS_FC_READ_COILS: | |||||
Modbus_Process_Read_Coils(frame, frame_len); | |||||
break; | |||||
case MODBUS_FC_READ_HOLDING_REGS: | case MODBUS_FC_READ_HOLDING_REGS: | ||||
Modbus_Process_Read_Holding_Regs(frame, frame_len); | Modbus_Process_Read_Holding_Regs(frame, frame_len); | ||||
break; | break; | ||||
case MODBUS_FC_WRITE_MULTIPLE_COILS: | |||||
Modbus_Process_Write_Multiple_Coils(frame, frame_len); | |||||
break; | |||||
case MODBUS_FC_WRITE_MULTIPLE_REGS: | case MODBUS_FC_WRITE_MULTIPLE_REGS: | ||||
Modbus_Process_Write_Multiple_Regs(frame, frame_len); | Modbus_Process_Write_Multiple_Regs(frame, frame_len); | ||||
break; | break; | ||||
@@ -405,49 +398,6 @@ void Modbus_Handle_SendLog(uint8_t* frame, uint16_t length) | |||||
} | } | ||||
} | } | ||||
/** | |||||
* @brief 处理读线圈请求 | |||||
* @param frame 接收的Modbus帧 | |||||
* @param length 帧长度 | |||||
*/ | |||||
static void Modbus_Process_Read_Coils(uint8_t *frame, uint16_t length) | |||||
{ | |||||
if(length != 8) | |||||
{ | |||||
Modbus_Send_Exception(MODBUS_FC_READ_COILS, MODBUS_EX_ILLEGAL_DATA_VALUE); | |||||
return; | |||||
} | |||||
uint16_t start_addr = (frame[2] << 8) | frame[3]; | |||||
uint16_t coil_count = (frame[4] << 8) | frame[5]; | |||||
if(coil_count == 0 || coil_count > 2000 || start_addr + coil_count > MODBUS_COIL_COUNT) | |||||
{ | |||||
Modbus_Send_Exception(MODBUS_FC_READ_COILS, MODBUS_EX_ILLEGAL_DATA_ADDRESS); | |||||
return; | |||||
} | |||||
uint8_t response[256]; | |||||
response[0] = ModbusSlave.slave_address; | |||||
response[1] = MODBUS_FC_READ_COILS; | |||||
response[2] = (coil_count + 7) / 8; // 字节数 | |||||
uint16_t byte_count = response[2]; | |||||
for(uint16_t i = 0; i < byte_count; i++) | |||||
{ | |||||
response[3 + i] = 0; | |||||
for(uint8_t bit = 0; bit < 8 && (i * 8 + bit) < coil_count; bit++) | |||||
{ | |||||
if(Get_Coil_Bit(start_addr + i * 8 + bit)) | |||||
{ | |||||
response[3 + i] |= (1 << bit); | |||||
} | |||||
} | |||||
} | |||||
Modbus_Send_Response(response, 3 + byte_count); | |||||
} | |||||
/** | /** | ||||
* @brief 读保持寄存器请求 | * @brief 读保持寄存器请求 | ||||
* @param frame 接收的Modbus帧 | * @param frame 接收的Modbus帧 | ||||
@@ -461,7 +411,7 @@ void Modbus_Handle_SendLog(uint8_t* frame, uint16_t length) | |||||
return; | return; | ||||
} | } | ||||
uint16_t start_addr = (frame[2] << 8) | frame[3]; | |||||
uint16_t start_addr = ((frame[2] << 8) | frame[3]) - MODBUS_OFFSET; | |||||
uint16_t reg_count = (frame[4] << 8) | frame[5]; | uint16_t reg_count = (frame[4] << 8) | frame[5]; | ||||
if(reg_count == 0 || reg_count > 125 || start_addr + reg_count > MODBUS_HOLDING_REG_COUNT) | if(reg_count == 0 || reg_count > 125 || start_addr + reg_count > MODBUS_HOLDING_REG_COUNT) | ||||
@@ -485,51 +435,7 @@ void Modbus_Handle_SendLog(uint8_t* frame, uint16_t length) | |||||
Modbus_Send_Response(response, 3 + reg_count * 2); | Modbus_Send_Response(response, 3 + reg_count * 2); | ||||
} | } | ||||
/** | |||||
* @brief 处理写多个线圈请求 | |||||
* @param frame 接收的Modbus帧 | |||||
* @param length 帧长度 | |||||
*/ | |||||
static void Modbus_Process_Write_Multiple_Coils(uint8_t *frame, uint16_t length) | |||||
{ | |||||
if(length < 9) | |||||
{ | |||||
Modbus_Send_Exception(MODBUS_FC_WRITE_MULTIPLE_COILS, MODBUS_EX_ILLEGAL_DATA_VALUE); | |||||
return; | |||||
} | |||||
uint16_t start_addr = (frame[2] << 8) | frame[3]; | |||||
uint16_t coil_count = (frame[4] << 8) | frame[5]; | |||||
uint8_t byte_count = frame[6]; | |||||
if(coil_count == 0 || coil_count > 1968 || start_addr + coil_count > MODBUS_COIL_COUNT || | |||||
byte_count != (coil_count + 7) / 8 || length != 9 + byte_count) | |||||
{ | |||||
Modbus_Send_Exception(MODBUS_FC_WRITE_MULTIPLE_COILS, MODBUS_EX_ILLEGAL_DATA_VALUE); | |||||
return; | |||||
} | |||||
// 写入线圈数据 | |||||
for(uint16_t i = 0; i < coil_count; i++) | |||||
{ | |||||
uint8_t byte_index = i / 8; | |||||
uint8_t bit_index = i % 8; | |||||
uint8_t coil_value = (frame[7 + byte_index] >> bit_index) & 0x01; | |||||
Set_Coil_Bit(start_addr + i, coil_value); | |||||
} | |||||
// 发送响应 | |||||
uint8_t response[8]; | |||||
response[0] = ModbusSlave.slave_address; | |||||
response[1] = MODBUS_FC_WRITE_MULTIPLE_COILS; | |||||
response[2] = (start_addr >> 8) & 0xFF; | |||||
response[3] = start_addr & 0xFF; | |||||
response[4] = (coil_count >> 8) & 0xFF; | |||||
response[5] = coil_count & 0xFF; | |||||
Modbus_Send_Response(response, 6); | |||||
} | |||||
/** | /** | ||||
* @brief 处理写单个保持寄存器请求 | * @brief 处理写单个保持寄存器请求 | ||||
* @param frame 接收的Modbus帧 | * @param frame 接收的Modbus帧 | ||||
@@ -543,16 +449,17 @@ void Modbus_Handle_SendLog(uint8_t* frame, uint16_t length) | |||||
return; | return; | ||||
} | } | ||||
uint16_t reg_addr = (frame[2] << 8) | frame[3]; | |||||
uint16_t reg_addr = ((frame[2] << 8) | frame[3]); | |||||
uint16_t write_addr = ((frame[2] << 8) | frame[3]) - MODBUS_OFFSET; | |||||
uint16_t write_num = (frame[4] << 8) | frame[5]; | uint16_t write_num = (frame[4] << 8) | frame[5]; | ||||
if(reg_addr > MODBUS_HOLDING_REG_COUNT) | |||||
if(write_addr > MODBUS_HOLDING_REG_COUNT) | |||||
{ | { | ||||
Modbus_Send_Exception(MODBUS_FC_WRITE_REG, MODBUS_EX_ILLEGAL_DATA_ADDRESS); | Modbus_Send_Exception(MODBUS_FC_WRITE_REG, MODBUS_EX_ILLEGAL_DATA_ADDRESS); | ||||
return; | return; | ||||
} | } | ||||
ModbusSlave.holding_regs[reg_addr] = write_num; | |||||
ModbusSlave.holding_regs[write_addr] = write_num; | |||||
BackupSRAM_SaveRegData(); | BackupSRAM_SaveRegData(); | ||||
@@ -565,7 +472,7 @@ void Modbus_Handle_SendLog(uint8_t* frame, uint16_t length) | |||||
response[4] = (write_num >> 8) & 0xFF; | response[4] = (write_num >> 8) & 0xFF; | ||||
response[5] = write_num & 0xFF; | response[5] = write_num & 0xFF; | ||||
Modbus_Send_Response(response, 8); | |||||
Modbus_Send_Response(response, 6); | |||||
} | } | ||||
/** | /** | ||||
@@ -581,14 +488,15 @@ void Modbus_Handle_SendLog(uint8_t* frame, uint16_t length) | |||||
return; | return; | ||||
} | } | ||||
uint16_t start_addr = (frame[2] << 8) | frame[3]; | |||||
uint16_t start_addr = ((frame[2] << 8) | frame[3]); | |||||
uint16_t write_addr = ((frame[2] << 8) | frame[3]) - MODBUS_OFFSET; | |||||
uint16_t reg_count = (frame[4] << 8) | frame[5]; | uint16_t reg_count = (frame[4] << 8) | frame[5]; | ||||
uint8_t byte_count = frame[6]; | uint8_t byte_count = frame[6]; | ||||
if(reg_count == 0 || reg_count > 123 || start_addr + reg_count > MODBUS_HOLDING_REG_COUNT || | |||||
if(reg_count == 0 || reg_count > 123 || write_addr + reg_count > MODBUS_HOLDING_REG_COUNT || | |||||
byte_count != reg_count * 2 || length != 9 + byte_count) | byte_count != reg_count * 2 || length != 9 + byte_count) | ||||
{ | { | ||||
Modbus_Send_Exception(MODBUS_FC_WRITE_MULTIPLE_REGS, MODBUS_EX_ILLEGAL_DATA_VALUE); | |||||
Modbus_Send_Exception(MODBUS_FC_WRITE_MULTIPLE_REGS, MODBUS_EX_ILLEGAL_DATA_ADDRESS); | |||||
return; | return; | ||||
} | } | ||||
@@ -596,7 +504,7 @@ void Modbus_Handle_SendLog(uint8_t* frame, uint16_t length) | |||||
for(uint16_t i = 0; i < reg_count; i++) | for(uint16_t i = 0; i < reg_count; i++) | ||||
{ | { | ||||
uint16_t reg_value = (frame[7 + i * 2] << 8) | frame[8 + i * 2]; | uint16_t reg_value = (frame[7 + i * 2] << 8) | frame[8 + i * 2]; | ||||
ModbusSlave.holding_regs[start_addr + i] = reg_value; | |||||
ModbusSlave.holding_regs[write_addr + i] = reg_value; | |||||
} | } | ||||
BackupSRAM_SaveRegData(); | BackupSRAM_SaveRegData(); | ||||
@@ -646,43 +554,7 @@ void Modbus_Handle_SendLog(uint8_t* frame, uint16_t length) | |||||
USART1_SendData_DMA(response, 5); | USART1_SendData_DMA(response, 5); | ||||
} | } | ||||
/** | |||||
* @brief 获取线圈位状态 | |||||
* @param addr 线圈地址 | |||||
* @return 线圈状态 (0或1) | |||||
*/ | |||||
static uint8_t Get_Coil_Bit(uint16_t addr) | |||||
{ | |||||
if(addr >= MODBUS_COIL_COUNT) return 0; | |||||
uint16_t byte_index = addr / 8; | |||||
uint8_t bit_index = addr % 8; | |||||
return (ModbusSlave.coils[byte_index] >> bit_index) & 0x01; | |||||
} | |||||
/** | |||||
* @brief 设置线圈位状态 | |||||
* @param addr 线圈地址 | |||||
* @param value 线圈状态 (0或1) | |||||
*/ | |||||
static void Set_Coil_Bit(uint16_t addr, uint8_t value) | |||||
{ | |||||
if(addr >= MODBUS_COIL_COUNT) return; | |||||
uint16_t byte_index = addr / 8; | |||||
uint8_t bit_index = addr % 8; | |||||
if(value) | |||||
{ | |||||
ModbusSlave.coils[byte_index] |= (1 << bit_index); | |||||
} | |||||
else | |||||
{ | |||||
ModbusSlave.coils[byte_index] &= ~(1 << bit_index); | |||||
} | |||||
} | |||||
/** | /** | ||||
* @brief 设置保持寄存器值 | * @brief 设置保持寄存器值 | ||||
* @param addr 寄存器地址 | * @param addr 寄存器地址 | ||||
@@ -709,25 +581,5 @@ void Modbus_Handle_SendLog(uint8_t* frame, uint16_t length) | |||||
} | } | ||||
return 0; | return 0; | ||||
} | } | ||||
/** | |||||
* @brief 设置线圈状态 | |||||
* @param addr 线圈地址 | |||||
* @param value 线圈状态 | |||||
*/ | |||||
void Modbus_SetCoil(uint16_t addr, uint8_t value) | |||||
{ | |||||
Set_Coil_Bit(addr, value); | |||||
} | |||||
/** | |||||
* @brief 获取线圈状态 | |||||
* @param addr 线圈地址 | |||||
* @return 线圈状态 | |||||
*/ | |||||
uint8_t Modbus_GetCoil(uint16_t addr) | |||||
{ | |||||
return Get_Coil_Bit(addr); | |||||
} | |||||
/* USER CODE END 1 */ | /* USER CODE END 1 */ |
@@ -12,12 +12,12 @@ | |||||
<ByteLimit>50</ByteLimit> | <ByteLimit>50</ByteLimit> | ||||
</Stack> | </Stack> | ||||
<StLinkDriver> | <StLinkDriver> | ||||
<stlinkserialNo>46232557</stlinkserialNo> | |||||
<stlinkfoundProbes /> | |||||
<CStepIntDis>_ 0</CStepIntDis> | <CStepIntDis>_ 0</CStepIntDis> | ||||
<LeaveTargetRunning>_ 0</LeaveTargetRunning> | <LeaveTargetRunning>_ 0</LeaveTargetRunning> | ||||
<stlinkResetStyle>0</stlinkResetStyle> | <stlinkResetStyle>0</stlinkResetStyle> | ||||
<stlinkResetStrategy>2</stlinkResetStrategy> | <stlinkResetStrategy>2</stlinkResetStrategy> | ||||
<stlinkserialNo>46232557</stlinkserialNo> | |||||
<stlinkfoundProbes /> | |||||
</StLinkDriver> | </StLinkDriver> | ||||
<DebugChecksum> | <DebugChecksum> | ||||
<Checksum>3949072944</Checksum> | <Checksum>3949072944</Checksum> | ||||