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] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=AE=9A=E6=97=B6=E5=99=A8?= =?UTF-8?q?=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