From 8b72eb79003f26a5207442eb28f83ded23e442dd Mon Sep 17 00:00:00 2001 From: 1923777848 <1923777848@qq.com> Date: Wed, 6 Aug 2025 16:57:33 +0800 Subject: [PATCH 01/11] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=AE=9A=E6=97=B6?= =?UTF-8?q?=E5=99=A8=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TrainCamp_zhangcheng_PLSR/app/inc/plsr.h | 25 ++ TrainCamp_zhangcheng_PLSR/app/src/main.c | 33 +- TrainCamp_zhangcheng_PLSR/app/src/plsr.c | 61 +++ TrainCamp_zhangcheng_PLSR/bsp/inc/time.h | 55 +++ TrainCamp_zhangcheng_PLSR/bsp/src/time.c | 371 ++++++++++++++++++ TrainCamp_zhangcheng_PLSR/iar/PLSR.ewp | 6 + TrainCamp_zhangcheng_PLSR/modbus/inc/modbus.h | 11 - 7 files changed, 520 insertions(+), 42 deletions(-) create mode 100644 TrainCamp_zhangcheng_PLSR/app/inc/plsr.h create mode 100644 TrainCamp_zhangcheng_PLSR/app/src/plsr.c create mode 100644 TrainCamp_zhangcheng_PLSR/bsp/inc/time.h create mode 100644 TrainCamp_zhangcheng_PLSR/bsp/src/time.c diff --git a/TrainCamp_zhangcheng_PLSR/app/inc/plsr.h b/TrainCamp_zhangcheng_PLSR/app/inc/plsr.h new file mode 100644 index 0000000..287e77d --- /dev/null +++ b/TrainCamp_zhangcheng_PLSR/app/inc/plsr.h @@ -0,0 +1,25 @@ +/** + * @file plsr.h + * @author zhangcheng + * @brief PLSR指令功能接口文件 + * @version v0.1 + * @date 2025-08-06 + * + * @copyright Copyright (c) 2025 + */ + + + #include "../../modbus/inc/modbus.h" + + +/** + * @brief PLSR功能初始化 + * @details + * + * @param[in] 无 + * + * @return RESUIL 初始化结果 + * @retval MODBUS_TURE 成功 + * @retval MODBUS_FALSE 失败 + */ +RESUIL PLSRInit(void); diff --git a/TrainCamp_zhangcheng_PLSR/app/src/main.c b/TrainCamp_zhangcheng_PLSR/app/src/main.c index c48b8e7..084f181 100644 --- a/TrainCamp_zhangcheng_PLSR/app/src/main.c +++ b/TrainCamp_zhangcheng_PLSR/app/src/main.c @@ -4,37 +4,7 @@ #include "../modbus/inc/modbus_operate_module.h" #include "../modbus/inc/modbus_ack_module.h" #include "../modbus/inc/modbus_link_check_module.h" - - -// PVD初始化函数,设置PVD阈值和中断模式 -void PVD_Init(void) -{ - // 使能PWR时钟 - RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); - - // 设置PVD阈值为2.9V,可以根据你的电源电压选择其他值 - PWR_PVDLevelConfig(PWR_PVDLevel_7); - - // 使能PVD - PWR_PVDCmd(ENABLE); - - // 使能PVD外部中断线 - EXTI_ClearITPendingBit(EXTI_Line16); // 清除中断标志位 - EXTI_InitTypeDef EXTI_InitStructure; // 定义外部中断结构体 - EXTI_InitStructure.EXTI_Line = EXTI_Line16; // PVD连接到外部中断线16 - EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; // 设置为中断模式 - EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; // 设置为上升沿触发,即电压低于阈值时触发 - EXTI_InitStructure.EXTI_LineCmd = ENABLE; // 使能外部中断线 - EXTI_Init(&EXTI_InitStructure); // 初始化外部中断 - - // 设置PVD中断优先级和使能 - NVIC_InitTypeDef NVIC_InitStructure; // 定义中断控制器结构体 - NVIC_InitStructure.NVIC_IRQChannel = PVD_IRQn; // PVD中断通道 - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 6; // 抢占优先级为0 - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 子优先级为0 - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 使能中断通道 - NVIC_Init(&NVIC_InitStructure); // 初始化中断控制器 -} +#include "../inc/plsr.h" int main(void) @@ -60,6 +30,7 @@ int main(void) OperateProcModuleInit(); AckProcModuleInit(); linkCheckModuleInit(); + PLSRInit(); OSStart(); } diff --git a/TrainCamp_zhangcheng_PLSR/app/src/plsr.c b/TrainCamp_zhangcheng_PLSR/app/src/plsr.c new file mode 100644 index 0000000..f50fd48 --- /dev/null +++ b/TrainCamp_zhangcheng_PLSR/app/src/plsr.c @@ -0,0 +1,61 @@ +/** + * @file plsr.c + * @author zhangcheng + * @brief PLSR指令功能源文件 + * @version v0.1 + * @date 2025-08-06 + * + * @copyright Copyright (c) 2025 + */ + + +#include "../../system/inc/system.h" +#include "../inc/plsr.h" + + +#define PLSR_MODULE_PRIO 5 +#define PLSR_MODULE_STACK_SIZE 1024 +static OS_STK PlsrModuleStack[PLSR_MODULE_STACK_SIZE]; +static void PlsrModuleTask(void * pArg); + + +/** + * @brief PLSR功能初始化 + * @details + * + * @param[in] 无 + * + * @return RESUIL 初始化结果 + * @retval MODBUS_TURE 成功 + * @retval MODBUS_FALSE 失败 + */ +RESUIL PLSRInit(void) +{ + INT8U err; + + OS_CPU_SR cpu_sr; + OS_ENTER_CRITICAL(); + + err = OSTaskCreate( + PlsrModuleTask, + NULL, + &PlsrModuleStack[PLSR_MODULE_STACK_SIZE - 1], + PLSR_MODULE_PRIO); + + if(err != OS_ERR_NONE) + { + MODBUS_LOG("PlsrcModule init fail\r\n"); + OS_EXIT_CRITICAL(); + return MODBUS_FALSE; + } + + OS_EXIT_CRITICAL(); + + return MODBUS_TURE; + } + + + void PlsrModuleTask(void *pArg) + { + while(1); + } \ No newline at end of file diff --git a/TrainCamp_zhangcheng_PLSR/bsp/inc/time.h b/TrainCamp_zhangcheng_PLSR/bsp/inc/time.h new file mode 100644 index 0000000..43d56ea --- /dev/null +++ b/TrainCamp_zhangcheng_PLSR/bsp/inc/time.h @@ -0,0 +1,55 @@ +/** + * @file time.h + * @author zhangcheng + * @brief 定时器及PWM输出接口文件 + * @version v0.1 + * @date 2025-08-06 + * + * @copyright Copyright (c) 2025 + */ + + +#ifndef _time_H +#define _time_H + +#include "stm32f4xx.h" + + +/** + * @brief 定时器数据结构 + * @details + * @note + * @attention + */ +typedef struct TIM +{ + TIM_TypeDef *TIM; + int8_t (*init)(struct TIM *tim, uint16_t psc, uint32_t per); + void (*deInit)(struct TIM *tim); + void (*setPsc)(struct TIM *tim, uint16_t psc); + void (*setPer)(struct TIM *tim, uint32_t per); + void (*open)(struct TIM *tim); + void (*close)(struct TIM *tim); + void (*openIrq)(struct TIM *tim); + void (*closeIrq)(struct TIM *tim); + void (*registerIrq)(struct TIM *tim, void (*registerFunc)(void *pArg), + void *pArg); + void (*pwmInit)(struct TIM *tim); + void (*pwmDeInit)(struct TIM *tim); + void (*pwmSetPulse)(struct TIM *tim, uint32_t pulse); +} TIM_OBJ; + + +/** + * @brief 获取定时器 + * @details + * + * @param[in] *timName 定时器名称 + * @param "timx" x : 10、11、13、14 + * + * @return TIM 定时器结构体 + */ +TIM_OBJ GetTimObj(char *timName); + +#endif + diff --git a/TrainCamp_zhangcheng_PLSR/bsp/src/time.c b/TrainCamp_zhangcheng_PLSR/bsp/src/time.c new file mode 100644 index 0000000..5bfdb1c --- /dev/null +++ b/TrainCamp_zhangcheng_PLSR/bsp/src/time.c @@ -0,0 +1,371 @@ +/** + * @file time.h + * @author zhangcheng + * @brief 定时器及PWM输出接口文件 + * @version v0.1 + * @date 2025-08-06 + * + * @copyright Copyright (c) 2025 + */ + + +#include "../../system/inc/system.h" +#include "../inc/time.h" + + +/* 中断注册回调函数类型 */ +typedef void (*Func)(void *pArg); + +/* 中断注册回调函数列表 */ +static Func CallBackFuncList[3] = +{ + NULL, ///< TIM10 + NULL, ///< TIM11 + NULL ///< TIM13 +}; + +/* 中断注册回调参数列表 */ +static void *ArgList[3] = +{ + NULL, ///< TIM10 + NULL, ///< TIM11 + NULL ///< TIM13 +}; + +/* 可用定时器列表 */ +static char *TimNameList[] = +{ + "tim10", ///< TIM10 + "tim11", ///< TIM11 + "tim13", ///< TIM13 + "tim14" ///< TIM14 +}; + +/* 可用定时器列表参数 */ +static TIM_TypeDef *TimType[] = +{ + TIM10, ///< TIM10 + TIM11, ///< TIM11 + TIM13, ///< TIM13 + TIM13 ///< TIM14 +}; + + +/** + * @brief 定时器初始化 + * @details + * + * @param[in] *tim 定时器结构体指针 + * @param[in] psc 定时器预分频系数 + * @param[in] per 定时器重装载值 + * + * @return int8_t 返回结果 + * @retval 0 成功 + * @retval -1 失败 +*/ +int8_t TimInit(TIM_OBJ *tim, uint16_t psc, uint32_t per) +{ + TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; + + if (tim->TIM == TIM10) + RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM10,ENABLE); + else if (tim->TIM == TIM11) + RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM11,ENABLE); + else if (tim->TIM == TIM13) + RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM13,ENABLE); + else if (tim->TIM == TIM14) + RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,ENABLE); + else + return -1; + + TIM_InternalClockConfig(tim->TIM); + + TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; + TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; + TIM_TimeBaseInitStructure.TIM_Period=per; + TIM_TimeBaseInitStructure.TIM_Prescaler=psc; + TIM_TimeBaseInit(tim->TIM, &TIM_TimeBaseInitStructure); + + return 0; +} + + +/** + * @brief 定时器复位 + * @details + * + * @param[in] *tim 定时器结构体指针 + * + * @return 无 +*/ +void TimDeInit(TIM_OBJ *tim) +{ + if (tim->TIM == TIM10) + RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM10,DISABLE); + else if (tim->TIM == TIM11) + RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM11,DISABLE); + else if (tim->TIM == TIM13) + RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM13,DISABLE); + else if (tim->TIM == TIM14) + RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,DISABLE); + else + return; + + TIM_Cmd(tim->TIM, DISABLE); + TIM_DeInit(tim->TIM); +} + + +/** + * @brief 设置定时器预分频 + * @details + * + * @param[in] *tim 定时器结构体指针 + * @param[in] psc 定时器预分频系数 + * + * @return 无 +*/ +void TimSetPsc(TIM_OBJ *tim, uint16_t psc) +{ + TIM_PrescalerConfig(tim->TIM, psc, TIM_PSCReloadMode_Immediate); +} + + +/** + * @brief 设置定时器重载值 + * @details + * + * @param[in] *tim 定时器结构体指针 + * @param[in] per 定时器重装载值 + * + * @return 无 +*/ +void TimSetPer(TIM_OBJ *tim, uint32_t per) +{ + TIM_SetAutoreload(tim->TIM, per); +} + + +/** + * @brief 开启定时器 + * @details + * + * @param[in] *tim 定时器结构体指针 + * + * @return 无 +*/ +void TimOpen(TIM_OBJ *tim) +{ + TIM_Cmd(tim->TIM, ENABLE); +} + + +/** + * @brief 关闭定时器 + * @details + * + * @param[in] *tim 定时器结构体指针 + * + * @return 无 +*/ +void TimClose(TIM_OBJ *tim) +{ + TIM_Cmd(tim->TIM, DISABLE); +} + + +/** + * @brief 开启定时器更新中断 + * @details + * + * @param[in] *tim 定时器结构体指针 + * + * @return 无 +*/ +void TimOpenIrq(TIM_OBJ *tim) +{ + NVIC_InitTypeDef NVIC_InitStructure; + + TIM_ITConfig(tim->TIM, TIM_IT_Update, ENABLE); + TIM_ClearITPendingBit(tim->TIM, TIM_IT_Update); + + NVIC_InitStructure.NVIC_IRQChannel=TIM8_UP_TIM13_IRQn; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=7; + NVIC_InitStructure.NVIC_IRQChannelSubPriority=0; + NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; + NVIC_Init(&NVIC_InitStructure); +} + + +/** + * @brief 关闭定时器更新中断 + * @details + * + * @param[in] *tim 定时器结构体指针 + * + * @return 无 +*/ +void TimCloseIrq(TIM_OBJ *tim) +{ + TIM_ITConfig(tim->TIM, TIM_IT_Update, DISABLE); + TIM_ClearITPendingBit(tim->TIM, TIM_IT_Update); +} + + +/** + * @brief 注册定时器中断回调函数 + * @details + * + * @param[in] *tim 定时器结构体指针 + * @param[in] registerFunc 回调函数地址 + * @note 回调函数格式 void (*registerFunc)(void *pArg) + * + * @return 无 +*/ +void TimRegisterIrq(TIM_OBJ *tim, void (*registerFunc)(void *pArg), void *pArg) +{ + if (tim->TIM == TIM10) + { + CallBackFuncList[0] = registerFunc; + ArgList[0] = pArg; + } + else if (tim->TIM == TIM11) + { + CallBackFuncList[1] = registerFunc; + ArgList[1] = pArg; + } + else if (tim->TIM == TIM13) + { + CallBackFuncList[2] = registerFunc; + ArgList[2] = pArg; + } + else + return; +} + + +/** + * @brief PWM初始化 + * @details + * + * @param[in] *tim 定时器结构体指针 + * @param[in] pulse 脉冲宽度 + * + * @return 无 +*/ +void PwmInit(TIM_OBJ *tim) +{ + TIM_OCInitTypeDef TIM_OCInitStructure; + + TIM_OCStructInit(&TIM_OCInitStructure); + + TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; + TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; + TIM_OCInitStructure.TIM_OutputState = ENABLE; + TIM_OCInitStructure.TIM_Pulse = 0; + TIM_OC1Init(tim->TIM, &TIM_OCInitStructure); +} + + + +/** + * @brief PWM复位 + * @details + * + * @param[in] *tim 定时器结构体指针 + * + * @return 无 +*/ +void PwmDeInit(TIM_OBJ *tim) +{ + TIM_OCInitTypeDef TIM_OCInitStructure; + TIM_OCInitStructure.TIM_OutputState = DISABLE; + TIM_OCInitStructure.TIM_Pulse = 0; + TIM_OC1Init(tim->TIM, &TIM_OCInitStructure); +} + + +/** + * @brief 设置PWM脉冲宽度 + * @details + * + * @param[in] *tim 定时器结构体指针 + * @param[in] pulse PWM脉冲宽度 + * + * @return 无 +*/ +void PwmSetPulse(TIM_OBJ *tim, uint32_t pulse) +{ + TIM_SetCompare1(tim->TIM, pulse); +} + + +/** + * @brief 定时器10、11、13、14更新中断服务函数 + * @details + * + * @param[in] 无 + * + * @return 无 +*/ +void TIM8_UP_TIM13_IRQHandler(void) +{ + if (TIM_GetITStatus(TIM10,TIM_IT_Update) == SET) + { + if (ArgList[0] != NULL) + CallBackFuncList[0](ArgList[0]); + TIM_ClearITPendingBit(TIM10, TIM_IT_Update); + } + else if (TIM_GetITStatus(TIM11,TIM_IT_Update) == SET) + { + if (ArgList[1] != NULL) + CallBackFuncList[1](ArgList[1]); + TIM_ClearITPendingBit(TIM11, TIM_IT_Update); + } + else if (TIM_GetITStatus(TIM11,TIM_IT_Update) == SET) + { + if (ArgList[2] != NULL) + CallBackFuncList[2](ArgList[2]); + TIM_ClearITPendingBit(TIM12, TIM_IT_Update); + } + else + return; +} + + +/** + * @brief 获取定时器 + * @details + * + * @param[in] *timName 定时器名称 + * @param "timx" x : 10、11、13、14 + * + * @return TIM_OBJ 定时器结构体 + */ +TIM_OBJ GetTimObj(char *timName) +{ + TIM_OBJ tim; + + for (uint8_t i = 0; i < sizeof(TimNameList) / sizeof(TimNameList[0]); i++) + { + if (strcmp(timName, TimNameList[i]) == 0) + { + tim.TIM = TimType[i]; + } + } + + tim.init = &TimInit; + tim.deInit = &TimDeInit; + tim.setPsc = &TimSetPsc; + tim.setPer = &TimSetPer; + tim.open = &TimOpen; + tim.close = &TimClose; + tim.openIrq = &TimOpenIrq; + tim.closeIrq = &TimCloseIrq; + tim.registerIrq = &TimRegisterIrq; + tim.pwmInit = &PwmInit; + tim.pwmDeInit = &PwmDeInit; + tim.pwmSetPulse = &PwmSetPulse; + + return tim; +} diff --git a/TrainCamp_zhangcheng_PLSR/iar/PLSR.ewp b/TrainCamp_zhangcheng_PLSR/iar/PLSR.ewp index 53a6d96..8e18fe1 100644 --- a/TrainCamp_zhangcheng_PLSR/iar/PLSR.ewp +++ b/TrainCamp_zhangcheng_PLSR/iar/PLSR.ewp @@ -2122,6 +2122,9 @@ $PROJ_DIR$\..\app\src\main.c + + $PROJ_DIR$\..\app\src\plsr.c + BSP @@ -2131,6 +2134,9 @@ $PROJ_DIR$\..\bsp\src\led.c + + $PROJ_DIR$\..\bsp\src\time.c + CMSIS diff --git a/TrainCamp_zhangcheng_PLSR/modbus/inc/modbus.h b/TrainCamp_zhangcheng_PLSR/modbus/inc/modbus.h index 7a60e30..70353d1 100644 --- a/TrainCamp_zhangcheng_PLSR/modbus/inc/modbus.h +++ b/TrainCamp_zhangcheng_PLSR/modbus/inc/modbus.h @@ -8,17 +8,6 @@ * @copyright Copyright (c) 2025 */ - - /** - * @file modbus.h - * @author zhangcheng - * @brief modbus相关数据结构文件 - * @version v0.1 - * @date 2025-07-25 - * - * @copyright Copyright (c) 2025 - */ - #ifndef _MODBUS_H #define _MODBUS_H From 62d4addc0cd335ff6981f23c73a9edb48d01d606 Mon Sep 17 00:00:00 2001 From: 1923777848 <1923777848@qq.com> Date: Fri, 8 Aug 2025 16:10:36 +0800 Subject: [PATCH 02/11] =?UTF-8?q?=E6=B7=BB=E5=8A=A0PLSR.c?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/modbus_operate_module.c~RF1ad0af.TMP | 350 ------------------ 1 file changed, 350 deletions(-) delete mode 100644 TrainCamp_zhangcheng_PLSR/modbus/src/modbus_operate_module.c~RF1ad0af.TMP diff --git a/TrainCamp_zhangcheng_PLSR/modbus/src/modbus_operate_module.c~RF1ad0af.TMP b/TrainCamp_zhangcheng_PLSR/modbus/src/modbus_operate_module.c~RF1ad0af.TMP deleted file mode 100644 index f51a70e..0000000 --- a/TrainCamp_zhangcheng_PLSR/modbus/src/modbus_operate_module.c~RF1ad0af.TMP +++ /dev/null @@ -1,350 +0,0 @@ -/** - * @file modbus_operate_module.c - * @author zhangcheng - * @brief modbus请求操作处理模块源文件 - * @version v0.1 - * @date 2025-07-25 - * - * @copyright Copyright (c) 2025 - */ - - -#include "../../SYSTEM/inc/system.h" -#include "../inc/modbus_operate_module.h" -#include "../inc/modbus_request_module.h" -#include "../inc/modbus_ack_module.h" -#include "../inc/CRC16.h" - -#define OPERATE_PROC_MODULE_PRIO 3 -#define OPERATE_PROC_MODULE_STACK_SIZE 1024 -static CPU_STK OperateProcModuleStack[OPERATE_PROC_MODULE_STACK_SIZE]; -static OS_TCB OperateProcModuleTcb; -static OS_Q AckQueue; -static void OperateProcModuleTask(void * pArg); - -static uint16_t FlashBuffer[10000]; - -/** - * @brief 操作处理模块初始化 - * @details - * - * @param[in] 无 - * - * @return RESUIL 初始化结果 - * @retval MODBUS_TURE 成功 - * @retval MODBUS_FALSE 失败 - */ -RESUIL OperateProcModuleInit(void) -{ - OS_ERR err; - - CPU_SR_ALLOC(); - CPU_CRITICAL_ENTER(); - - OSTaskCreate( (OS_TCB * )&OperateProcModuleTcb, - (CPU_CHAR * )"OperateProcModule", - (OS_TASK_PTR )OperateProcModuleTask, - (void * )0, - (OS_PRIO )OPERATE_PROC_MODULE_PRIO, - (CPU_STK * )OperateProcModuleStack, - (CPU_STK_SIZE )OPERATE_PROC_MODULE_STACK_SIZE / 10, - (CPU_STK_SIZE )OPERATE_PROC_MODULE_STACK_SIZE, - (OS_MSG_QTY )0, - (OS_TICK )0, - (void * )0, - (OS_OPT )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR), - (OS_ERR * )&err); - if(err != OS_ERR_NONE) - { - MODBUS_LOG("OperateProcModule init fail\r\n"); - return MODBUS_FALSE; - } - - OSQCreate(&AckQueue, "AckQueue", 1, &err); - if(err != OS_ERR_NONE) - { - MODBUS_LOG("OperateProcModule data queue create fail\r\n"); - OSTaskDel(&OperateProcModuleTcb, &err); - return MODBUS_FALSE; - } - - CPU_CRITICAL_EXIT(); - - return MODBUS_TURE; -} - - - -/** - * @brief 请求帧处理模块 - * @details - * - * @param[in] *pArg 任务参数 - * - * @return RESUIL 初始化结果 - * @retval MODBUS_TURE 成功 - * @retval MODBUS_FALSE 失败 - */ -static void OperateProcModuleTask(void *pArg) -{ - OS_ERR err = OS_ERR_NONE; - - REQUEST_FRAME requestFrame; - ACK_FRAME ackFrame; - RESUIL res; - - uint8_t *pCoil = (uint8_t *)COIL_REGISTER_ADRR; - uint16_t *pDataRegister = (uint16_t *)DATA_REGISTER_ADRR; - uint16_t *pKeepRegister = (uint16_t *)KEEP_REGISTER_ADRR; - - while(1) - { - /* 阻塞式接收请求数据帧 */ - res = RequestOperateDataRead(&requestFrame, 0); - - if (res != MODBUS_TURE) - { - continue; - } - - ackFrame.deviceNumber = requestFrame.deviceNumber; - ackFrame.functionCode = requestFrame.functionCode; - - switch (requestFrame.functionCode) - { - case READ_COIL: - { - ackFrame.operateType = OPERATE_READ; - ackFrame.operateObjType = OPERATE_COIL; - ackFrame.format = MODBUS_STANDARD; - ackFrame.returnByteCount = requestFrame.readCount / 8; - ackFrame.data = pCoil + (requestFrame.memoryAddr / 8); - ackFrame.errorCode = ERROR_NONE; - OSQPost(&AckQueue, &ackFrame, 1, - OS_OPT_POST_FIFO | OS_OPT_POST_NO_SCHED, &err); - AckProcModuleSetFlags(NORMAL_FLAG_BIT); - break; - } - case READ_KEEP_REGISTER: - { - ackFrame.operateType = OPERATE_READ; - ackFrame.operateObjType = OPERATE_REGISTER; - ackFrame.format = MODBUS_STANDARD; - ackFrame.returnByteCount = requestFrame.readCount * 2; - - if ( requestFrame.memoryAddr < 0x270F) - { - ackFrame.data = (uint8_t *)(pDataRegister + requestFrame.memoryAddr); - } - else - { - requestFrame.memoryAddr -= 0xA080; - //ackFrame.data = (uint8_t *)(pKeepRegister + requestFrame.memoryAddr); - ackFrame.data = (uint8_t *)(FlashBuffer + requestFrame.memoryAddr); - } - - //ackFrame.data = (uint8_t *)(pKeepRegister + requestFrame.memoryAddr); - ackFrame.errorCode = ERROR_NONE; - OSQPost(&AckQueue, &ackFrame, 1, - OS_OPT_POST_FIFO | OS_OPT_POST_NO_SCHED, &err); - AckProcModuleSetFlags(NORMAL_FLAG_BIT); - break; - } - case WRITE_ONE_COIL: - { - ackFrame.operateType = OPERATE_WRITE; - ackFrame.operateObjType = OPERATE_COIL; - ackFrame.format = MODBUS_STANDARD; - ackFrame.returnByteCount = requestFrame.readCount; - ackFrame.memoryAddr = requestFrame.memoryAddr; - ackFrame.data = pCoil + (requestFrame.memoryAddr / 8); - - if (requestFrame.data[0] == 0xFF) - { - *ackFrame.data |= (0x01 << (requestFrame.memoryAddr % 8)); - } - else - { - *ackFrame.data &= ~(0x01 << (requestFrame.memoryAddr % 8)); - } - - ackFrame.errorCode = ERROR_NONE; - OSQPost(&AckQueue, &ackFrame, 1, - OS_OPT_POST_FIFO | OS_OPT_POST_NO_SCHED, &err); - AckProcModuleSetFlags(NORMAL_FLAG_BIT); - - break; - } - case WRITE_COIL: - { - ackFrame.operateType = OPERATE_WRITE; - ackFrame.operateObjType = OPERATE_COIL; - ackFrame.format = MODBUS_STANDARD; - ackFrame.returnByteCount = requestFrame.writeCount; - ackFrame.memoryAddr = requestFrame.memoryAddr; - ackFrame.data = pCoil + (requestFrame.memoryAddr / 8); - - uint8_t offset = requestFrame.memoryAddr % 8; - - for (uint16_t i = 0; i < requestFrame.writeByteLenght; i++) - { - for (uint8_t j = 0; j < 8; j++) - { - if (*requestFrame.data & (0x01 << j)) - { - *ackFrame.data |= (1 << offset); - } - else - { - *ackFrame.data &= ~(1 << offset); - } - offset++; - if (offset == 8) - { - offset = 0; - ackFrame.data++; - } - } - requestFrame.data++; - } - - ackFrame.errorCode = ERROR_NONE; - OSQPost(&AckQueue, &ackFrame, 1, - OS_OPT_POST_FIFO | OS_OPT_POST_NO_SCHED, &err); - AckProcModuleSetFlags(NORMAL_FLAG_BIT); - break; - } - case WRITE_KEEP_REGISTER: - { - ackFrame.operateType = OPERATE_WRITE; - ackFrame.operateObjType = OPERATE_REGISTER; - ackFrame.format = MODBUS_STANDARD; - ackFrame.returnByteCount = requestFrame.writeCount; - ackFrame.memoryAddr = requestFrame.memoryAddr; - - if ( requestFrame.memoryAddr < 0x270F) - { - ackFrame.data = (uint8_t *)(pDataRegister + requestFrame.memoryAddr); - - for (uint16_t i = 0; i < requestFrame.writeCount; i++) - { - ((uint16_t *)ackFrame.data)[i] = (requestFrame.data[2*i] << 8) | requestFrame.data[2*i+1]; - } - - ackFrame.errorCode = ERROR_NONE; - OSQPost(&AckQueue, &ackFrame, 1, - OS_OPT_POST_FIFO | OS_OPT_POST_NO_SCHED, &err); - AckProcModuleSetFlags(NORMAL_FLAG_BIT); - - } - else - { - requestFrame.memoryAddr -= 0xA080; - //ackFrame.data = (uint8_t *)(pKeepRegister + requestFrame.memoryAddr); - ackFrame.data = (uint8_t *)(FlashBuffer + requestFrame.memoryAddr); - } - - - FLASH_Unlock(); - FLASH_DataCacheCmd(ENABLE); - - memcpy((void *)FlashBuffer, (void *)KEEP_REGISTER_ADRR, KEEP_REGISTER_SIZE); - - while (FLASH_GetStatus() != FLASH_COMPLETE); - - for (uint16_t i = 0; i < requestFrame.writeCount; i++) - { - FlashBuffer[requestFrame.memoryAddr + i] = (requestFrame.data[2*i] << 8) | requestFrame.data[2*i+1]; - } - - ackFrame.errorCode = ERROR_NONE; - OSQPost(&AckQueue, &ackFrame, 1, - OS_OPT_POST_FIFO, &err); - AckProcModuleSetFlags(NORMAL_FLAG_BIT); - -// FLASH_EraseSector(FLASH_Sector_4, VoltageRange_3); - for (uint16_t i = 0; i < KEEP_REGISTER_SIZE / 2; i++) - { -// FLASH_ProgramHalfWord((uint32_t)KEEP_REGISTER_ADRR + 2 * i, FlashBuffer[i]); - while (FLASH_GetStatus() != FLASH_COMPLETE); - } - - FLASH_DataCacheCmd(ENABLE); - FLASH_Lock(); - - break; - } - case READ_OUT_SCOPE_REGISTER: //0x10000 ~ 0x1A000 40KB - { - ackFrame.operateType = OPERATE_READ; - ackFrame.operateObjType = OPERATE_REGISTER; - ackFrame.format = MODBUS_EXT; - ackFrame.returnByteCount = requestFrame.readCount * 2; - ackFrame.data = (uint8_t *)((DATA_REGISTER_ADRR + DATA_REGISTER_NUMBER) + requestFrame.extMemoryAddr - 0x10000); - ackFrame.errorCode = ERROR_NONE; - OSQPost(&AckQueue, &ackFrame, 1, - OS_OPT_POST_FIFO | OS_OPT_POST_NO_SCHED, &err); - AckProcModuleSetFlags(NORMAL_FLAG_BIT); - break; - } - case READ_ALL_SINGULAR_REGISTER: - { - ackFrame.operateType = OPERATE_READ; - ackFrame.operateObjType = OPERATE_REGISTER; - ackFrame.format = MODBUS_STANDARD; - ackFrame.returnByteCount = 0xFFFF; - ackFrame.memoryAddr = requestFrame.memoryAddr; - ackFrame.data = (uint8_t *)(pDataRegister + requestFrame.memoryAddr); - ackFrame.errorCode = ERROR_NONE; - OSQPost(&AckQueue, &ackFrame, 1, - OS_OPT_POST_FIFO | OS_OPT_POST_NO_SCHED, &err); - AckProcModuleSetFlags(NORMAL_FLAG_BIT); - break; - } - case READ_CORRESPONDENCE_HISTORY: - { - ackFrame.data = (uint8_t *)0x08020000; - OSQPost(&AckQueue, &ackFrame, 1, - OS_OPT_POST_FIFO | OS_OPT_POST_NO_SCHED, &err); - AckProcModuleSetFlags(NORMAL_FLAG_BIT); - break; - break; - } - - } - } -} - - -/** - * @brief 读取请求帧 - * @details - * - * @param[out] *requestFrame 接收请求数据帧结构体地址 - * @param[in] timeOut 读取请求帧数据超时时间 - * - * @return RESUIL 读取结果 - * @retval MODBUS_TURE 成功 - * @retval MODBUS_FALSE 失败 - */ -RESUIL OperateAckFrameRead(ACK_FRAME *ackFrame, OS_TICK timeOut) -{ - OS_ERR err; - OS_MSG_SIZE msgSize; - void *pMsgAddr = NULL; - - pMsgAddr = OSQPend(&AckQueue, - timeOut, - OS_OPT_PEND_BLOCKING, - &msgSize, - 0, - &err); - - if (err == OS_ERR_NONE) - { - memcpy(ackFrame, pMsgAddr, sizeof(ACK_FRAME)); - return MODBUS_TURE; - } - else - return MODBUS_FALSE; -} From 49d9775f1f385d8cec223f9a9ccf0879d6ade285 Mon Sep 17 00:00:00 2001 From: 1923777848 <1923777848@qq.com> Date: Fri, 8 Aug 2025 16:11:27 +0800 Subject: [PATCH 03/11] =?UTF-8?q?=E6=B7=BB=E5=8A=A0PLSR.c?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 +- TrainCamp_zhangcheng_PLSR/app/inc/plsr.h | 70 ++++++++++ TrainCamp_zhangcheng_PLSR/app/src/plsr.c | 107 +++++++++++++- TrainCamp_zhangcheng_PLSR/bsp/inc/time.h | 13 +- TrainCamp_zhangcheng_PLSR/bsp/src/time.c | 132 +++++++++++------- .../modbus/src/modbus_ack_module.c | 4 +- .../modbus/src/modbus_link_check_module.c | 4 +- .../modbus/src/modbus_operate_module.c | 4 +- .../modbus/src/modbus_request_module.c | 44 +++++- TrainCamp_zhangcheng_PLSR/system/src/usart.c | 2 +- 10 files changed, 306 insertions(+), 77 deletions(-) diff --git a/.gitignore b/.gitignore index 4cd487f..791d435 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ TrainCamp_zhangcheng_PLSR/.vscode TrainCamp_zhangcheng_PLSR/iar/Debug TrainCamp_zhangcheng_PLSR/iar/settings TrainCamp_zhangcheng_PLSR/iar/PLSR.dep -TrainCamp_zhangcheng_PLSR/iar/PLSR.ewt \ No newline at end of file +TrainCamp_zhangcheng_PLSR/iar/PLSR.ewt +.TMP \ No newline at end of file diff --git a/TrainCamp_zhangcheng_PLSR/app/inc/plsr.h b/TrainCamp_zhangcheng_PLSR/app/inc/plsr.h index 287e77d..226f707 100644 --- a/TrainCamp_zhangcheng_PLSR/app/inc/plsr.h +++ b/TrainCamp_zhangcheng_PLSR/app/inc/plsr.h @@ -12,6 +12,76 @@ #include "../../modbus/inc/modbus.h" +/** + * @brief 系统参数块 + * @details + * @note + * @attention + */ +typedef enum { + SYSTEM_PARAM_BLOCK_0 = 0, ///< 系统参数块0,默认参数块,不可修改 + SYSTEM_PARAM_BLOCK_1, ///< 系统参数块1 + SYSTEM_PARAM_BLOCK_2, ///< 系统参数块2 + SYSTEM_PARAM_BLOCK_3, ///< 系统参数块3 + SYSTEM_PARAM_BLOCK_4 ///< 系统参数块4 +} PLSR_SYSTEM_PARAM_BLOCK; + + + +/** + * @brief 输出端口 + * @details + * @note + * @attention + */ +typedef enum { + OUTPUT_PORT_Y0 = 0, ///< 输出端子Y0 + OUTPUT_PORT_Y1, ///< 输出端子Y1 + OUTPUT_PORT_Y2, ///< 输出端子Y2 + OUTPUT_PORT_Y3 ///< 输出端子Y3 +} PLSR_OUTPUT_PORT; + + +/** + * @brief 输出模式 + * @details + * @note + * @attention + */ +typedef enum { + RELATIVE_MODE = 0, ///< 相对模式 + ABSOLUTE_MODE ///< 绝对模式 +} PLSR_OUTPUT_MODE; + + +/** + * @brief 参数错误类型 + * @details + * @note + * @attention + */ +typedef enum { + PLSR_ERROR_NONE = 0, ///< 无错误 + PLSR_FREQ_EXCE_MAX_VALUE ///< 超过最大输出频率 +} PLSR_ERROR_TYPE; + + +/** + * @brief PLSR指令结构类型 + * @details + * @note + * @attention + */ +typedef struct +{ + uint16_t *dataStartAddr; ///< 起始数据地址 + uint16_t *userParamBlockAddr; ///< 用户参数块地址 + PLSR_SYSTEM_PARAM_BLOCK systemParamBlock; ///< 系统参数 + PLSR_OUTPUT_PORT outputPort; ///< 输出端子 + PLSR_OUTPUT_PORT mode; ///< 输出模式 +} PLSR_CMD; + + /** * @brief PLSR功能初始化 * @details diff --git a/TrainCamp_zhangcheng_PLSR/app/src/plsr.c b/TrainCamp_zhangcheng_PLSR/app/src/plsr.c index f50fd48..b0dc897 100644 --- a/TrainCamp_zhangcheng_PLSR/app/src/plsr.c +++ b/TrainCamp_zhangcheng_PLSR/app/src/plsr.c @@ -10,6 +10,7 @@ #include "../../system/inc/system.h" +#include "../../bsp/inc/time.h" #include "../inc/plsr.h" @@ -50,12 +51,106 @@ RESUIL PLSRInit(void) } OS_EXIT_CRITICAL(); - + return MODBUS_TURE; - } +} + + +#include "../../bsp/inc/gpio.h" +void Callack(void *pArg) +{ + gpio_obj_t *gpio_f_6; + gpio_f_6 = get_gpio_obj("gpio_f"); + gpio_f_6->gpio_init(gpio_f_6, gpio_pin_6, "OUT_PP", "UP"); + + if (*((uint8_t *)pArg) < 13) + printf("Callback tim2 count %d\r\n", (*((uint8_t *)pArg))++); + else + printf("Callback tim13 count %d\r\n", (*((uint8_t *)pArg))++); + uint16_t read_gpio_pin = 0; + read_gpio_pin = gpio_f_6->gpio_read_output(gpio_f_6); + if(gpio_f_6->gpio_pin & read_gpio_pin) + { + gpio_f_6->gpio_set_output(gpio_f_6, gpio_f_6->gpio_pin, 0); + #ifdef USE_LED_PIN_TRACE + pDev->led_state = "on"; + #endif + } + else + { + gpio_f_6->gpio_set_output(gpio_f_6, gpio_f_6->gpio_pin, 1); + #ifdef USE_LED_PIN_TRACE + pDev->led_state = "off"; + #endif + } +} +/** + * @brief PLSR处理任务 + * @details + * + * @param[in] *pArg 任务参数 + * + * @return RESUIL 初始化结果 + * @retval MODBUS_TURE 成功 + * @retval MODBUS_FALSE 失败 + */ +void PlsrModuleTask(void *pArg) +{ + TIM_OBJ tim2; + TIM_OBJ tim10; + int8_t res; + uint8_t pArgment = 0; + + int32_t pulseFreq = 0; + int32_t pulseCount = 0; + uint32_t pulseReload = 0; + + res = GetTimObj("tim2", &tim2); + res = GetTimObj("tim10", &tim10); + if (res) + while (1); + + tim2.init(&tim2, 8399, 9999); + tim2.open(&tim2); + tim2.registerIrq(&tim2, &Callack, &pArgment); + tim2.openIrq(&tim2); + + tim10.init(&tim10, pulseFreq, pulseCount * 2); + tim10.open(&tim10); + + if (pulseFreq >= 0 || pulseFreq <= 5000) + { + pulseReload = (uint32_t)(((1.f / (float)pulseFreq) * 1000 * 1000) / 20); + tim10.init(&tim10, 1679, pulseReload); + } + else if (pulseFreq >= 5000 || pulseFreq <= 100000) + { + pulseReload = (uint32_t)(((1.f / (float)pulseFreq) * 1000 * 1000) / 1); + tim10.init(&tim10, 83, pulseReload); + } + + tim10.pwmInit(&tim10); + tim10.pwmSetPulse(&tim10, pulseReload / 2); + + while (1) + { + + } +} + +//1HZ +//psc 1680 +//per 50000 + +//5KHZ +//psc 1680 +//per 10 +//100KHZ +//psc 84 +//per 840 - void PlsrModuleTask(void *pArg) - { - while(1); - } \ No newline at end of file +//定时器3 外部输入时钟源ETR引脚PB4,定时器11输出 +//定时器4 外部输入时钟源ETR引脚PB6,定时器14输出 +//定时器9 内部输入时钟源ITx主从模式定时器10 +//定时器12 内部输入时钟源ITx主从模式定时器13 \ No newline at end of file diff --git a/TrainCamp_zhangcheng_PLSR/bsp/inc/time.h b/TrainCamp_zhangcheng_PLSR/bsp/inc/time.h index 43d56ea..109197e 100644 --- a/TrainCamp_zhangcheng_PLSR/bsp/inc/time.h +++ b/TrainCamp_zhangcheng_PLSR/bsp/inc/time.h @@ -44,12 +44,17 @@ typedef struct TIM * @brief 获取定时器 * @details * - * @param[in] *timName 定时器名称 - * @param "timx" x : 10、11、13、14 + * @param[in] *timName 定时器名称 + * + * @param[out] *timObj 接收定时器参数地址 * - * @return TIM 定时器结构体 + * @return int8_t 返回结果 + * @retval 0 成功 + * @retval -1 失败 + * + * @note *timName "timx" x : 10、11、13、14 */ -TIM_OBJ GetTimObj(char *timName); +int8_t GetTimObj(char *timName, TIM_OBJ *timObj); #endif diff --git a/TrainCamp_zhangcheng_PLSR/bsp/src/time.c b/TrainCamp_zhangcheng_PLSR/bsp/src/time.c index 5bfdb1c..552797f 100644 --- a/TrainCamp_zhangcheng_PLSR/bsp/src/time.c +++ b/TrainCamp_zhangcheng_PLSR/bsp/src/time.c @@ -17,24 +17,23 @@ typedef void (*Func)(void *pArg); /* 中断注册回调函数列表 */ -static Func CallBackFuncList[3] = +static Func CallBackFuncList[] = { - NULL, ///< TIM10 - NULL, ///< TIM11 + NULL, ///< TIM2 NULL ///< TIM13 }; /* 中断注册回调参数列表 */ -static void *ArgList[3] = +static void *ArgList[] = { - NULL, ///< TIM10 - NULL, ///< TIM11 + NULL, ///< TIM2 NULL ///< TIM13 }; /* 可用定时器列表 */ static char *TimNameList[] = { + "tim2", ///< TIM2 "tim10", ///< TIM10 "tim11", ///< TIM11 "tim13", ///< TIM13 @@ -44,10 +43,11 @@ static char *TimNameList[] = /* 可用定时器列表参数 */ static TIM_TypeDef *TimType[] = { + TIM2, ///< TIM2 TIM10, ///< TIM10 TIM11, ///< TIM11 TIM13, ///< TIM13 - TIM13 ///< TIM14 + TIM14 ///< TIM14 }; @@ -67,8 +67,16 @@ int8_t TimInit(TIM_OBJ *tim, uint16_t psc, uint32_t per) { TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; - if (tim->TIM == TIM10) + if (tim->TIM == TIM2) + { + RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); + } + + else if (tim->TIM == TIM10) + { RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM10,ENABLE); + } + else if (tim->TIM == TIM11) RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM11,ENABLE); else if (tim->TIM == TIM13) @@ -85,7 +93,9 @@ int8_t TimInit(TIM_OBJ *tim, uint16_t psc, uint32_t per) TIM_TimeBaseInitStructure.TIM_Period=per; TIM_TimeBaseInitStructure.TIM_Prescaler=psc; TIM_TimeBaseInit(tim->TIM, &TIM_TimeBaseInitStructure); - + + TIM_GenerateEvent(tim->TIM, TIM_EventSource_Update); + return 0; } @@ -100,7 +110,9 @@ int8_t TimInit(TIM_OBJ *tim, uint16_t psc, uint32_t per) */ void TimDeInit(TIM_OBJ *tim) { - if (tim->TIM == TIM10) + if (tim->TIM == TIM2) + RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,DISABLE); + else if (tim->TIM == TIM10) RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM10,DISABLE); else if (tim->TIM == TIM11) RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM11,DISABLE); @@ -189,7 +201,12 @@ void TimOpenIrq(TIM_OBJ *tim) TIM_ITConfig(tim->TIM, TIM_IT_Update, ENABLE); TIM_ClearITPendingBit(tim->TIM, TIM_IT_Update); - NVIC_InitStructure.NVIC_IRQChannel=TIM8_UP_TIM13_IRQn; + if (tim->TIM == TIM2) + NVIC_InitStructure.NVIC_IRQChannel=TIM2_IRQn; + else if(tim->TIM == TIM13) + NVIC_InitStructure.NVIC_IRQChannel=TIM8_UP_TIM13_IRQn; + else + return; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=7; NVIC_InitStructure.NVIC_IRQChannelSubPriority=0; NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; @@ -224,21 +241,16 @@ void TimCloseIrq(TIM_OBJ *tim) */ void TimRegisterIrq(TIM_OBJ *tim, void (*registerFunc)(void *pArg), void *pArg) { - if (tim->TIM == TIM10) + if (tim->TIM == TIM2) { CallBackFuncList[0] = registerFunc; ArgList[0] = pArg; } - else if (tim->TIM == TIM11) + else if (tim->TIM == TIM13) { CallBackFuncList[1] = registerFunc; ArgList[1] = pArg; } - else if (tim->TIM == TIM13) - { - CallBackFuncList[2] = registerFunc; - ArgList[2] = pArg; - } else return; } @@ -301,35 +313,40 @@ void PwmSetPulse(TIM_OBJ *tim, uint32_t pulse) /** - * @brief 定时器10、11、13、14更新中断服务函数 + * @brief 定时器2更新中断服务函数 * @details * * @param[in] 无 * * @return 无 */ -void TIM8_UP_TIM13_IRQHandler(void) +void TIM2_IRQHandler(void) { - if (TIM_GetITStatus(TIM10,TIM_IT_Update) == SET) + if (TIM_GetITStatus(TIM2,TIM_IT_Update) == SET) { if (ArgList[0] != NULL) CallBackFuncList[0](ArgList[0]); - TIM_ClearITPendingBit(TIM10, TIM_IT_Update); + TIM_ClearITPendingBit(TIM2, TIM_IT_Update); } - else if (TIM_GetITStatus(TIM11,TIM_IT_Update) == SET) +} + + +/** + * @brief 定时器13更新中断服务函数 + * @details + * + * @param[in] 无 + * + * @return 无 +*/ +void TIM8_UP_TIM13_IRQHandler(void) +{ + if (TIM_GetITStatus(TIM13,TIM_IT_Update) == SET) { if (ArgList[1] != NULL) CallBackFuncList[1](ArgList[1]); - TIM_ClearITPendingBit(TIM11, TIM_IT_Update); + TIM_ClearITPendingBit(TIM13, TIM_IT_Update); } - else if (TIM_GetITStatus(TIM11,TIM_IT_Update) == SET) - { - if (ArgList[2] != NULL) - CallBackFuncList[2](ArgList[2]); - TIM_ClearITPendingBit(TIM12, TIM_IT_Update); - } - else - return; } @@ -337,35 +354,46 @@ void TIM8_UP_TIM13_IRQHandler(void) * @brief 获取定时器 * @details * - * @param[in] *timName 定时器名称 - * @param "timx" x : 10、11、13、14 + * @param[in] *timName 定时器名称 + * @note "timx" x : 10、11、13、14 + * @param[out] *timObj 接收定时器参数地址 * - * @return TIM_OBJ 定时器结构体 + * @return int8_t 返回结果 + * @retval 0 成功 + * @retval -1 失败 */ -TIM_OBJ GetTimObj(char *timName) +int8_t GetTimObj(char *timName, TIM_OBJ *timObj) { - TIM_OBJ tim; + uint8_t getTimFlag = 0; + + if (!timObj) + return -1; for (uint8_t i = 0; i < sizeof(TimNameList) / sizeof(TimNameList[0]); i++) { if (strcmp(timName, TimNameList[i]) == 0) { - tim.TIM = TimType[i]; + timObj->TIM = TimType[i]; + getTimFlag = 1; + break; } } - tim.init = &TimInit; - tim.deInit = &TimDeInit; - tim.setPsc = &TimSetPsc; - tim.setPer = &TimSetPer; - tim.open = &TimOpen; - tim.close = &TimClose; - tim.openIrq = &TimOpenIrq; - tim.closeIrq = &TimCloseIrq; - tim.registerIrq = &TimRegisterIrq; - tim.pwmInit = &PwmInit; - tim.pwmDeInit = &PwmDeInit; - tim.pwmSetPulse = &PwmSetPulse; - - return tim; + if (!getTimFlag) + return -1; + + timObj->init = &TimInit; + timObj->deInit = &TimDeInit; + timObj->setPsc = &TimSetPsc; + timObj->setPer = &TimSetPer; + timObj->open = &TimOpen; + timObj->close = &TimClose; + timObj->openIrq = &TimOpenIrq; + timObj->closeIrq = &TimCloseIrq; + timObj->registerIrq = &TimRegisterIrq; + timObj->pwmInit = &PwmInit; + timObj->pwmDeInit = &PwmDeInit; + timObj->pwmSetPulse = &PwmSetPulse; + + return 0; } diff --git a/TrainCamp_zhangcheng_PLSR/modbus/src/modbus_ack_module.c b/TrainCamp_zhangcheng_PLSR/modbus/src/modbus_ack_module.c index eef1ff6..a3f54e7 100644 --- a/TrainCamp_zhangcheng_PLSR/modbus/src/modbus_ack_module.c +++ b/TrainCamp_zhangcheng_PLSR/modbus/src/modbus_ack_module.c @@ -76,9 +76,7 @@ RESUIL AckProcModuleInit(void) * * @param[in] *pArg 任务参数 * - * @return RESUIL 初始化结果 - * @retval MODBUS_TURE 成功 - * @retval MODBUS_FALSE 失败 + * @return 无 */ static void AckProcModuleTask(void *pArg) { diff --git a/TrainCamp_zhangcheng_PLSR/modbus/src/modbus_link_check_module.c b/TrainCamp_zhangcheng_PLSR/modbus/src/modbus_link_check_module.c index 808fcb7..1c1e831 100644 --- a/TrainCamp_zhangcheng_PLSR/modbus/src/modbus_link_check_module.c +++ b/TrainCamp_zhangcheng_PLSR/modbus/src/modbus_link_check_module.c @@ -76,9 +76,7 @@ RESUIL linkCheckModuleInit(void) * * @param[in] *pArg 任务参数 * - * @return RESUIL 初始化结果 - * @retval MODBUS_TURE 成功 - * @retval MODBUS_FALSE 失败 + * @return 无 */ static void LinkCheckModuleTask(void *pArg) { diff --git a/TrainCamp_zhangcheng_PLSR/modbus/src/modbus_operate_module.c b/TrainCamp_zhangcheng_PLSR/modbus/src/modbus_operate_module.c index b6051ca..4dd964a 100644 --- a/TrainCamp_zhangcheng_PLSR/modbus/src/modbus_operate_module.c +++ b/TrainCamp_zhangcheng_PLSR/modbus/src/modbus_operate_module.c @@ -77,9 +77,7 @@ RESUIL OperateProcModuleInit(void) * * @param[in] *pArg 任务参数 * - * @return RESUIL 初始化结果 - * @retval MODBUS_TURE 成功 - * @retval MODBUS_FALSE 失败 + * @return 无 */ static void OperateProcModuleTask(void *pArg) { diff --git a/TrainCamp_zhangcheng_PLSR/modbus/src/modbus_request_module.c b/TrainCamp_zhangcheng_PLSR/modbus/src/modbus_request_module.c index f186a71..327faba 100644 --- a/TrainCamp_zhangcheng_PLSR/modbus/src/modbus_request_module.c +++ b/TrainCamp_zhangcheng_PLSR/modbus/src/modbus_request_module.c @@ -79,7 +79,19 @@ RESUIL RequestProcModuleInit(void) -RESUIL AddrIsTure(uint8_t *data, uint8_t dataLenght, ACK_FRAME *ackFrame) +/** + * @brief 判断地址是否合法 + * @details + * + * @param[in] *data 地址起始字节 + * @param[in] *dataLenght 地址长度 + * @param[out] *ackFrame 异常码输出 + * + * @return RESUIL 检测结果 + * @retval MODBUS_TURE 成功 + * @retval MODBUS_FALSE 失败 +*/ +static RESUIL AddrIsTure(uint8_t *data, uint8_t dataLenght, ACK_FRAME *ackFrame) { uint32_t addr; if (dataLenght == 2) @@ -114,6 +126,20 @@ RESUIL AddrIsTure(uint8_t *data, uint8_t dataLenght, ACK_FRAME *ackFrame) return MODBUS_FALSE; } + + +/** + * @brief 判断数据长度是否合法 + * @details + * + * @param[in] *countLenght 计算的数据长度 + * @param[in] *buffLenght 接收到的数据长度 + * @param[out] *ackFrame 异常码输出 + * + * @return RESUIL 检测结果 + * @retval MODBUS_TURE 成功 + * @retval MODBUS_FALSE 失败 +*/ RESUIL DataLenghtIsTure(uint16_t countLenght, uint16_t buffLenght, ACK_FRAME *ackFrame) { if (countLenght != buffLenght) @@ -128,6 +154,18 @@ RESUIL DataLenghtIsTure(uint16_t countLenght, uint16_t buffLenght, ACK_FRAME *ac } } + +/** + * @brief 判断数据长度是否为零 + * @details + * + * @param[in] *data 数据帧数据长度起始地址 + * @param[out] *ackFrame 异常码输出 + * + * @return RESUIL 检测结果 + * @retval MODBUS_TURE 成功 + * @retval MODBUS_FALSE 失败 +*/ RESUIL DataCountIsZero(uint8_t *data, ACK_FRAME *ackFrame) { if (((data[0] << 8) | data[1]) == 0) @@ -149,9 +187,7 @@ RESUIL DataCountIsZero(uint8_t *data, ACK_FRAME *ackFrame) * * @param[in] *pArg 任务参数 * - * @return RESUIL 初始化结果 - * @retval MODBUS_TURE 成功 - * @retval MODBUS_FALSE 失败 + * @return 无 */ static void RequestProcModuleTask(void *pArg) { diff --git a/TrainCamp_zhangcheng_PLSR/system/src/usart.c b/TrainCamp_zhangcheng_PLSR/system/src/usart.c index 1de74d0..dcd2fb8 100644 --- a/TrainCamp_zhangcheng_PLSR/system/src/usart.c +++ b/TrainCamp_zhangcheng_PLSR/system/src/usart.c @@ -21,7 +21,7 @@ void _sys_exit(int x) //ضfputc int fputc(int ch, FILE *f) { - while((USART1->SR&0X40)==0);//ѭ,ֱ + while((USART1->SR&0X80)==0);//ѭ,ֱ USART1->DR = (u8) ch; return ch; } From 42778b3d2cd93e9a1c94ef2dc7a819cc673b6c53 Mon Sep 17 00:00:00 2001 From: 1923777848 <1923777848@qq.com> Date: Mon, 11 Aug 2025 21:32:03 +0800 Subject: [PATCH 04/11] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=9B=B4=E7=BA=BF?= =?UTF-8?q?=E5=8A=A0=E5=87=8F=E9=80=9F=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TrainCamp_zhangcheng_PLSR/app/inc/plsr.h | 100 +++- TrainCamp_zhangcheng_PLSR/app/src/plsr.c | 428 +++++++++++++++--- TrainCamp_zhangcheng_PLSR/bsp/src/gpio.c | 27 +- TrainCamp_zhangcheng_PLSR/bsp/src/time.c | 49 +- TrainCamp_zhangcheng_PLSR/system/src/system.c | 2 +- 5 files changed, 518 insertions(+), 88 deletions(-) diff --git a/TrainCamp_zhangcheng_PLSR/app/inc/plsr.h b/TrainCamp_zhangcheng_PLSR/app/inc/plsr.h index 226f707..5f86d60 100644 --- a/TrainCamp_zhangcheng_PLSR/app/inc/plsr.h +++ b/TrainCamp_zhangcheng_PLSR/app/inc/plsr.h @@ -9,7 +9,16 @@ */ - #include "../../modbus/inc/modbus.h" +#include "../../modbus/inc/modbus.h" + + +/** + * @brief 最大支持脉冲段 + * @details + * @note + * @attention + */ +#define PLSR_PULSE_MAX_SEGMENT_NUM 10 /** @@ -42,6 +51,57 @@ typedef enum { } PLSR_OUTPUT_PORT; +/** + * @brief 输出方向端口 + * @details + * @note + * @attention + */ +typedef enum { + OUTPUT_DIR_PORT_Y12 = 0, ///< 输出方向端子Y12 + OUTPUT_DIR_PORT_Y13, ///< 输出方向端子Y13 + OUTPUT_DIR_PORT_Y14, ///< 输出方向端子Y14 + OUTPUT_DIR_PORT_Y15 ///< 输出方向端子Y15 +} PLSR_OUTPUT_DIR_PORT; + + +/** + * @brief 方向端子方向逻辑 + * @details + * @note + * @attention + */ +typedef enum { + OUTPUT_DIR_CORRECT = 0, ///< 正逻辑 + OUTPUT_DIR_NEGATIVE, ///< 负逻辑 +} PLSR_OUTPUT_DIR_PORT_LOGIC; + + +/** + * @brief 输入信号端口 + * @details + * @note + * @attention + */ +typedef enum { + INPUT_EXT_PORT_X4 = 0, ///< 输入端子X4 + INPUT_EXT_PORT_X5, ///< 输入端子X5 +} PLSR_INPUT_EXT_PORT; + + +/** + * @brief 加减速模式模式 + * @details + * @note + * @attention + */ +typedef enum { + STRAIGHT_LINE_MODE = 0, ///< 直线加减速模式 + S_CURVE_MODE, ///< S曲线加减速模式 + SINE_CURVE_MODE ///< 正弦曲线加减速模式 +} PLSR_ACC_DEC_SPEED_MODE; + + /** * @brief 输出模式 * @details @@ -66,6 +126,21 @@ typedef enum { } PLSR_ERROR_TYPE; +/** + * @brief PLSR脉冲段 + * @details + * @note + * @attention + */ +typedef struct +{ + int32_t pulseFreq; + int32_t pulseNumber; + int16_t waitType; + int16_t jumpNumber; +} PLSR_SEGMENT; + + /** * @brief PLSR指令结构类型 * @details @@ -74,12 +149,23 @@ typedef enum { */ typedef struct { - uint16_t *dataStartAddr; ///< 起始数据地址 - uint16_t *userParamBlockAddr; ///< 用户参数块地址 - PLSR_SYSTEM_PARAM_BLOCK systemParamBlock; ///< 系统参数 - PLSR_OUTPUT_PORT outputPort; ///< 输出端子 - PLSR_OUTPUT_PORT mode; ///< 输出模式 -} PLSR_CMD; + PLSR_OUTPUT_PORT outputPort; ///< 输出端子 + PLSR_OUTPUT_DIR_PORT dirPort; ///< 输出方向端子 + PLSR_INPUT_EXT_PORT extPort; ///< 输入端子 + PLSR_OUTPUT_DIR_PORT_LOGIC dirLogic; ///< 输出方向端子逻辑 + PLSR_ACC_DEC_SPEED_MODE accDecSpeedMode; ///< 加减速模式 + PLSR_OUTPUT_MODE outMode; ///< 输出模式 + uint16_t dirDelayTime; ///< 方向延时时间 + uint16_t segmentAllNum; ///< 总段数 + uint16_t startRunSegment; ///< 起始执行段数 + uint16_t currentSegment; ///< 当前执行段数 + uint32_t defaultSpeed; ///< 默认速度 + uint16_t defaultAccSpeedTime; ///< 默认加速时间 + uint16_t defaultDecSpeedTime; ///< 默认减速时间 + int32_t monitorPulseNum; ///< 监控脉冲数量 + uint16_t sendEnableState; ///< 脉冲发送使能 + PLSR_SEGMENT segment[PLSR_PULSE_MAX_SEGMENT_NUM]; ///< 各段数参数 +} PLSR; /** diff --git a/TrainCamp_zhangcheng_PLSR/app/src/plsr.c b/TrainCamp_zhangcheng_PLSR/app/src/plsr.c index b0dc897..c825d1a 100644 --- a/TrainCamp_zhangcheng_PLSR/app/src/plsr.c +++ b/TrainCamp_zhangcheng_PLSR/app/src/plsr.c @@ -12,6 +12,19 @@ #include "../../system/inc/system.h" #include "../../bsp/inc/time.h" #include "../inc/plsr.h" +#include "../../bsp/inc/gpio.h" + + +typedef struct { + int32_t inc; + int32_t dec; + int32_t currentSpeed; + uint8_t currentState; ///< 0:无操作 1:匀速 2:加速 3:减速 + uint8_t currentPart; + int32_t firstPartNum; + int32_t secondPartNum; + int32_t thirdPartNum; +} SEGMENT_PART; #define PLSR_MODULE_PRIO 5 @@ -19,6 +32,14 @@ static OS_STK PlsrModuleStack[PLSR_MODULE_STACK_SIZE]; static void PlsrModuleTask(void * pArg); +static void TimCallBack(void *pArg); +static void ReadRegisterParam(PLSR *plsr); +static void configPulsePort(PLSR *plsr); +static void ComputePartNum(PLSR *plsr, SEGMENT_PART *segmentPart); +static void FirstSegmentProc(SEGMENT_PART *segmentPart); +static void SecondSegmentProc(SEGMENT_PART *segmentPart); +static void ThirdSegmentProc(SEGMENT_PART *segmentPart); + /** * @brief PLSR功能初始化 @@ -56,34 +77,6 @@ RESUIL PLSRInit(void) } -#include "../../bsp/inc/gpio.h" -void Callack(void *pArg) -{ - gpio_obj_t *gpio_f_6; - gpio_f_6 = get_gpio_obj("gpio_f"); - gpio_f_6->gpio_init(gpio_f_6, gpio_pin_6, "OUT_PP", "UP"); - - if (*((uint8_t *)pArg) < 13) - printf("Callback tim2 count %d\r\n", (*((uint8_t *)pArg))++); - else - printf("Callback tim13 count %d\r\n", (*((uint8_t *)pArg))++); - uint16_t read_gpio_pin = 0; - read_gpio_pin = gpio_f_6->gpio_read_output(gpio_f_6); - if(gpio_f_6->gpio_pin & read_gpio_pin) - { - gpio_f_6->gpio_set_output(gpio_f_6, gpio_f_6->gpio_pin, 0); - #ifdef USE_LED_PIN_TRACE - pDev->led_state = "on"; - #endif - } - else - { - gpio_f_6->gpio_set_output(gpio_f_6, gpio_f_6->gpio_pin, 1); - #ifdef USE_LED_PIN_TRACE - pDev->led_state = "off"; - #endif - } -} /** * @brief PLSR处理任务 * @details @@ -94,63 +87,374 @@ void Callack(void *pArg) * @retval MODBUS_TURE 成功 * @retval MODBUS_FALSE 失败 */ +TIM_OBJ tim2; +TIM_OBJ tim10; +int32_t accSpeedSlope = 0; +int32_t decSpeedSlope = 0; +int32_t accTime = 0; +int32_t decTime = 0; +int32_t accPulse = 0; +int32_t decPulse = 0; +int32_t uniformTime = 0; +int32_t uniformPulse = 0; +uint8_t currentSegment = 0; +uint32_t currentSpeed = 0; + + +int32_t pulseFreq = 168 - 1; +uint32_t pulseReload = 20; + +SEGMENT_PART currentSeg = { + .currentState = 2, + .currentPart = 1 + }; +PLSR plsr = { + .segmentAllNum = 1, + .segment[0].jumpNumber = 0 + }; + void PlsrModuleTask(void *pArg) { - TIM_OBJ tim2; - TIM_OBJ tim10; int8_t res; uint8_t pArgment = 0; +uint8_t RunFlag = 0; + - int32_t pulseFreq = 0; - int32_t pulseCount = 0; - uint32_t pulseReload = 0; + uint8_t nextSegment = plsr.startRunSegment; + +// ReadRegisterParam(&plsr); res = GetTimObj("tim2", &tim2); res = GetTimObj("tim10", &tim10); - if (res) - while (1); + + tim10.init(&tim10, 168 - 1, 65535); +// tim10.open(&tim10); + tim10.registerIrq(&tim10, TimCallBack, ¤tSeg); +// tim10.openIrq(&tim10); + tim10.pwmInit(&tim10); + tim10.pwmSetPulse(&tim10, TIM10->ARR); - tim2.init(&tim2, 8399, 9999); - tim2.open(&tim2); - tim2.registerIrq(&tim2, &Callack, &pArgment); - tim2.openIrq(&tim2); + plsr.sendEnableState = 0; + plsr.accDecSpeedMode = STRAIGHT_LINE_MODE; + plsr.segment[0].pulseFreq = 2000; + plsr.segment[0].pulseNumber = 3000; + plsr.defaultSpeed = 1000; + plsr.defaultAccSpeedTime = 10; + plsr.defaultDecSpeedTime = 10; + while (1) + { +// ReadRegisterParam(&plsr); + currentSegment = plsr.currentSegment; - tim10.init(&tim10, pulseFreq, pulseCount * 2); - tim10.open(&tim10); + if (plsr.sendEnableState != 1) + { + continue; + } - if (pulseFreq >= 0 || pulseFreq <= 5000) - { - pulseReload = (uint32_t)(((1.f / (float)pulseFreq) * 1000 * 1000) / 20); - tim10.init(&tim10, 1679, pulseReload); - } - else if (pulseFreq >= 5000 || pulseFreq <= 100000) - { - pulseReload = (uint32_t)(((1.f / (float)pulseFreq) * 1000 * 1000) / 1); - tim10.init(&tim10, 83, pulseReload); - } + if (plsr.segment[currentSegment].pulseFreq <= 5000) + pulseFreq = 1680 - 1; + else if ((plsr.segment[currentSegment].pulseFreq > 5000) + && (plsr.segment[currentSegment].pulseFreq <= 100000)) + pulseFreq = 84 - 1; + else + continue; - tim10.pwmInit(&tim10); - tim10.pwmSetPulse(&tim10, pulseReload / 2); + /* 配置输入输出相关端子 */ + configPulsePort(&plsr); - while (1) - { + if (plsr.outMode == ABSOLUTE_MODE) + { + if (plsr.monitorPulseNum + >= plsr.segment[currentSegment].pulseNumber) + { + continue; + } + } + + if ((plsr.accDecSpeedMode == STRAIGHT_LINE_MODE) && (RunFlag == 0)) + { + RunFlag = 1; + ComputePartNum(&plsr, ¤tSeg); + + switch (currentSeg.currentPart) + { + case 1: + { + FirstSegmentProc(¤tSeg); + break; + } + case 2: + { + SecondSegmentProc(¤tSeg); + break; + } + case 3: + { + ThirdSegmentProc(¤tSeg); + break; + } + } + } } } //1HZ -//psc 1680 +//psc 1680 一次10us //per 50000 - //5KHZ //psc 1680 //per 10 - //100KHZ -//psc 84 -//per 840 - +//psc 168 一次0.5us +//per 10 //定时器3 外部输入时钟源ETR引脚PB4,定时器11输出 //定时器4 外部输入时钟源ETR引脚PB6,定时器14输出 //定时器9 内部输入时钟源ITx主从模式定时器10 -//定时器12 内部输入时钟源ITx主从模式定时器13 \ No newline at end of file +//定时器12 内部输入时钟源ITx主从模式定时器13 + +void TimCallBack(void *pArg) +{ + uint16_t reloadValue = 0; + uint32_t diffValue; + static int32_t pulseCount = 0; + static uint8_t endFlag = 0; + + pulseCount++; + if (currentSeg.currentPart == 1) + { + switch (currentSeg.currentState) + { + case 2: ///< 加速 + { + if ((currentSpeed + currentSeg.inc) >= plsr.segment[currentSegment].pulseFreq) + { + diffValue = currentSpeed + currentSeg.inc - plsr.segment[currentSegment].pulseFreq; + currentSeg.inc = currentSeg.inc - diffValue; + } + currentSpeed += currentSeg.inc; + + reloadValue = 168000000 / (TIM10->PSC + 1) / (currentSpeed); + tim10.setPer(&tim10, reloadValue - 1); + tim10.pwmSetPulse(&tim10, TIM10->ARR / 2 + 1); + + if (pulseCount > currentSeg.firstPartNum - 1) + { + currentSeg.currentPart = 2; + pulseCount = 0; + tim10.registerIrq(&tim10, TimCallBack, ¤tSeg.currentPart); + } + break; + } + default: + { + break; + } + } + } + else if (currentSeg.currentPart == 2) + { + reloadValue = 168000000 / (TIM10->PSC + 1) / (currentSpeed); + tim10.setPer(&tim10, reloadValue - 1); + tim10.pwmSetPulse(&tim10, TIM10->ARR / 2 + 1); + + if (pulseCount > currentSeg.secondPartNum - 1) + { + currentSeg.currentPart = 3; + pulseCount = 0; + tim10.registerIrq(&tim10, TimCallBack, ¤tSeg.currentPart); + + currentSeg.dec = currentSpeed / currentSeg.thirdPartNum; + } + } + else if (currentSeg.currentPart == 3) + { + if (((currentSpeed - currentSeg.dec) <= 0) + || (pulseCount > currentSeg.thirdPartNum - 1)) + { + pulseCount = 0; + currentSeg.currentPart = 1; + + tim10.setPer(&tim10, 100); + tim10.pwmSetPulse(&tim10, 65535); + tim10.closeIrq(&tim10); + + tim10.registerIrq(&tim10, TimCallBack, ¤tSeg.currentPart); + return; + } + currentSpeed -= currentSeg.dec; + reloadValue = 168000000 / (TIM10->PSC + 1) / (currentSpeed); + tim10.setPer(&tim10, reloadValue - 1); + tim10.pwmSetPulse(&tim10, TIM10->ARR / 2 + 1); + } +} + + +static void ReadRegisterParam(PLSR *plsr) +{ + int16_t *pDataRegister = (uint16_t *)(DATA_REGISTER_ADRR + 0x1000); + + plsr->outputPort = pDataRegister[0]; + plsr->dirPort = pDataRegister[1]; + plsr->extPort = pDataRegister[2]; + plsr->dirDelayTime = pDataRegister[3]; + plsr->dirLogic = pDataRegister[4]; + plsr->accDecSpeedMode = pDataRegister[5]; + plsr->outMode = pDataRegister[6]; + plsr->segmentAllNum = pDataRegister[7]; + plsr->startRunSegment = pDataRegister[8]; + plsr->defaultSpeed = *((uint32_t *)pDataRegister[9]); + plsr->defaultAccSpeedTime = pDataRegister[11]; + plsr->defaultDecSpeedTime = pDataRegister[12]; + plsr->monitorPulseNum = *((int32_t *)(pDataRegister + 0x1000)); + plsr->sendEnableState = *(pDataRegister + 0x2000); + + pDataRegister += 0x100; + for (uint8_t i = 0; i < PLSR_PULSE_MAX_SEGMENT_NUM; i++) + { + plsr->segment[i].pulseFreq = *((uint32_t *)pDataRegister[i]); + plsr->segment[i].pulseNumber = *((int32_t *)pDataRegister[i + 2]); + plsr->segment[i].waitType = pDataRegister[i + 4]; + plsr->segment[i].jumpNumber = pDataRegister[i + 5]; + + pDataRegister += 0x10; + } +} + + +static void configPulsePort(PLSR *plsr) +{ + gpio_obj_t *outDirPort = NULL; + + outDirPort = get_gpio_obj("gpio_h"); + + if ((outDirPort == NULL) || (plsr == NULL)) + return; + + switch (plsr->dirPort) + { + case OUTPUT_DIR_PORT_Y12: + { + outDirPort->gpio_init(outDirPort, gpio_pin_9, "OUT_PP", "UP"); + outDirPort->gpio_set_output(outDirPort, gpio_pin_9, 1); + break; + } + case OUTPUT_DIR_PORT_Y13: + { + outDirPort->gpio_init(outDirPort, gpio_pin_8, "OUT_PP", "UP"); + break; + } + case OUTPUT_DIR_PORT_Y14: + { + outDirPort->gpio_init(outDirPort, gpio_pin_7, "OUT_PP", "UP"); + break; + } + case OUTPUT_DIR_PORT_Y15: + { + outDirPort->gpio_init(outDirPort, gpio_pin_6, "OUT_PP", "UP"); + break; + } + } + // switch (plsr->outputPort) + // { + // case OUTPUT_PORT_Y0: + // { + // outDirPort->gpio_init(outDirPort, gpio_pin) + // } + // } +} + + +static void ComputePartNum(PLSR *plsr, SEGMENT_PART *segmentPart) +{ + uint32_t target = plsr->segment[currentSegment].pulseFreq; + accSpeedSlope = plsr->defaultSpeed / plsr->defaultAccSpeedTime; + decSpeedSlope = plsr->defaultSpeed / plsr->defaultDecSpeedTime; + + /* 最后一段 */ + if ((currentSegment == (plsr->segmentAllNum -1)) + && (plsr->segment[currentSegment].jumpNumber == 0)) + { + decTime = target / decSpeedSlope; + segmentPart->thirdPartNum = target / 2 * decTime / 1000; + } + else + { + segmentPart->thirdPartNum = 0; + } + + if (currentSpeed < target) + { + accTime = (target - currentSpeed) / accSpeedSlope; + segmentPart->firstPartNum = (target + currentSpeed) / 2 * accTime / 1000; + } + else if (currentSpeed > target) + { + decTime = (currentSpeed - target) / decSpeedSlope; + segmentPart->firstPartNum = (target + currentSpeed) / 2 * decTime / 1000; + } + segmentPart->secondPartNum = plsr->segment[currentSegment].pulseNumber + - segmentPart->firstPartNum + - segmentPart->thirdPartNum; +} + + +static void FirstSegmentProc(SEGMENT_PART *segmentPart) +{ + int32_t targetFreq = 0; + int32_t slope = 0; + int32_t diffValue = 0; + static int32_t incAll = 0; + + switch (segmentPart->currentState) + { + case 2 : + { + targetFreq = plsr.segment[currentSegment].pulseFreq; + slope = plsr.defaultSpeed / plsr.defaultAccSpeedTime; + segmentPart->inc = ((targetFreq - currentSpeed) / slope) + * ((targetFreq + currentSpeed) / 2) / 1000; + segmentPart->inc = (targetFreq - currentSpeed) / segmentPart->inc; + if ((currentSpeed + segmentPart->inc) >= plsr.segment[currentSegment].pulseFreq) + { + diffValue = currentSpeed + segmentPart->inc - plsr.segment[currentSegment].pulseFreq; + segmentPart->inc = segmentPart->inc - diffValue; + } + incAll += segmentPart->inc; + if (plsr.segment[currentSegment].pulseFreq <= 5000) + { + tim10.setPsc(&tim10, 1680 - 1); + if (currentSpeed != 0) + tim10.setPer(&tim10, 100000 / currentSpeed); + else + tim10.setPer(&tim10, 1000); + tim10.registerIrq(&tim10, TimCallBack, ¤tSeg.currentPart); + tim10.open(&tim10); + tim10.openIrq(&tim10); + + + } + else + { + tim10.setPsc(&tim10, 168 - 1); + tim10.setPer(&tim10, 1000000 / currentSpeed); + tim10.registerIrq(&tim10, TimCallBack, ¤tSeg.currentPart); + tim10.open(&tim10); + tim10.openIrq(&tim10); + } + + } + } +} + + +static void SecondSegmentProc(SEGMENT_PART *segmentPart) +{ + +} + + +static void ThirdSegmentProc(SEGMENT_PART *segmentPart) +{ + +} \ No newline at end of file diff --git a/TrainCamp_zhangcheng_PLSR/bsp/src/gpio.c b/TrainCamp_zhangcheng_PLSR/bsp/src/gpio.c index 2c8fbf3..a1c19d4 100644 --- a/TrainCamp_zhangcheng_PLSR/bsp/src/gpio.c +++ b/TrainCamp_zhangcheng_PLSR/bsp/src/gpio.c @@ -187,6 +187,30 @@ static gpio_obj_t g_stm32f103_gpio_g = { &g_stm32f103_gpio_g_priv }; + +/* GPIOH˽ */ +static gpio_priv_obj_t g_stm32f103_gpio_h_priv = { + GPIOH, + GPIO_Mode_IN, + (GPIOOType_TypeDef)0, + (GPIOPuPd_TypeDef)0, + RCC_AHB1Periph_GPIOH +}; +/* GPIOHṹ */ +static gpio_obj_t g_stm32f103_gpio_h = { + "gpio_h", + 0, + "gpio_mode", + gpio_init, + gpio_deinit, + gpio_set_output, + gpio_read_output, + gpio_read_input, + gpio_open_irq, + gpio_close_irq, + &g_stm32f103_gpio_h_priv +}; + /* GPIOб */ static gpio_obj_t *g_gpio_devs[] = { &g_stm32f103_gpio_a, @@ -195,7 +219,8 @@ static gpio_obj_t *g_gpio_devs[] = { &g_stm32f103_gpio_d, &g_stm32f103_gpio_e, &g_stm32f103_gpio_f, - &g_stm32f103_gpio_g + &g_stm32f103_gpio_g, + &g_stm32f103_gpio_h }; /* GPIOģʽ˽б */ diff --git a/TrainCamp_zhangcheng_PLSR/bsp/src/time.c b/TrainCamp_zhangcheng_PLSR/bsp/src/time.c index 552797f..c53adb5 100644 --- a/TrainCamp_zhangcheng_PLSR/bsp/src/time.c +++ b/TrainCamp_zhangcheng_PLSR/bsp/src/time.c @@ -20,14 +20,14 @@ typedef void (*Func)(void *pArg); static Func CallBackFuncList[] = { NULL, ///< TIM2 - NULL ///< TIM13 + NULL ///< TIM10 }; /* 中断注册回调参数列表 */ static void *ArgList[] = { NULL, ///< TIM2 - NULL ///< TIM13 + NULL ///< TIM10 }; /* 可用定时器列表 */ @@ -86,7 +86,11 @@ int8_t TimInit(TIM_OBJ *tim, uint16_t psc, uint32_t per) else return -1; - TIM_InternalClockConfig(tim->TIM); + if (tim->TIM == TIM2) + //TIM_TIxExternalClockConfig(tim->TIM, TIM_TIxExternalCLK1Source_TI1, TIM_ICPolarity_Rising, 10); + TIM_InternalClockConfig(tim->TIM); + else + TIM_InternalClockConfig(tim->TIM); TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; @@ -94,7 +98,8 @@ int8_t TimInit(TIM_OBJ *tim, uint16_t psc, uint32_t per) TIM_TimeBaseInitStructure.TIM_Prescaler=psc; TIM_TimeBaseInit(tim->TIM, &TIM_TimeBaseInitStructure); - TIM_GenerateEvent(tim->TIM, TIM_EventSource_Update); +// TIM_GenerateEvent(tim->TIM, TIM_EventSource_Update); + TIM_ClearITPendingBit(tim->TIM, TIM_IT_Update); return 0; } @@ -140,6 +145,7 @@ void TimDeInit(TIM_OBJ *tim) void TimSetPsc(TIM_OBJ *tim, uint16_t psc) { TIM_PrescalerConfig(tim->TIM, psc, TIM_PSCReloadMode_Immediate); + TIM_ClearITPendingBit(tim->TIM, TIM_IT_Update); } @@ -203,8 +209,8 @@ void TimOpenIrq(TIM_OBJ *tim) if (tim->TIM == TIM2) NVIC_InitStructure.NVIC_IRQChannel=TIM2_IRQn; - else if(tim->TIM == TIM13) - NVIC_InitStructure.NVIC_IRQChannel=TIM8_UP_TIM13_IRQn; + else if(tim->TIM == TIM10) + NVIC_InitStructure.NVIC_IRQChannel=TIM1_UP_TIM10_IRQn; else return; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=7; @@ -246,7 +252,7 @@ void TimRegisterIrq(TIM_OBJ *tim, void (*registerFunc)(void *pArg), void *pArg) CallBackFuncList[0] = registerFunc; ArgList[0] = pArg; } - else if (tim->TIM == TIM13) + else if (tim->TIM == TIM10) { CallBackFuncList[1] = registerFunc; ArgList[1] = pArg; @@ -269,13 +275,22 @@ void PwmInit(TIM_OBJ *tim) { TIM_OCInitTypeDef TIM_OCInitStructure; - TIM_OCStructInit(&TIM_OCInitStructure); - - TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; - TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; - TIM_OCInitStructure.TIM_OutputState = ENABLE; - TIM_OCInitStructure.TIM_Pulse = 0; - TIM_OC1Init(tim->TIM, &TIM_OCInitStructure); + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE); + GPIO_PinAFConfig(GPIOF, GPIO_PinSource6, GPIO_AF_TIM10); + + GPIO_InitTypeDef GPIO_InitStructure; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_Init(GPIOF,&GPIO_InitStructure); + + TIM_OCStructInit(&TIM_OCInitStructure); + TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; + TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; + TIM_OCInitStructure.TIM_OutputState = ENABLE; + TIM_OCInitStructure.TIM_Pulse = 0; + TIM_OC1Init(tim->TIM, &TIM_OCInitStructure); } @@ -339,13 +354,13 @@ void TIM2_IRQHandler(void) * * @return 无 */ -void TIM8_UP_TIM13_IRQHandler(void) +void TIM1_UP_TIM10_IRQHandler(void) { - if (TIM_GetITStatus(TIM13,TIM_IT_Update) == SET) + if (TIM_GetITStatus(TIM10,TIM_IT_Update) == SET) { if (ArgList[1] != NULL) CallBackFuncList[1](ArgList[1]); - TIM_ClearITPendingBit(TIM13, TIM_IT_Update); + TIM_ClearITPendingBit(TIM10, TIM_IT_Update); } } diff --git a/TrainCamp_zhangcheng_PLSR/system/src/system.c b/TrainCamp_zhangcheng_PLSR/system/src/system.c index 35a196b..e5aea7f 100644 --- a/TrainCamp_zhangcheng_PLSR/system/src/system.c +++ b/TrainCamp_zhangcheng_PLSR/system/src/system.c @@ -8,5 +8,5 @@ void system_hardware_init(void) usart1 = get_usart_obj("usart1"); if(NULL == usart1) while(1); - usart1->usart_init(usart1, 19200, 9, 1, 2); + usart1->usart_init(usart1, 19200, 9, 1, 1); } From ba4a9f0c58a19c9a88457f908451c2aebf72b255 Mon Sep 17 00:00:00 2001 From: 1923777848 <1923777848@qq.com> Date: Tue, 12 Aug 2025 13:45:04 +0800 Subject: [PATCH 05/11] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=9B=B4=E7=BA=BF?= =?UTF-8?q?=E5=8A=A0=E5=87=8F=E9=80=9F=E5=A4=9A=E6=AE=B5=E8=B7=B3=E8=BD=AC?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TrainCamp_zhangcheng_PLSR/app/src/plsr.c | 98 +++++++++++++----------- TrainCamp_zhangcheng_PLSR/bsp/src/time.c | 14 +++- 2 files changed, 67 insertions(+), 45 deletions(-) diff --git a/TrainCamp_zhangcheng_PLSR/app/src/plsr.c b/TrainCamp_zhangcheng_PLSR/app/src/plsr.c index c825d1a..ad8409c 100644 --- a/TrainCamp_zhangcheng_PLSR/app/src/plsr.c +++ b/TrainCamp_zhangcheng_PLSR/app/src/plsr.c @@ -99,7 +99,7 @@ int32_t uniformTime = 0; int32_t uniformPulse = 0; uint8_t currentSegment = 0; uint32_t currentSpeed = 0; - +uint8_t RunFlag = 0; int32_t pulseFreq = 168 - 1; uint32_t pulseReload = 20; @@ -109,16 +109,29 @@ SEGMENT_PART currentSeg = { .currentPart = 1 }; PLSR plsr = { - .segmentAllNum = 1, - .segment[0].jumpNumber = 0 - }; + .segmentAllNum = 4, + .defaultSpeed = 1000, + .defaultAccSpeedTime = 5, + .defaultDecSpeedTime = 10, + .segment[0].pulseFreq = 2000, + .segment[0].pulseNumber = 1000, + .segment[0].jumpNumber = 0, + .segment[1].pulseFreq = 3000, + .segment[1].pulseNumber = 2000, + .segment[1].jumpNumber = 0, + .segment[2].pulseFreq = 6000, + .segment[2].pulseNumber = 2000, + .segment[2].jumpNumber = 0, + .segment[3].pulseFreq = 9000, + .segment[3].pulseNumber = 2000, + .segment[3].jumpNumber = 0, + .startRunSegment = 0 +}; void PlsrModuleTask(void *pArg) { int8_t res; uint8_t pArgment = 0; -uint8_t RunFlag = 0; - uint8_t nextSegment = plsr.startRunSegment; @@ -134,28 +147,25 @@ uint8_t RunFlag = 0; tim10.pwmInit(&tim10); tim10.pwmSetPulse(&tim10, TIM10->ARR); - plsr.sendEnableState = 0; + plsr.sendEnableState = 1; plsr.accDecSpeedMode = STRAIGHT_LINE_MODE; - plsr.segment[0].pulseFreq = 2000; - plsr.segment[0].pulseNumber = 3000; - plsr.defaultSpeed = 1000; - plsr.defaultAccSpeedTime = 10; - plsr.defaultDecSpeedTime = 10; + + currentSegment = plsr.startRunSegment; + while (1) { // ReadRegisterParam(&plsr); - currentSegment = plsr.currentSegment; - + if (plsr.sendEnableState != 1) { continue; } if (plsr.segment[currentSegment].pulseFreq <= 5000) - pulseFreq = 1680 - 1; + pulseFreq = 3360 - 1; else if ((plsr.segment[currentSegment].pulseFreq > 5000) && (plsr.segment[currentSegment].pulseFreq <= 100000)) - pulseFreq = 84 - 1; + pulseFreq = 2 - 1; else continue; @@ -216,9 +226,7 @@ uint8_t RunFlag = 0; void TimCallBack(void *pArg) { uint16_t reloadValue = 0; - uint32_t diffValue; static int32_t pulseCount = 0; - static uint8_t endFlag = 0; pulseCount++; if (currentSeg.currentPart == 1) @@ -227,23 +235,20 @@ void TimCallBack(void *pArg) { case 2: ///< 加速 { - if ((currentSpeed + currentSeg.inc) >= plsr.segment[currentSegment].pulseFreq) + if ((currentSpeed + currentSeg.inc) >= plsr.segment[currentSegment].pulseFreq + || (pulseCount > currentSeg.firstPartNum - 1)) { - diffValue = currentSpeed + currentSeg.inc - plsr.segment[currentSegment].pulseFreq; - currentSeg.inc = currentSeg.inc - diffValue; + currentSpeed = plsr.segment[currentSegment].pulseFreq; + + currentSeg.currentPart = 2; + pulseCount = 0; } - currentSpeed += currentSeg.inc; + else + currentSpeed += currentSeg.inc; reloadValue = 168000000 / (TIM10->PSC + 1) / (currentSpeed); tim10.setPer(&tim10, reloadValue - 1); - tim10.pwmSetPulse(&tim10, TIM10->ARR / 2 + 1); - - if (pulseCount > currentSeg.firstPartNum - 1) - { - currentSeg.currentPart = 2; - pulseCount = 0; - tim10.registerIrq(&tim10, TimCallBack, ¤tSeg.currentPart); - } + tim10.pwmSetPulse(&tim10, TIM10->ARR / 2 + 1); break; } default: @@ -254,23 +259,30 @@ void TimCallBack(void *pArg) } else if (currentSeg.currentPart == 2) { - reloadValue = 168000000 / (TIM10->PSC + 1) / (currentSpeed); - tim10.setPer(&tim10, reloadValue - 1); - tim10.pwmSetPulse(&tim10, TIM10->ARR / 2 + 1); - - if (pulseCount > currentSeg.secondPartNum - 1) + if (pulseCount > currentSeg.secondPartNum - 4) { - currentSeg.currentPart = 3; - pulseCount = 0; - tim10.registerIrq(&tim10, TimCallBack, ¤tSeg.currentPart); + if ((currentSegment == (plsr.segmentAllNum -1)) + && (plsr.segment[currentSegment].jumpNumber == 0)) + { + currentSeg.currentPart = 3; + pulseCount = 0; + currentSeg.dec = currentSpeed / currentSeg.thirdPartNum; + return; + } - currentSeg.dec = currentSpeed / currentSeg.thirdPartNum; + currentSeg.currentPart = 1; + pulseCount = 0; + RunFlag = 0; + if (plsr.segment[currentSegment].jumpNumber == 0) + currentSegment++; + else + currentSegment = plsr.segment[currentSegment].jumpNumber; } } else if (currentSeg.currentPart == 3) { if (((currentSpeed - currentSeg.dec) <= 0) - || (pulseCount > currentSeg.thirdPartNum - 1)) + || (pulseCount > currentSeg.thirdPartNum)) { pulseCount = 0; currentSeg.currentPart = 1; @@ -423,16 +435,14 @@ static void FirstSegmentProc(SEGMENT_PART *segmentPart) incAll += segmentPart->inc; if (plsr.segment[currentSegment].pulseFreq <= 5000) { - tim10.setPsc(&tim10, 1680 - 1); + tim10.setPsc(&tim10, 3360 - 1); if (currentSpeed != 0) - tim10.setPer(&tim10, 100000 / currentSpeed); + tim10.setPer(&tim10, 50000 / currentSpeed); else tim10.setPer(&tim10, 1000); tim10.registerIrq(&tim10, TimCallBack, ¤tSeg.currentPart); tim10.open(&tim10); tim10.openIrq(&tim10); - - } else { diff --git a/TrainCamp_zhangcheng_PLSR/bsp/src/time.c b/TrainCamp_zhangcheng_PLSR/bsp/src/time.c index c53adb5..17e8e1f 100644 --- a/TrainCamp_zhangcheng_PLSR/bsp/src/time.c +++ b/TrainCamp_zhangcheng_PLSR/bsp/src/time.c @@ -70,19 +70,32 @@ int8_t TimInit(TIM_OBJ *tim, uint16_t psc, uint32_t per) if (tim->TIM == TIM2) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); + TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; } else if (tim->TIM == TIM10) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM10,ENABLE); + TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; } else if (tim->TIM == TIM11) + { RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM11,ENABLE); + TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; + } + else if (tim->TIM == TIM13) + { RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM13,ENABLE); + TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; + } + else if (tim->TIM == TIM14) + { RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,ENABLE); + TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; + } else return -1; @@ -92,7 +105,6 @@ int8_t TimInit(TIM_OBJ *tim, uint16_t psc, uint32_t per) else TIM_InternalClockConfig(tim->TIM); - TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; TIM_TimeBaseInitStructure.TIM_Period=per; TIM_TimeBaseInitStructure.TIM_Prescaler=psc; From 0d58029f71ccefc299864aa2a7c09fe9a8362ced Mon Sep 17 00:00:00 2001 From: 1923777848 <1923777848@qq.com> Date: Tue, 12 Aug 2025 14:34:18 +0800 Subject: [PATCH 06/11] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=B7=B3=E8=BD=AC?= =?UTF-8?q?=E6=97=B6=E5=A4=9A=E6=AE=B5=E6=B3=A2=E5=BD=A2=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TrainCamp_zhangcheng_PLSR/app/src/plsr.c | 28 ++++++++++-------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/TrainCamp_zhangcheng_PLSR/app/src/plsr.c b/TrainCamp_zhangcheng_PLSR/app/src/plsr.c index ad8409c..52a36c4 100644 --- a/TrainCamp_zhangcheng_PLSR/app/src/plsr.c +++ b/TrainCamp_zhangcheng_PLSR/app/src/plsr.c @@ -161,11 +161,11 @@ void PlsrModuleTask(void *pArg) continue; } - if (plsr.segment[currentSegment].pulseFreq <= 5000) - pulseFreq = 3360 - 1; - else if ((plsr.segment[currentSegment].pulseFreq > 5000) + if (plsr.segment[currentSegment].pulseFreq <= 1000) + pulseFreq = 2625 - 1; + else if ((plsr.segment[currentSegment].pulseFreq > 1000) && (plsr.segment[currentSegment].pulseFreq <= 100000)) - pulseFreq = 2 - 1; + pulseFreq = 4 - 1; else continue; @@ -435,23 +435,19 @@ static void FirstSegmentProc(SEGMENT_PART *segmentPart) incAll += segmentPart->inc; if (plsr.segment[currentSegment].pulseFreq <= 5000) { - tim10.setPsc(&tim10, 3360 - 1); - if (currentSpeed != 0) - tim10.setPer(&tim10, 50000 / currentSpeed); - else - tim10.setPer(&tim10, 1000); - tim10.registerIrq(&tim10, TimCallBack, ¤tSeg.currentPart); - tim10.open(&tim10); - tim10.openIrq(&tim10); + tim10.setPsc(&tim10, 2625 - 1); } else { tim10.setPsc(&tim10, 168 - 1); - tim10.setPer(&tim10, 1000000 / currentSpeed); - tim10.registerIrq(&tim10, TimCallBack, ¤tSeg.currentPart); - tim10.open(&tim10); - tim10.openIrq(&tim10); } + if (currentSpeed != 0) + tim10.setPer(&tim10, 168000000 / (TIM10->PSC + 1) / currentSpeed); + else + tim10.setPer(&tim10, 1000); + tim10.registerIrq(&tim10, TimCallBack, ¤tSeg.currentPart); + tim10.open(&tim10); + tim10.openIrq(&tim10); } } From eede0ad12f0b5f3bcd5e75c34064ff1e5371c4f1 Mon Sep 17 00:00:00 2001 From: 1923777848 <1923777848@qq.com> Date: Wed, 13 Aug 2025 08:19:00 +0800 Subject: [PATCH 07/11] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E8=84=89=E5=86=B2?= =?UTF-8?q?=E8=BE=93=E5=87=BA=E8=AE=A1=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TrainCamp_zhangcheng_PLSR/app/src/plsr.c | 39 ++++++++++++++++-------- TrainCamp_zhangcheng_PLSR/bsp/src/time.c | 18 ++++++++--- 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/TrainCamp_zhangcheng_PLSR/app/src/plsr.c b/TrainCamp_zhangcheng_PLSR/app/src/plsr.c index 52a36c4..b29e131 100644 --- a/TrainCamp_zhangcheng_PLSR/app/src/plsr.c +++ b/TrainCamp_zhangcheng_PLSR/app/src/plsr.c @@ -109,7 +109,7 @@ SEGMENT_PART currentSeg = { .currentPart = 1 }; PLSR plsr = { - .segmentAllNum = 4, + .segmentAllNum = 3, .defaultSpeed = 1000, .defaultAccSpeedTime = 5, .defaultDecSpeedTime = 10, @@ -122,9 +122,9 @@ PLSR plsr = { .segment[2].pulseFreq = 6000, .segment[2].pulseNumber = 2000, .segment[2].jumpNumber = 0, - .segment[3].pulseFreq = 9000, - .segment[3].pulseNumber = 2000, - .segment[3].jumpNumber = 0, +// .segment[3].pulseFreq = 9000, +// .segment[3].pulseNumber = 2000, +// .segment[3].jumpNumber = 0, .startRunSegment = 0 }; @@ -139,11 +139,12 @@ void PlsrModuleTask(void *pArg) res = GetTimObj("tim2", &tim2); res = GetTimObj("tim10", &tim10); - + + tim2.init(&tim2, 0, 65535); + tim2.open(&tim2); + tim10.init(&tim10, 168 - 1, 65535); -// tim10.open(&tim10); tim10.registerIrq(&tim10, TimCallBack, ¤tSeg); -// tim10.openIrq(&tim10); tim10.pwmInit(&tim10); tim10.pwmSetPulse(&tim10, TIM10->ARR); @@ -227,8 +228,9 @@ void TimCallBack(void *pArg) { uint16_t reloadValue = 0; static int32_t pulseCount = 0; - + static int32_t allcount = 0; pulseCount++; + allcount++; if (currentSeg.currentPart == 1) { switch (currentSeg.currentState) @@ -245,7 +247,12 @@ void TimCallBack(void *pArg) } else currentSpeed += currentSeg.inc; - + + if (currentSpeed <= 1000) + tim10.setPsc(&tim10, 2625 - 1); + else + tim10.setPsc(&tim10, 3 - 1); + reloadValue = 168000000 / (TIM10->PSC + 1) / (currentSpeed); tim10.setPer(&tim10, reloadValue - 1); tim10.pwmSetPulse(&tim10, TIM10->ARR / 2 + 1); @@ -259,7 +266,7 @@ void TimCallBack(void *pArg) } else if (currentSeg.currentPart == 2) { - if (pulseCount > currentSeg.secondPartNum - 4) + if (pulseCount > currentSeg.secondPartNum - 1) { if ((currentSegment == (plsr.segmentAllNum -1)) && (plsr.segment[currentSegment].jumpNumber == 0)) @@ -282,7 +289,7 @@ void TimCallBack(void *pArg) else if (currentSeg.currentPart == 3) { if (((currentSpeed - currentSeg.dec) <= 0) - || (pulseCount > currentSeg.thirdPartNum)) + || (pulseCount > currentSeg.thirdPartNum - 1)) { pulseCount = 0; currentSeg.currentPart = 1; @@ -295,6 +302,12 @@ void TimCallBack(void *pArg) return; } currentSpeed -= currentSeg.dec; + + if (currentSpeed <= 1000) + tim10.setPsc(&tim10, 2625 - 1); + else + tim10.setPsc(&tim10, 3 - 1); + reloadValue = 168000000 / (TIM10->PSC + 1) / (currentSpeed); tim10.setPer(&tim10, reloadValue - 1); tim10.pwmSetPulse(&tim10, TIM10->ARR / 2 + 1); @@ -433,13 +446,13 @@ static void FirstSegmentProc(SEGMENT_PART *segmentPart) segmentPart->inc = segmentPart->inc - diffValue; } incAll += segmentPart->inc; - if (plsr.segment[currentSegment].pulseFreq <= 5000) + if (currentSpeed <= 1000) { tim10.setPsc(&tim10, 2625 - 1); } else { - tim10.setPsc(&tim10, 168 - 1); + tim10.setPsc(&tim10, 3 - 1); } if (currentSpeed != 0) tim10.setPer(&tim10, 168000000 / (TIM10->PSC + 1) / currentSpeed); diff --git a/TrainCamp_zhangcheng_PLSR/bsp/src/time.c b/TrainCamp_zhangcheng_PLSR/bsp/src/time.c index 17e8e1f..4df429b 100644 --- a/TrainCamp_zhangcheng_PLSR/bsp/src/time.c +++ b/TrainCamp_zhangcheng_PLSR/bsp/src/time.c @@ -70,7 +70,20 @@ int8_t TimInit(TIM_OBJ *tim, uint16_t psc, uint32_t per) if (tim->TIM == TIM2) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); + TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; + + GPIO_InitTypeDef GPIO_InitStructure; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_Init(GPIOA, &GPIO_InitStructure); + + GPIO_PinAFConfig(GPIOA, GPIO_PinSource15, GPIO_AF_TIM2); + + TIM_SelectInputTrigger(tim->TIM, TIM_TS_ETRF); + TIM_ETRClockMode2Config(tim->TIM, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_Inverted, 0); } else if (tim->TIM == TIM10) @@ -99,10 +112,7 @@ int8_t TimInit(TIM_OBJ *tim, uint16_t psc, uint32_t per) else return -1; - if (tim->TIM == TIM2) - //TIM_TIxExternalClockConfig(tim->TIM, TIM_TIxExternalCLK1Source_TI1, TIM_ICPolarity_Rising, 10); - TIM_InternalClockConfig(tim->TIM); - else + if (tim->TIM != TIM2) TIM_InternalClockConfig(tim->TIM); TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; From 16daa756eda2fec1b269d18394abbe5f41f38155 Mon Sep 17 00:00:00 2001 From: 1923777848 <1923777848@qq.com> Date: Wed, 13 Aug 2025 10:36:34 +0800 Subject: [PATCH 08/11] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=BE=93=E5=87=BA?= =?UTF-8?q?=E8=AE=A1=E6=95=B0=E8=AF=AF=E5=B7=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TrainCamp_zhangcheng_PLSR/app/src/plsr.c | 50 +++++++++++++++++------- TrainCamp_zhangcheng_PLSR/bsp/src/time.c | 6 ++- 2 files changed, 39 insertions(+), 17 deletions(-) diff --git a/TrainCamp_zhangcheng_PLSR/app/src/plsr.c b/TrainCamp_zhangcheng_PLSR/app/src/plsr.c index b29e131..a6748ad 100644 --- a/TrainCamp_zhangcheng_PLSR/app/src/plsr.c +++ b/TrainCamp_zhangcheng_PLSR/app/src/plsr.c @@ -33,6 +33,7 @@ static OS_STK PlsrModuleStack[PLSR_MODULE_STACK_SIZE]; static void PlsrModuleTask(void * pArg); static void TimCallBack(void *pArg); +static void Tim2CntCallBack(void *pArg); static void ReadRegisterParam(PLSR *plsr); static void configPulsePort(PLSR *plsr); static void ComputePartNum(PLSR *plsr, SEGMENT_PART *segmentPart); @@ -88,6 +89,8 @@ RESUIL PLSRInit(void) * @retval MODBUS_FALSE 失败 */ TIM_OBJ tim2; +int32_t tim2OverCnt = 0; +int32_t CumulativePulseCount = 0; TIM_OBJ tim10; int32_t accSpeedSlope = 0; int32_t decSpeedSlope = 0; @@ -109,7 +112,7 @@ SEGMENT_PART currentSeg = { .currentPart = 1 }; PLSR plsr = { - .segmentAllNum = 3, + .segmentAllNum = 4, .defaultSpeed = 1000, .defaultAccSpeedTime = 5, .defaultDecSpeedTime = 10, @@ -122,9 +125,9 @@ PLSR plsr = { .segment[2].pulseFreq = 6000, .segment[2].pulseNumber = 2000, .segment[2].jumpNumber = 0, -// .segment[3].pulseFreq = 9000, -// .segment[3].pulseNumber = 2000, -// .segment[3].jumpNumber = 0, + .segment[3].pulseFreq = 9000, + .segment[3].pulseNumber = 100000, + .segment[3].jumpNumber = 0, .startRunSegment = 0 }; @@ -140,8 +143,10 @@ void PlsrModuleTask(void *pArg) res = GetTimObj("tim2", &tim2); res = GetTimObj("tim10", &tim10); - tim2.init(&tim2, 0, 65535); + tim2.init(&tim2, 0, 50000 - 1); tim2.open(&tim2); + tim2.registerIrq(&tim2, Tim2CntCallBack, NULL); + tim2.openIrq(&tim2); tim10.init(&tim10, 168 - 1, 65535); tim10.registerIrq(&tim10, TimCallBack, ¤tSeg); @@ -162,6 +167,8 @@ void PlsrModuleTask(void *pArg) continue; } + CumulativePulseCount = tim2OverCnt * (TIM2->ARR + 1) + TIM2->CNT; + if (plsr.segment[currentSegment].pulseFreq <= 1000) pulseFreq = 2625 - 1; else if ((plsr.segment[currentSegment].pulseFreq > 1000) @@ -224,26 +231,28 @@ void PlsrModuleTask(void *pArg) //定时器9 内部输入时钟源ITx主从模式定时器10 //定时器12 内部输入时钟源ITx主从模式定时器13 -void TimCallBack(void *pArg) +static void Tim2CntCallBack(void *pArg) +{ + tim2OverCnt++; +} + +static void TimCallBack(void *pArg) { uint16_t reloadValue = 0; static int32_t pulseCount = 0; static int32_t allcount = 0; - pulseCount++; - allcount++; + if (currentSeg.currentPart == 1) { switch (currentSeg.currentState) { case 2: ///< 加速 { - if ((currentSpeed + currentSeg.inc) >= plsr.segment[currentSegment].pulseFreq - || (pulseCount > currentSeg.firstPartNum - 1)) + if ((currentSpeed + currentSeg.inc) >= plsr.segment[currentSegment].pulseFreq) { currentSpeed = plsr.segment[currentSegment].pulseFreq; currentSeg.currentPart = 2; - pulseCount = 0; } else currentSpeed += currentSeg.inc; @@ -255,7 +264,13 @@ void TimCallBack(void *pArg) reloadValue = 168000000 / (TIM10->PSC + 1) / (currentSpeed); tim10.setPer(&tim10, reloadValue - 1); - tim10.pwmSetPulse(&tim10, TIM10->ARR / 2 + 1); + tim10.pwmSetPulse(&tim10, TIM10->ARR / 2 + 1); + allcount++; + pulseCount++; + + if (pulseCount > currentSeg.firstPartNum - 1) + pulseCount = 0; + break; } default: @@ -285,20 +300,23 @@ void TimCallBack(void *pArg) else currentSegment = plsr.segment[currentSegment].jumpNumber; } + allcount++; + pulseCount++; } else if (currentSeg.currentPart == 3) { if (((currentSpeed - currentSeg.dec) <= 0) - || (pulseCount > currentSeg.thirdPartNum - 1)) + || (pulseCount > currentSeg.thirdPartNum - 2)) { + currentSpeed = 0; pulseCount = 0; currentSeg.currentPart = 1; tim10.setPer(&tim10, 100); tim10.pwmSetPulse(&tim10, 65535); tim10.closeIrq(&tim10); - - tim10.registerIrq(&tim10, TimCallBack, ¤tSeg.currentPart); + + allcount++; return; } currentSpeed -= currentSeg.dec; @@ -311,6 +329,8 @@ void TimCallBack(void *pArg) reloadValue = 168000000 / (TIM10->PSC + 1) / (currentSpeed); tim10.setPer(&tim10, reloadValue - 1); tim10.pwmSetPulse(&tim10, TIM10->ARR / 2 + 1); + allcount++; + pulseCount++; } } diff --git a/TrainCamp_zhangcheng_PLSR/bsp/src/time.c b/TrainCamp_zhangcheng_PLSR/bsp/src/time.c index 4df429b..db1ad86 100644 --- a/TrainCamp_zhangcheng_PLSR/bsp/src/time.c +++ b/TrainCamp_zhangcheng_PLSR/bsp/src/time.c @@ -83,7 +83,7 @@ int8_t TimInit(TIM_OBJ *tim, uint16_t psc, uint32_t per) GPIO_PinAFConfig(GPIOA, GPIO_PinSource15, GPIO_AF_TIM2); TIM_SelectInputTrigger(tim->TIM, TIM_TS_ETRF); - TIM_ETRClockMode2Config(tim->TIM, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_Inverted, 0); + TIM_ETRClockMode2Config(tim->TIM, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0); } else if (tim->TIM == TIM10) @@ -166,8 +166,10 @@ void TimDeInit(TIM_OBJ *tim) */ void TimSetPsc(TIM_OBJ *tim, uint16_t psc) { + TIM_ITConfig(tim->TIM, TIM_IT_Update, DISABLE); TIM_PrescalerConfig(tim->TIM, psc, TIM_PSCReloadMode_Immediate); TIM_ClearITPendingBit(tim->TIM, TIM_IT_Update); + TIM_ITConfig(tim->TIM, TIM_IT_Update, ENABLE); } @@ -361,7 +363,7 @@ void TIM2_IRQHandler(void) { if (TIM_GetITStatus(TIM2,TIM_IT_Update) == SET) { - if (ArgList[0] != NULL) + if (CallBackFuncList[0] != NULL) CallBackFuncList[0](ArgList[0]); TIM_ClearITPendingBit(TIM2, TIM_IT_Update); } From 9e3fa147822f7fa64c9fb9f1a4ff26b90ee3217a Mon Sep 17 00:00:00 2001 From: 1923777848 <1923777848@qq.com> Date: Wed, 13 Aug 2025 14:44:08 +0800 Subject: [PATCH 09/11] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=87=8F=E9=80=9F?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TrainCamp_zhangcheng_PLSR/app/inc/plsr.h | 5 +- TrainCamp_zhangcheng_PLSR/app/src/plsr.c | 169 ++++++++++++++++------- 2 files changed, 125 insertions(+), 49 deletions(-) diff --git a/TrainCamp_zhangcheng_PLSR/app/inc/plsr.h b/TrainCamp_zhangcheng_PLSR/app/inc/plsr.h index 5f86d60..b0d5a5a 100644 --- a/TrainCamp_zhangcheng_PLSR/app/inc/plsr.h +++ b/TrainCamp_zhangcheng_PLSR/app/inc/plsr.h @@ -157,8 +157,9 @@ typedef struct PLSR_OUTPUT_MODE outMode; ///< 输出模式 uint16_t dirDelayTime; ///< 方向延时时间 uint16_t segmentAllNum; ///< 总段数 - uint16_t startRunSegment; ///< 起始执行段数 - uint16_t currentSegment; ///< 当前执行段数 + uint16_t startRunSegment; ///< 起始执行段编号 + uint16_t previouSegment; ///< 上一段编号 + uint16_t currentSegment; ///< 当前执行段编号 uint32_t defaultSpeed; ///< 默认速度 uint16_t defaultAccSpeedTime; ///< 默认加速时间 uint16_t defaultDecSpeedTime; ///< 默认减速时间 diff --git a/TrainCamp_zhangcheng_PLSR/app/src/plsr.c b/TrainCamp_zhangcheng_PLSR/app/src/plsr.c index a6748ad..5c07b38 100644 --- a/TrainCamp_zhangcheng_PLSR/app/src/plsr.c +++ b/TrainCamp_zhangcheng_PLSR/app/src/plsr.c @@ -8,12 +8,16 @@ * @copyright Copyright (c) 2025 */ - #include "../../system/inc/system.h" #include "../../bsp/inc/time.h" #include "../inc/plsr.h" #include "../../bsp/inc/gpio.h" +/* 求x绝对值 */ +#define ABS(x) do { \ + if ((x) < 0) \ + ((x) = 0 - (x)); \ + } while(0) typedef struct { int32_t inc; @@ -119,14 +123,14 @@ PLSR plsr = { .segment[0].pulseFreq = 2000, .segment[0].pulseNumber = 1000, .segment[0].jumpNumber = 0, - .segment[1].pulseFreq = 3000, + .segment[1].pulseFreq = 1000, .segment[1].pulseNumber = 2000, .segment[1].jumpNumber = 0, .segment[2].pulseFreq = 6000, .segment[2].pulseNumber = 2000, .segment[2].jumpNumber = 0, - .segment[3].pulseFreq = 9000, - .segment[3].pulseNumber = 100000, + .segment[3].pulseFreq = 6000, + .segment[3].pulseNumber = 10000, .segment[3].jumpNumber = 0, .startRunSegment = 0 }; @@ -161,14 +165,9 @@ void PlsrModuleTask(void *pArg) while (1) { // ReadRegisterParam(&plsr); - - if (plsr.sendEnableState != 1) - { - continue; - } - CumulativePulseCount = tim2OverCnt * (TIM2->ARR + 1) + TIM2->CNT; - + plsr.monitorPulseNum = CumulativePulseCount; + if (plsr.segment[currentSegment].pulseFreq <= 1000) pulseFreq = 2625 - 1; else if ((plsr.segment[currentSegment].pulseFreq > 1000) @@ -177,18 +176,23 @@ void PlsrModuleTask(void *pArg) else continue; - /* 配置输入输出相关端子 */ - configPulsePort(&plsr); - if (plsr.outMode == ABSOLUTE_MODE) { - if (plsr.monitorPulseNum + if (plsr.monitorPulseNum >= plsr.segment[currentSegment].pulseNumber) { continue; } } + /* 配置输入输出相关端子 */ + if ((plsr.sendEnableState != 1) || (RunFlag == 1)) + { + continue; + } + + configPulsePort(&plsr); + if ((plsr.accDecSpeedMode == STRAIGHT_LINE_MODE) && (RunFlag == 0)) { RunFlag = 1; @@ -273,6 +277,33 @@ static void TimCallBack(void *pArg) break; } + case 3: ///< 减速 + { + if ((currentSpeed - currentSeg.dec) < plsr.segment[currentSegment].pulseFreq) + { + currentSpeed = plsr.segment[currentSegment].pulseFreq; + + currentSeg.currentPart = 2; + } + else + currentSpeed -= currentSeg.dec; + + if (currentSpeed <= 1000) + tim10.setPsc(&tim10, 2625 - 1); + else + tim10.setPsc(&tim10, 3 - 1); + + reloadValue = 168000000 / (TIM10->PSC + 1) / (currentSpeed); + tim10.setPer(&tim10, reloadValue - 1); + tim10.pwmSetPulse(&tim10, TIM10->ARR / 2 + 1); + allcount++; + pulseCount++; + + if (pulseCount > currentSeg.firstPartNum - 1) + pulseCount = 0; + + break; + } default: { break; @@ -369,6 +400,7 @@ static void ReadRegisterParam(PLSR *plsr) static void configPulsePort(PLSR *plsr) { + uint8_t pulseDir = 1; gpio_obj_t *outDirPort = NULL; outDirPort = get_gpio_obj("gpio_h"); @@ -376,12 +408,16 @@ static void configPulsePort(PLSR *plsr) if ((outDirPort == NULL) || (plsr == NULL)) return; + if (plsr->segment[currentSegment].pulseNumber >= 0) + pulseDir = 1; + else + pulseDir = 0; + switch (plsr->dirPort) { case OUTPUT_DIR_PORT_Y12: { outDirPort->gpio_init(outDirPort, gpio_pin_9, "OUT_PP", "UP"); - outDirPort->gpio_set_output(outDirPort, gpio_pin_9, 1); break; } case OUTPUT_DIR_PORT_Y13: @@ -399,20 +435,35 @@ static void configPulsePort(PLSR *plsr) outDirPort->gpio_init(outDirPort, gpio_pin_6, "OUT_PP", "UP"); break; } + default: + { + break; + } } - // switch (plsr->outputPort) - // { - // case OUTPUT_PORT_Y0: - // { - // outDirPort->gpio_init(outDirPort, gpio_pin) - // } - // } + outDirPort->gpio_set_output(outDirPort, outDirPort->gpio_pin, + plsr->dirLogic ^ pulseDir); + if (currentSegment == plsr->startRunSegment) + return; + + if (((plsr->segment[currentSegment].pulseNumber >= 0) + && (plsr->segment[plsr->previouSegment].pulseNumber >= 0))) + return; + + if ((plsr->segment[currentSegment].pulseNumber < 0) + && (plsr->segment[plsr->previouSegment].pulseNumber < 0)) + return; + +// tim10.pwmSetPulse(&tim10, 65535); + OSTimeDly(plsr->dirDelayTime); } static void ComputePartNum(PLSR *plsr, SEGMENT_PART *segmentPart) { uint32_t target = plsr->segment[currentSegment].pulseFreq; + uint32_t targetPulseCount = plsr->segment[currentSegment].pulseNumber; + ABS(targetPulseCount); + accSpeedSlope = plsr->defaultSpeed / plsr->defaultAccSpeedTime; decSpeedSlope = plsr->defaultSpeed / plsr->defaultDecSpeedTime; @@ -438,7 +489,11 @@ static void ComputePartNum(PLSR *plsr, SEGMENT_PART *segmentPart) decTime = (currentSpeed - target) / decSpeedSlope; segmentPart->firstPartNum = (target + currentSpeed) / 2 * decTime / 1000; } - segmentPart->secondPartNum = plsr->segment[currentSegment].pulseNumber + else + { + segmentPart->firstPartNum = 0; + } + segmentPart->secondPartNum = targetPulseCount - segmentPart->firstPartNum - segmentPart->thirdPartNum; } @@ -449,10 +504,23 @@ static void FirstSegmentProc(SEGMENT_PART *segmentPart) int32_t targetFreq = 0; int32_t slope = 0; int32_t diffValue = 0; - static int32_t incAll = 0; + if (currentSpeed == plsr.segment[currentSegment].pulseFreq) + segmentPart->currentState = 1; + else if ((currentSpeed < plsr.segment[currentSegment].pulseFreq)) + segmentPart->currentState = 2; + else + segmentPart->currentState = 3; + switch (segmentPart->currentState) { + /* 匀速处理 */ + case 1 : + { + segmentPart->currentPart = 2; + break; + } + /* 加速处理 */ case 2 : { targetFreq = plsr.segment[currentSegment].pulseFreq; @@ -460,30 +528,37 @@ static void FirstSegmentProc(SEGMENT_PART *segmentPart) segmentPart->inc = ((targetFreq - currentSpeed) / slope) * ((targetFreq + currentSpeed) / 2) / 1000; segmentPart->inc = (targetFreq - currentSpeed) / segmentPart->inc; - if ((currentSpeed + segmentPart->inc) >= plsr.segment[currentSegment].pulseFreq) - { - diffValue = currentSpeed + segmentPart->inc - plsr.segment[currentSegment].pulseFreq; - segmentPart->inc = segmentPart->inc - diffValue; - } - incAll += segmentPart->inc; - if (currentSpeed <= 1000) - { - tim10.setPsc(&tim10, 2625 - 1); - } - else - { - tim10.setPsc(&tim10, 3 - 1); - } - if (currentSpeed != 0) - tim10.setPer(&tim10, 168000000 / (TIM10->PSC + 1) / currentSpeed); - else - tim10.setPer(&tim10, 1000); - tim10.registerIrq(&tim10, TimCallBack, ¤tSeg.currentPart); - tim10.open(&tim10); - tim10.openIrq(&tim10); - + + break; + } + /* 减速处理 */ + case 3 : + { + targetFreq = plsr.segment[currentSegment].pulseFreq; + slope = plsr.defaultSpeed / plsr.defaultDecSpeedTime; + segmentPart->dec = ((currentSpeed - targetFreq) / slope) + * ((currentSpeed + targetFreq) / 2) / 1000; + segmentPart->dec = (currentSpeed - targetFreq) / segmentPart->dec; + + break; } } + + if (currentSpeed <= 1000) + { + tim10.setPsc(&tim10, 2625 - 1); + } + else + { + tim10.setPsc(&tim10, 3 - 1); + } + if (currentSpeed != 0) + tim10.setPer(&tim10, 168000000 / (TIM10->PSC + 1) / currentSpeed); + else + tim10.setPer(&tim10, 1000); + tim10.registerIrq(&tim10, TimCallBack, ¤tSeg.currentPart); + tim10.open(&tim10); + tim10.openIrq(&tim10); } From 17b02e2aed75b6288b3dc8e31dc3a6587feb06a0 Mon Sep 17 00:00:00 2001 From: 1923777848 <1923777848@qq.com> Date: Wed, 13 Aug 2025 15:38:01 +0800 Subject: [PATCH 10/11] =?UTF-8?q?=E8=BF=87=E7=A8=8B=E6=80=A7=E4=BF=9D?= =?UTF-8?q?=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TrainCamp_zhangcheng_PLSR/app/src/plsr.c | 106 ++++++++--------------- 1 file changed, 36 insertions(+), 70 deletions(-) diff --git a/TrainCamp_zhangcheng_PLSR/app/src/plsr.c b/TrainCamp_zhangcheng_PLSR/app/src/plsr.c index 5c07b38..48a5fec 100644 --- a/TrainCamp_zhangcheng_PLSR/app/src/plsr.c +++ b/TrainCamp_zhangcheng_PLSR/app/src/plsr.c @@ -41,10 +41,7 @@ static void Tim2CntCallBack(void *pArg); static void ReadRegisterParam(PLSR *plsr); static void configPulsePort(PLSR *plsr); static void ComputePartNum(PLSR *plsr, SEGMENT_PART *segmentPart); -static void FirstSegmentProc(SEGMENT_PART *segmentPart); -static void SecondSegmentProc(SEGMENT_PART *segmentPart); -static void ThirdSegmentProc(SEGMENT_PART *segmentPart); - +static void StartPulseOutput(void); /** * @brief PLSR功能初始化 @@ -105,6 +102,7 @@ int32_t decPulse = 0; int32_t uniformTime = 0; int32_t uniformPulse = 0; uint8_t currentSegment = 0; +uint8_t currentSegmentID = 0; uint32_t currentSpeed = 0; uint8_t RunFlag = 0; @@ -122,17 +120,17 @@ PLSR plsr = { .defaultDecSpeedTime = 10, .segment[0].pulseFreq = 2000, .segment[0].pulseNumber = 1000, - .segment[0].jumpNumber = 0, + .segment[0].jumpNumber = 3, .segment[1].pulseFreq = 1000, .segment[1].pulseNumber = 2000, - .segment[1].jumpNumber = 0, + .segment[1].jumpNumber = 4, .segment[2].pulseFreq = 6000, .segment[2].pulseNumber = 2000, - .segment[2].jumpNumber = 0, + .segment[2].jumpNumber = 2, .segment[3].pulseFreq = 6000, .segment[3].pulseNumber = 10000, .segment[3].jumpNumber = 0, - .startRunSegment = 0 + .startRunSegment = 1 }; void PlsrModuleTask(void *pArg) @@ -160,7 +158,8 @@ void PlsrModuleTask(void *pArg) plsr.sendEnableState = 1; plsr.accDecSpeedMode = STRAIGHT_LINE_MODE; - currentSegment = plsr.startRunSegment; + currentSegmentID = plsr.startRunSegment; + currentSegment = currentSegmentID - 1; while (1) { @@ -196,27 +195,9 @@ void PlsrModuleTask(void *pArg) if ((plsr.accDecSpeedMode == STRAIGHT_LINE_MODE) && (RunFlag == 0)) { RunFlag = 1; - + ComputePartNum(&plsr, ¤tSeg); - - switch (currentSeg.currentPart) - { - case 1: - { - FirstSegmentProc(¤tSeg); - break; - } - case 2: - { - SecondSegmentProc(¤tSeg); - break; - } - case 3: - { - ThirdSegmentProc(¤tSeg); - break; - } - } + StartPulseOutput(); } } } @@ -314,7 +295,7 @@ static void TimCallBack(void *pArg) { if (pulseCount > currentSeg.secondPartNum - 1) { - if ((currentSegment == (plsr.segmentAllNum -1)) + if ((currentSegmentID == (plsr.segmentAllNum)) && (plsr.segment[currentSegment].jumpNumber == 0)) { currentSeg.currentPart = 3; @@ -326,10 +307,13 @@ static void TimCallBack(void *pArg) currentSeg.currentPart = 1; pulseCount = 0; RunFlag = 0; + if (plsr.segment[currentSegment].jumpNumber == 0) currentSegment++; else - currentSegment = plsr.segment[currentSegment].jumpNumber; + currentSegment = plsr.segment[currentSegment].jumpNumber - 1; + + currentSegmentID = currentSegment + 1; } allcount++; pulseCount++; @@ -460,34 +444,35 @@ static void configPulsePort(PLSR *plsr) static void ComputePartNum(PLSR *plsr, SEGMENT_PART *segmentPart) { - uint32_t target = plsr->segment[currentSegment].pulseFreq; + uint32_t targetFreq = plsr->segment[currentSegment].pulseFreq; uint32_t targetPulseCount = plsr->segment[currentSegment].pulseNumber; ABS(targetPulseCount); accSpeedSlope = plsr->defaultSpeed / plsr->defaultAccSpeedTime; decSpeedSlope = plsr->defaultSpeed / plsr->defaultDecSpeedTime; + /* 计算每段脉冲三个部分脉冲数量 */ /* 最后一段 */ - if ((currentSegment == (plsr->segmentAllNum -1)) + if ((currentSegmentID == (plsr->segmentAllNum)) && (plsr->segment[currentSegment].jumpNumber == 0)) { - decTime = target / decSpeedSlope; - segmentPart->thirdPartNum = target / 2 * decTime / 1000; + decTime = targetFreq / decSpeedSlope; + segmentPart->thirdPartNum = targetFreq / 2 * decTime / 1000; } else { segmentPart->thirdPartNum = 0; } - if (currentSpeed < target) + if (currentSpeed < targetFreq) { - accTime = (target - currentSpeed) / accSpeedSlope; - segmentPart->firstPartNum = (target + currentSpeed) / 2 * accTime / 1000; + accTime = (targetFreq - currentSpeed) / accSpeedSlope; + segmentPart->firstPartNum = (targetFreq + currentSpeed) / 2 * accTime / 1000; } - else if (currentSpeed > target) + else if (currentSpeed > targetFreq) { - decTime = (currentSpeed - target) / decSpeedSlope; - segmentPart->firstPartNum = (target + currentSpeed) / 2 * decTime / 1000; + decTime = (currentSpeed - targetFreq) / decSpeedSlope; + segmentPart->firstPartNum = (targetFreq + currentSpeed) / 2 * decTime / 1000; } else { @@ -496,22 +481,15 @@ static void ComputePartNum(PLSR *plsr, SEGMENT_PART *segmentPart) segmentPart->secondPartNum = targetPulseCount - segmentPart->firstPartNum - segmentPart->thirdPartNum; -} - -static void FirstSegmentProc(SEGMENT_PART *segmentPart) -{ - int32_t targetFreq = 0; - int32_t slope = 0; - int32_t diffValue = 0; - - if (currentSpeed == plsr.segment[currentSegment].pulseFreq) + if (currentSpeed == plsr->segment[currentSegment].pulseFreq) segmentPart->currentState = 1; - else if ((currentSpeed < plsr.segment[currentSegment].pulseFreq)) + else if ((currentSpeed < plsr->segment[currentSegment].pulseFreq)) segmentPart->currentState = 2; else segmentPart->currentState = 3; - + + /* 计算每个脉冲的频率增量 */ switch (segmentPart->currentState) { /* 匀速处理 */ @@ -523,9 +501,7 @@ static void FirstSegmentProc(SEGMENT_PART *segmentPart) /* 加速处理 */ case 2 : { - targetFreq = plsr.segment[currentSegment].pulseFreq; - slope = plsr.defaultSpeed / plsr.defaultAccSpeedTime; - segmentPart->inc = ((targetFreq - currentSpeed) / slope) + segmentPart->inc = ((targetFreq - currentSpeed) / accSpeedSlope) * ((targetFreq + currentSpeed) / 2) / 1000; segmentPart->inc = (targetFreq - currentSpeed) / segmentPart->inc; @@ -534,16 +510,18 @@ static void FirstSegmentProc(SEGMENT_PART *segmentPart) /* 减速处理 */ case 3 : { - targetFreq = plsr.segment[currentSegment].pulseFreq; - slope = plsr.defaultSpeed / plsr.defaultDecSpeedTime; - segmentPart->dec = ((currentSpeed - targetFreq) / slope) + segmentPart->dec = ((currentSpeed - targetFreq) / decSpeedSlope) * ((currentSpeed + targetFreq) / 2) / 1000; segmentPart->dec = (currentSpeed - targetFreq) / segmentPart->dec; break; } } +} + +static void StartPulseOutput(void) +{ if (currentSpeed <= 1000) { tim10.setPsc(&tim10, 2625 - 1); @@ -560,15 +538,3 @@ static void FirstSegmentProc(SEGMENT_PART *segmentPart) tim10.open(&tim10); tim10.openIrq(&tim10); } - - -static void SecondSegmentProc(SEGMENT_PART *segmentPart) -{ - -} - - -static void ThirdSegmentProc(SEGMENT_PART *segmentPart) -{ - -} \ No newline at end of file From 85b6075f9b4480f1f92f4cb9566fc369677c9ae8 Mon Sep 17 00:00:00 2001 From: 1923777848 <1923777848@qq.com> Date: Thu, 14 Aug 2025 10:45:03 +0800 Subject: [PATCH 11/11] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=BB=9D=E5=AF=B9?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TrainCamp_zhangcheng_PLSR/app/src/plsr.c | 171 +++++++++++++++++------ 1 file changed, 126 insertions(+), 45 deletions(-) diff --git a/TrainCamp_zhangcheng_PLSR/app/src/plsr.c b/TrainCamp_zhangcheng_PLSR/app/src/plsr.c index 48a5fec..74fd0bb 100644 --- a/TrainCamp_zhangcheng_PLSR/app/src/plsr.c +++ b/TrainCamp_zhangcheng_PLSR/app/src/plsr.c @@ -12,6 +12,33 @@ #include "../../bsp/inc/time.h" #include "../inc/plsr.h" #include "../../bsp/inc/gpio.h" +#include "../../system/inc/usart.h" + +/* 速度波形发送任务使能 */ +#define SPEED_SEND_TASK 0 + +#if (SPEED_SEND_TASK) +#define SPEED_SEND_MODULE_PRIO 20 +#define SPEED_SEND_MODULE_STACK_SIZE 200 +static OS_STK SpeedSendModuleStack[SPEED_SEND_MODULE_STACK_SIZE]; +static void SpeedSendModuleTask(void * pArg); +void UsartSend(uint32_t data) +{ + extern usart_obj_t *usart1; + uint8_t buff[4]; + buff[0] = (uint8_t)((data) >> 24); + buff[1] = (uint8_t)((data) >> 16); + buff[2] = (uint8_t)((data) >> 8); + buff[3] = (uint8_t)((data)); + for (uint8_t i = 0; i < 4; i++) + { + USART_SendData(USART1, buff[i]);//发送一个字节 + while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) != SET); + } +} +#define USART_SEND_SPEED(x) UsartSend(x) +#endif + /* 求x绝对值 */ #define ABS(x) do { \ @@ -42,6 +69,7 @@ static void ReadRegisterParam(PLSR *plsr); static void configPulsePort(PLSR *plsr); static void ComputePartNum(PLSR *plsr, SEGMENT_PART *segmentPart); static void StartPulseOutput(void); +static void StopPulseOutput(void); /** * @brief PLSR功能初始化 @@ -73,6 +101,21 @@ RESUIL PLSRInit(void) return MODBUS_FALSE; } +#if (SPEED_SEND_TASK) + err = OSTaskCreate( + SpeedSendModuleTask, + NULL, + &SpeedSendModuleStack[SPEED_SEND_MODULE_STACK_SIZE - 1], + SPEED_SEND_MODULE_PRIO); + + if(err != OS_ERR_NONE) + { + MODBUS_LOG("SpeedSendModule init fail\r\n"); + OS_EXIT_CRITICAL(); + return MODBUS_FALSE; + } +#endif + OS_EXIT_CRITICAL(); return MODBUS_TURE; @@ -120,30 +163,28 @@ PLSR plsr = { .defaultDecSpeedTime = 10, .segment[0].pulseFreq = 2000, .segment[0].pulseNumber = 1000, - .segment[0].jumpNumber = 3, + .segment[0].jumpNumber = 0, .segment[1].pulseFreq = 1000, .segment[1].pulseNumber = 2000, - .segment[1].jumpNumber = 4, + .segment[1].jumpNumber = 0, .segment[2].pulseFreq = 6000, - .segment[2].pulseNumber = 2000, - .segment[2].jumpNumber = 2, + .segment[2].pulseNumber = 3000, + .segment[2].jumpNumber = 0, .segment[3].pulseFreq = 6000, - .segment[3].pulseNumber = 10000, + .segment[3].pulseNumber = 100000, .segment[3].jumpNumber = 0, - .startRunSegment = 1 + .startRunSegment = 1, + .outMode = ABSOLUTE_MODE, + .accDecSpeedMode = STRAIGHT_LINE_MODE, + .sendEnableState = 1 }; -void PlsrModuleTask(void *pArg) +static void PlsrModuleTask(void *pArg) { - int8_t res; - uint8_t pArgment = 0; + //ReadRegisterParam(&plsr); - uint8_t nextSegment = plsr.startRunSegment; - -// ReadRegisterParam(&plsr); - - res = GetTimObj("tim2", &tim2); - res = GetTimObj("tim10", &tim10); + GetTimObj("tim2", &tim2); + GetTimObj("tim10", &tim10); tim2.init(&tim2, 0, 50000 - 1); tim2.open(&tim2); @@ -155,16 +196,15 @@ void PlsrModuleTask(void *pArg) tim10.pwmInit(&tim10); tim10.pwmSetPulse(&tim10, TIM10->ARR); - plsr.sendEnableState = 1; - plsr.accDecSpeedMode = STRAIGHT_LINE_MODE; - currentSegmentID = plsr.startRunSegment; currentSegment = currentSegmentID - 1; + int tmpTIMARR = 0; while (1) { // ReadRegisterParam(&plsr); - CumulativePulseCount = tim2OverCnt * (TIM2->ARR + 1) + TIM2->CNT; + tmpTIMARR = TIM2->ARR + 1; + CumulativePulseCount = tim2OverCnt * tmpTIMARR + TIM2->CNT; plsr.monitorPulseNum = CumulativePulseCount; if (plsr.segment[currentSegment].pulseFreq <= 1000) @@ -175,33 +215,45 @@ void PlsrModuleTask(void *pArg) else continue; + /* 配置输入输出相关端子 */ + if ((plsr.sendEnableState != 1) || (RunFlag == 1)) + { + continue; + } + if (plsr.outMode == ABSOLUTE_MODE) { if (plsr.monitorPulseNum - >= plsr.segment[currentSegment].pulseNumber) + == plsr.segment[currentSegment].pulseNumber) { + plsr.sendEnableState = 0; + StopPulseOutput(); continue; } } - /* 配置输入输出相关端子 */ - if ((plsr.sendEnableState != 1) || (RunFlag == 1)) - { - continue; - } - - configPulsePort(&plsr); - if ((plsr.accDecSpeedMode == STRAIGHT_LINE_MODE) && (RunFlag == 0)) { RunFlag = 1; + configPulsePort(&plsr); ComputePartNum(&plsr, ¤tSeg); StartPulseOutput(); } } } +static void SpeedSendModuleTask(void * pArg) +{ + while(1) + { +#if (SPEED_SEND_TASK) + if (plsr.sendEnableState == 1) + USART_SEND_SPEED(currentSpeed); +#endif + } + +} //1HZ //psc 1680 一次10us //per 50000 @@ -254,8 +306,11 @@ static void TimCallBack(void *pArg) pulseCount++; if (pulseCount > currentSeg.firstPartNum - 1) + { pulseCount = 0; - +// currentSeg.currentPart = 2; + } + break; } case 3: ///< 减速 @@ -281,8 +336,11 @@ static void TimCallBack(void *pArg) pulseCount++; if (pulseCount > currentSeg.firstPartNum - 1) + { pulseCount = 0; - +// currentSeg.currentPart = 2; + } + break; } default: @@ -326,12 +384,11 @@ static void TimCallBack(void *pArg) currentSpeed = 0; pulseCount = 0; currentSeg.currentPart = 1; - - tim10.setPer(&tim10, 100); - tim10.pwmSetPulse(&tim10, 65535); - tim10.closeIrq(&tim10); - + + StopPulseOutput(); + allcount++; + plsr.sendEnableState = 0; return; } currentSpeed -= currentSeg.dec; @@ -352,15 +409,15 @@ static void TimCallBack(void *pArg) static void ReadRegisterParam(PLSR *plsr) { - int16_t *pDataRegister = (uint16_t *)(DATA_REGISTER_ADRR + 0x1000); + int16_t *pDataRegister = (int16_t *)(DATA_REGISTER_ADRR + 0x1000); - plsr->outputPort = pDataRegister[0]; - plsr->dirPort = pDataRegister[1]; - plsr->extPort = pDataRegister[2]; + plsr->outputPort = (PLSR_OUTPUT_PORT)pDataRegister[0]; + plsr->dirPort = (PLSR_OUTPUT_DIR_PORT)pDataRegister[1]; + plsr->extPort = (PLSR_INPUT_EXT_PORT)pDataRegister[2]; plsr->dirDelayTime = pDataRegister[3]; - plsr->dirLogic = pDataRegister[4]; - plsr->accDecSpeedMode = pDataRegister[5]; - plsr->outMode = pDataRegister[6]; + plsr->dirLogic = (PLSR_OUTPUT_DIR_PORT_LOGIC)pDataRegister[4]; + plsr->accDecSpeedMode = (PLSR_ACC_DEC_SPEED_MODE)pDataRegister[5]; + plsr->outMode = (PLSR_OUTPUT_MODE)pDataRegister[6]; plsr->segmentAllNum = pDataRegister[7]; plsr->startRunSegment = pDataRegister[8]; plsr->defaultSpeed = *((uint32_t *)pDataRegister[9]); @@ -444,10 +501,14 @@ static void configPulsePort(PLSR *plsr) static void ComputePartNum(PLSR *plsr, SEGMENT_PART *segmentPart) { - uint32_t targetFreq = plsr->segment[currentSegment].pulseFreq; - uint32_t targetPulseCount = plsr->segment[currentSegment].pulseNumber; + int32_t targetFreq = plsr->segment[currentSegment].pulseFreq; + int32_t targetPulseCount = plsr->segment[currentSegment].pulseNumber; + + if (plsr->outMode == ABSOLUTE_MODE) + targetPulseCount -= plsr->monitorPulseNum; + ABS(targetPulseCount); - + accSpeedSlope = plsr->defaultSpeed / plsr->defaultAccSpeedTime; decSpeedSlope = plsr->defaultSpeed / plsr->defaultDecSpeedTime; @@ -458,6 +519,11 @@ static void ComputePartNum(PLSR *plsr, SEGMENT_PART *segmentPart) { decTime = targetFreq / decSpeedSlope; segmentPart->thirdPartNum = targetFreq / 2 * decTime / 1000; + + if (segmentPart->thirdPartNum > targetPulseCount) + { + segmentPart->thirdPartNum = targetPulseCount; + } } else { @@ -478,6 +544,11 @@ static void ComputePartNum(PLSR *plsr, SEGMENT_PART *segmentPart) { segmentPart->firstPartNum = 0; } + + if ((segmentPart->firstPartNum + segmentPart->thirdPartNum) + >= (targetPulseCount )) + segmentPart->firstPartNum = targetPulseCount - segmentPart->thirdPartNum; + segmentPart->secondPartNum = targetPulseCount - segmentPart->firstPartNum - segmentPart->thirdPartNum; @@ -538,3 +609,13 @@ static void StartPulseOutput(void) tim10.open(&tim10); tim10.openIrq(&tim10); } + + +static void StopPulseOutput(void) +{ + currentSpeed = 0; + tim10.setPer(&tim10, 10); + tim10.pwmSetPulse(&tim10, 65535); + tim10.close(&tim10); + tim10.openIrq(&tim10); +}