From 4c9243090347d6d278a7f8c5dd4571b7a1ec9ba4 Mon Sep 17 00:00:00 2001 From: hanyongwei <2043702190@qq.com> Date: Wed, 19 Aug 2026 12:35:39 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0PWM=E8=BE=93=E5=87=BA?= =?UTF-8?q?=E5=BC=95=E8=84=9A=EF=BC=8C=E5=85=81=E8=AE=B8=E5=88=87=E6=8D=A2?= =?UTF-8?q?Y0-Y2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hanyongwei <2043702190@qq.com> --- app/main.c | 2 +- drivers/Source/gpio.c | 2 +- plsr/param/plsr_param.h | 2 +- plsr/pulse_driver/plsr_pulse_driver.c | 89 +++++++++++++++++++++------ plsr/pulse_driver/plsr_pulse_driver.h | 8 +-- 5 files changed, 77 insertions(+), 26 deletions(-) diff --git a/app/main.c b/app/main.c index 8d02df2..c90f71f 100644 --- a/app/main.c +++ b/app/main.c @@ -4,7 +4,7 @@ * @brief 初始化系统时钟配置、初始化GPIO、初始化串口、启动任务 * * @note Modbus / PLSR / 参数块管理 / 指令接口 - * @note PLSR: Y0(PF6)=TIM10 脉冲,Y3(PF9)=方向 + * @note PLSR: Y0(PF6)=TIM10 / Y1(PF8)=TIM13 / Y2(PF7)=TIM11 脉冲,Y3(PF9)=方向 * ****************************************************************************** */ diff --git a/drivers/Source/gpio.c b/drivers/Source/gpio.c index 13b0a05..2e8cdab 100644 --- a/drivers/Source/gpio.c +++ b/drivers/Source/gpio.c @@ -2,7 +2,7 @@ /** ****************************************************************************** * @file gpio.c - * @brief GPIO 时钟与基础初始化(Y0/Y1 由 PLSR 硬件层配置) + * @brief GPIO 时钟与基础初始化(Y0/Y1/Y2 由 PLSR 脉冲驱动配置) ****************************************************************************** */ /* USER CODE END Header */ diff --git a/plsr/param/plsr_param.h b/plsr/param/plsr_param.h index 753eab6..512bde3 100644 --- a/plsr/param/plsr_param.h +++ b/plsr/param/plsr_param.h @@ -90,7 +90,7 @@ typedef enum { /** 公共运行参数(运动侧只读此映像,不直接啃寄存器) */ typedef struct { - uint16_t pulse_y; /* 0=Y0/TIM10 1=Y1/TIM11 2=Y2/TIM13 */ + uint16_t pulse_y; /* 0=Y0/PF6/TIM10 1=Y1/PF8/TIM13 2=Y2/PF7/TIM11 */ uint16_t dir_y; /* 固定 3=Y3,不可选 */ uint16_t wait_x_sel; uint16_t ext_x_sel; diff --git a/plsr/pulse_driver/plsr_pulse_driver.c b/plsr/pulse_driver/plsr_pulse_driver.c index 73007e2..e0ef627 100644 --- a/plsr/pulse_driver/plsr_pulse_driver.c +++ b/plsr/pulse_driver/plsr_pulse_driver.c @@ -1,7 +1,7 @@ /** * @file plsr_pulse_driver.c - * @brief 脉冲输出:Y0/TIM10、Y1/TIM11、Y2/TIM13;方向固定 Y3 - * @note TIMxCLK=168MHz;段内锁 PSC 只改 ARR;改频在周期边界生效 + * @brief 脉冲输出:Y0/PF6/TIM10、Y1/PF8/TIM13、Y2/PF7/TIM11;方向固定 Y3 + * @note TIM10/11=168MHz,TIM13=84MHz;段内锁 PSC 只改 ARR;改频在周期边界生效 */ #include "plsr_pulse_driver.h" #include "plsr_param.h" @@ -11,14 +11,15 @@ TIM_HandleTypeDef htim10; TIM_HandleTypeDef htim11; TIM_HandleTypeDef htim13; -#define PLSR_TIM_CLK_HZ 168000000UL +#define PLSR_TIM_CLK_APB2_HZ 168000000UL /* TIM10 / TIM11 */ +#define PLSR_TIM_CLK_APB1_HZ 84000000UL /* TIM13 */ #define PLSR_Y0_PORT GPIOF -#define PLSR_Y0_PIN GPIO_PIN_6 +#define PLSR_Y0_PIN GPIO_PIN_6 /* TIM10 */ #define PLSR_Y1_PORT GPIOF -#define PLSR_Y1_PIN GPIO_PIN_8 +#define PLSR_Y1_PIN GPIO_PIN_8 /* TIM13:端子编号与 TIM 交叉 */ #define PLSR_Y2_PORT GPIOF -#define PLSR_Y2_PIN GPIO_PIN_7 +#define PLSR_Y2_PIN GPIO_PIN_7 /* TIM11 */ #define PLSR_Y3_PORT GPIOF #define PLSR_Y3_PIN GPIO_PIN_9 @@ -36,13 +37,14 @@ static volatile uint8_t s_req_pending; static TIM_HandleTypeDef *PlsrPulseDriverHtimByY(uint16_t pulse_y) { + /* Y1=PF8→TIM13,Y2=PF7→TIM11,与端子编号交叉 */ if (pulse_y == 1U) { - return &htim11; + return &htim13; } if (pulse_y == 2U) { - return &htim13; + return &htim11; } return &htim10; } @@ -59,6 +61,17 @@ static uint8_t PlsrPulseDriverSelectY(void) return (uint8_t)y; } +/** TIM10/11:APB2 定时器 168MHz;TIM13:APB1 定时器 84MHz */ +static uint32_t PlsrPulseDriverTimClkHz(const TIM_HandleTypeDef *htim) +{ + if ((htim != (const TIM_HandleTypeDef *)0) && + (htim->Instance == TIM13)) + { + return PLSR_TIM_CLK_APB1_HZ; + } + return PLSR_TIM_CLK_APB2_HZ; +} + static void PlsrPulseDriverDirGpioInit(void) { GPIO_InitTypeDef gpio = {0}; @@ -130,6 +143,26 @@ void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim) HAL_NVIC_SetPriority(TIM1_UP_TIM10_IRQn, 5, 0); HAL_NVIC_EnableIRQ(TIM1_UP_TIM10_IRQn); } + else if (htim->Instance == TIM11) + { + /* TIM11_CH1 = PF7 = Y2 */ + __HAL_RCC_TIM11_CLK_ENABLE(); + gpio.Pin = PLSR_Y2_PIN; + gpio.Alternate = GPIO_AF3_TIM11; + HAL_GPIO_Init(PLSR_Y2_PORT, &gpio); + HAL_NVIC_SetPriority(TIM1_TRG_COM_TIM11_IRQn, 5, 0); + HAL_NVIC_EnableIRQ(TIM1_TRG_COM_TIM11_IRQn); + } + else if (htim->Instance == TIM13) + { + /* TIM13_CH1 = PF8 = Y1 */ + __HAL_RCC_TIM13_CLK_ENABLE(); + gpio.Pin = PLSR_Y1_PIN; + gpio.Alternate = GPIO_AF9_TIM13; + HAL_GPIO_Init(PLSR_Y1_PORT, &gpio); + HAL_NVIC_SetPriority(TIM8_UP_TIM13_IRQn, 5, 0); + HAL_NVIC_EnableIRQ(TIM8_UP_TIM13_IRQn); + } } static void PlsrPulseDriverTimInitOne(TIM_HandleTypeDef *htim, TIM_TypeDef *inst) @@ -177,7 +210,10 @@ void PlsrPulseDriverInit(void) s_active_y = 0U; s_active_htim = &htim10; PlsrPulseDriverDirGpioInit(); + /* 三路都 Init + 空闲拉高,计数器关闭;出脉冲时只 Start 选中那路 */ PlsrPulseDriverTimInitOne(&htim10, TIM10); + PlsrPulseDriverTimInitOne(&htim11, TIM11); + PlsrPulseDriverTimInitOne(&htim13, TIM13); } void PlsrPulseDriverSetDir(uint8_t forward) @@ -207,13 +243,17 @@ uint8_t PlsrPulseDriverIsPulseTim(TIM_TypeDef *instance) return ((instance == TIM10) || (instance == TIM11) || (instance == TIM13)) ? 1U : 0U; } -static void PlsrPulseDriverCalcArrWithPsc(uint32_t freq_hz, uint32_t psc, +static void PlsrPulseDriverCalcArrWithPsc(uint32_t clk_hz, uint32_t freq_hz, uint32_t psc, uint32_t *arr, uint32_t *ccr) { uint32_t ticks; uint32_t a; uint32_t c; + if (clk_hz < 1U) + { + clk_hz = PLSR_TIM_CLK_APB2_HZ; + } if (freq_hz < 1U) { freq_hz = 1U; @@ -223,7 +263,7 @@ static void PlsrPulseDriverCalcArrWithPsc(uint32_t freq_hz, uint32_t psc, freq_hz = 100000U; } - ticks = PLSR_TIM_CLK_HZ / freq_hz; + ticks = clk_hz / freq_hz; if (ticks < 2UL) { ticks = 2UL; @@ -250,11 +290,16 @@ static void PlsrPulseDriverCalcArrWithPsc(uint32_t freq_hz, uint32_t psc, *ccr = c; } -static void PlsrPulseDriverCalcPscArr(uint32_t freq_hz, uint32_t *psc, uint32_t *arr, uint32_t *ccr) +static void PlsrPulseDriverCalcPscArr(uint32_t clk_hz, uint32_t freq_hz, + uint32_t *psc, uint32_t *arr, uint32_t *ccr) { uint32_t ticks; uint32_t p; + if (clk_hz < 1U) + { + clk_hz = PLSR_TIM_CLK_APB2_HZ; + } if (freq_hz < 1U) { freq_hz = 1U; @@ -264,7 +309,7 @@ static void PlsrPulseDriverCalcPscArr(uint32_t freq_hz, uint32_t *psc, uint32_t freq_hz = 100000U; } - ticks = PLSR_TIM_CLK_HZ / freq_hz; + ticks = clk_hz / freq_hz; if (ticks < 2UL) { ticks = 2UL; @@ -282,7 +327,7 @@ static void PlsrPulseDriverCalcPscArr(uint32_t freq_hz, uint32_t *psc, uint32_t } *psc = p; - PlsrPulseDriverCalcArrWithPsc(freq_hz, p, arr, ccr); + PlsrPulseDriverCalcArrWithPsc(clk_hz, freq_hz, p, arr, ccr); } void PlsrPulseDriverLockPscRange(uint32_t f_min_hz, uint32_t f_max_hz) @@ -292,6 +337,8 @@ void PlsrPulseDriverLockPscRange(uint32_t f_min_hz, uint32_t f_max_hz) uint32_t psc_div_lo; uint32_t psc_div_hi; uint32_t div; + uint32_t clk_hz = PlsrPulseDriverTimClkHz( + PlsrPulseDriverHtimByY(PlsrPulseDriverSelectY())); if (f_min_hz < 1U) { @@ -308,8 +355,8 @@ void PlsrPulseDriverLockPscRange(uint32_t f_min_hz, uint32_t f_max_hz) f_max_hz = t; } - ticks_lo = PLSR_TIM_CLK_HZ / f_min_hz; - ticks_hi = PLSR_TIM_CLK_HZ / f_max_hz; + ticks_lo = clk_hz / f_min_hz; + ticks_hi = clk_hz / f_max_hz; if (ticks_lo < 2UL) { ticks_lo = 2UL; @@ -365,6 +412,7 @@ static void PlsrPulseDriverStartCommon(uint32_t freq_hz, uint8_t enable_update_i uint32_t ccr; uint8_t y = PlsrPulseDriverSelectY(); TIM_HandleTypeDef *htim = PlsrPulseDriverHtimByY(y); + uint32_t clk_hz; s_req_pending = 0U; @@ -374,6 +422,7 @@ static void PlsrPulseDriverStartCommon(uint32_t freq_hz, uint8_t enable_update_i } s_active_y = y; s_active_htim = htim; + clk_hz = PlsrPulseDriverTimClkHz(htim); if (freq_hz == 0U) { @@ -387,11 +436,11 @@ static void PlsrPulseDriverStartCommon(uint32_t freq_hz, uint8_t enable_update_i if (s_psc_locked != 0U) { psc = s_locked_psc; - PlsrPulseDriverCalcArrWithPsc(freq_hz, psc, &arr, &ccr); + PlsrPulseDriverCalcArrWithPsc(clk_hz, freq_hz, psc, &arr, &ccr); } else { - PlsrPulseDriverCalcPscArr(freq_hz, &psc, &arr, &ccr); + PlsrPulseDriverCalcPscArr(clk_hz, freq_hz, &psc, &arr, &ccr); } s_last_freq = freq_hz; @@ -436,6 +485,7 @@ void PlsrPulseDriverSetFreq(uint32_t freq_hz) uint32_t psc; uint32_t arr; uint32_t ccr; + uint32_t clk_hz; TIM_HandleTypeDef *htim; if (freq_hz == s_last_freq) @@ -446,6 +496,7 @@ void PlsrPulseDriverSetFreq(uint32_t freq_hz) htim = (s_active_htim != (TIM_HandleTypeDef *)0) ? s_active_htim : PlsrPulseDriverHtimByY(PlsrPulseDriverSelectY()); s_active_htim = htim; + clk_hz = PlsrPulseDriverTimClkHz(htim); if (freq_hz == 0U) { @@ -459,11 +510,11 @@ void PlsrPulseDriverSetFreq(uint32_t freq_hz) if (s_psc_locked != 0U) { psc = s_locked_psc; - PlsrPulseDriverCalcArrWithPsc(freq_hz, psc, &arr, &ccr); + PlsrPulseDriverCalcArrWithPsc(clk_hz, freq_hz, psc, &arr, &ccr); } else { - PlsrPulseDriverCalcPscArr(freq_hz, &psc, &arr, &ccr); + PlsrPulseDriverCalcPscArr(clk_hz, freq_hz, &psc, &arr, &ccr); } if ((psc == s_last_psc) && (arr == s_last_arr)) diff --git a/plsr/pulse_driver/plsr_pulse_driver.h b/plsr/pulse_driver/plsr_pulse_driver.h index a5970f0..b8b6805 100644 --- a/plsr/pulse_driver/plsr_pulse_driver.h +++ b/plsr/pulse_driver/plsr_pulse_driver.h @@ -2,10 +2,10 @@ * @file plsr_pulse_driver.h * @brief 脉冲输出驱动(方案书 5.1):TIM 脉冲 + 方向 GPIO * - * 脉冲端子(由参数 pulse_y 选择): - * Y0 → PF6 / TIM10_CH1 - * Y1 → PF8 / TIM11_CH1 - * Y2 → PF7 / TIM13_CH1 + * 脉冲端子(由参数 pulse_y 选择;端子编号与 TIM 编号交叉): + * Y0 → PF6 / TIM10_CH1 AF3 (APB2 Timer 168MHz) + * Y1 → PF8 / TIM13_CH1 AF9 (APB1 Timer 84MHz) + * Y2 → PF7 / TIM11_CH1 AF3 (APB2 Timer 168MHz) * 方向固定 Y3 → PF9 GPIO(不可选) * * 频率 0:停止该路 PWM;>0 时按 Hz 输出。