From 8e1dab0bf553ce5e43f0ee0e65c24d8762df59c3 Mon Sep 17 00:00:00 2001 From: hanyongwei <2043702190@qq.com> Date: Tue, 18 Aug 2026 11:16:38 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9D=BF=E8=BD=BD=E6=8C=87=E7=A4=BA=E7=81=AF?= =?UTF-8?q?=E5=85=B1=E9=98=B3=E6=9E=81=EF=BC=8C=E8=BE=93=E5=87=BA=E9=AB=98?= =?UTF-8?q?=E7=94=B5=E5=B9=B3=E6=8C=87=E7=A4=BA=E7=81=AF=E7=86=84=E7=81=AD?= =?UTF-8?q?=EF=BC=8C=E8=BE=93=E5=87=BA=E4=BD=8E=E7=94=B5=E5=B9=B3=E6=8C=87?= =?UTF-8?q?=E7=A4=BA=E7=81=AF=E7=82=B9=E4=BA=AE=E3=80=82=E4=B8=BA=E4=BA=86?= =?UTF-8?q?=E8=AE=A9=E8=B5=B7=E5=A7=8B=E6=B5=8B=E5=88=B0=E4=BD=8E=E7=94=B5?= =?UTF-8?q?=E5=B9=B3=EF=BC=8C=E6=94=B9=E4=B8=BA=E7=A9=BA=E9=97=B2=E8=BE=93?= =?UTF-8?q?=E5=87=BA=E9=AB=98=E7=94=B5=E5=B9=B3=E3=80=82=20=E5=9C=A8?= =?UTF-8?q?=E7=A9=BA=E9=97=B2=E6=97=B6=E5=BC=BA=E5=88=B6=E9=AB=98=E7=94=B5?= =?UTF-8?q?=E5=B9=B3=E8=BE=93=E5=87=BA=EF=BC=8C=E8=A7=A3=E5=86=B3=E6=AE=B5?= =?UTF-8?q?=E4=B8=8E=E6=AE=B5=E4=B9=8B=E9=97=B4=E5=B7=B2=E7=BB=8F=E5=81=9C?= =?UTF-8?q?=E8=A1=A8=E3=80=82HAL=5FTIM=5FPWM=5FStop=20=E4=BC=9A=E6=B8=85?= =?UTF-8?q?=20CC1E=EF=BC=8C=E6=AF=94=E8=BE=83=E9=80=9A=E9=81=93=E5=85=B3?= =?UTF-8?q?=E6=8E=89=E5=90=8E=EF=BC=8CPF6=20=E4=BB=8D=E6=98=AF=20TIM=20?= =?UTF-8?q?=E5=A4=8D=E7=94=A8=EF=BC=8C=E4=BD=86=E5=AE=9A=E6=97=B6=E5=99=A8?= =?UTF-8?q?=E4=B8=8D=E5=86=8D=E6=8E=A8=E6=8C=BD=E9=A9=B1=E5=8A=A8=EF=BC=8C?= =?UTF-8?q?=E8=84=9A=E8=BF=91=E4=BC=BC=E9=AB=98=E9=98=BB=E3=80=82=E5=86=85?= =?UTF-8?q?=E9=83=A8=E4=B8=8B=E6=8B=89=E5=8F=AA=E6=9C=89=E5=87=A0=E5=8D=81?= =?UTF-8?q?=20k=CE=A9=EF=BC=8C=E6=8C=A1=E4=B8=8D=E4=BD=8F=E9=A3=9E?= =?UTF-8?q?=E7=BA=BF=E6=8E=A5=E5=9C=B0=E6=97=B6=E9=82=A3=E4=B8=AA=E5=BE=88?= =?UTF-8?q?=E9=99=A1=E7=9A=84=E6=B2=BF=E3=80=82=E5=AF=BC=E7=BA=BF=E3=80=81?= =?UTF-8?q?=E5=9C=B0=E3=80=81=E6=8E=A2=E5=A4=B4=E4=B9=8B=E9=97=B4=E7=9A=84?= =?UTF-8?q?=E8=80=A6=E5=90=88=E7=94=B5=E5=AE=B9=E4=BC=9A=E5=9C=A8=20Y0=20?= =?UTF-8?q?=E4=B8=8A=E9=A1=B6=E5=87=BA=E4=B8=80=E6=A0=B9=E8=84=89=E5=AE=BD?= =?UTF-8?q?=E6=9E=81=E7=9F=AD=E7=9A=84=E9=92=88=E3=80=82=E6=89=80=E4=BB=A5?= =?UTF-8?q?=E5=AE=83=E6=AD=A3=E5=A5=BD=E5=87=BA=E7=8E=B0=E5=9C=A8=E6=8E=A5?= =?UTF-8?q?=E5=9C=B0=E7=9A=84=E7=9E=AC=E9=97=B4=EF=BC=8C=E8=80=8C=E4=B8=8D?= =?UTF-8?q?=E6=98=AF=E6=AE=B5=E5=86=85=E6=AD=A3=E5=B8=B8=20PWM=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hanyongwei <2043702190@qq.com> --- plsr/pulse_driver/plsr_pulse_driver.c | 69 +++++++++++++++++++-------- 1 file changed, 48 insertions(+), 21 deletions(-) diff --git a/plsr/pulse_driver/plsr_pulse_driver.c b/plsr/pulse_driver/plsr_pulse_driver.c index fa0bca3..73007e2 100644 --- a/plsr/pulse_driver/plsr_pulse_driver.c +++ b/plsr/pulse_driver/plsr_pulse_driver.c @@ -73,6 +73,44 @@ static void PlsrPulseDriverDirGpioInit(void) HAL_GPIO_WritePin(PLSR_Y3_PORT, PLSR_Y3_PIN, GPIO_PIN_RESET); } +/** + * 停表:不关复用、不关 CC1E。 + * HAL_TIM_PWM_Stop 会清 CC1E,脚变成 AF 高阻,飞线接地的沿会耦合出极短脉冲。 + * Forced active + 通道保持使能:TIM 推挽把脚主动拉高(段间空闲高)。 + */ +static void PlsrPulseDriverOcHoldHigh(TIM_HandleTypeDef *htim) +{ + uint32_t ccmr; + + if ((htim == (TIM_HandleTypeDef *)0) || (htim->Instance == (TIM_TypeDef *)0)) + { + return; + } + + __HAL_TIM_DISABLE_IT(htim, TIM_IT_UPDATE); + htim->Instance->CR1 &= (uint32_t)(~(TIM_CR1_CEN | TIM_CR1_OPM)); + + ccmr = htim->Instance->CCMR1; + ccmr &= (uint32_t)(~TIM_CCMR1_OC1M); + ccmr |= TIM_OCMODE_FORCED_ACTIVE; + htim->Instance->CCMR1 = ccmr; + htim->Instance->CCER |= TIM_CCER_CC1E; + + __HAL_TIM_CLEAR_FLAG(htim, TIM_FLAG_UPDATE); + __HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); +} + +static void PlsrPulseDriverOcPwm1(TIM_HandleTypeDef *htim) +{ + uint32_t ccmr; + + ccmr = htim->Instance->CCMR1; + ccmr &= (uint32_t)(~TIM_CCMR1_OC1M); + ccmr |= TIM_OCMODE_PWM1; + htim->Instance->CCMR1 = ccmr; +} + void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim) { GPIO_InitTypeDef gpio = {0}; @@ -80,7 +118,7 @@ void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim) __HAL_RCC_GPIOF_CLK_ENABLE(); gpio.Mode = GPIO_MODE_AF_PP; - gpio.Pull = GPIO_PULLDOWN; + gpio.Pull = GPIO_PULLUP; gpio.Speed = GPIO_SPEED_FREQ_HIGH; if (htim->Instance == TIM10) @@ -123,6 +161,8 @@ static void PlsrPulseDriverTimInitOne(TIM_HandleTypeDef *htim, TIM_TypeDef *inst Error_Handler(); } htim->Instance->CCMR1 |= TIM_CCMR1_OC1PE; + /* 复用保持:比较通道强制有效,推挽把脚拉高 */ + PlsrPulseDriverOcHoldHigh(htim); } void PlsrPulseDriverInit(void) @@ -315,14 +355,7 @@ void PlsrPulseDriverUnlockPsc(void) static void PlsrPulseDriverStopHtim(TIM_HandleTypeDef *htim) { - if (htim == (TIM_HandleTypeDef *)0) - { - return; - } - __HAL_TIM_DISABLE_IT(htim, TIM_IT_UPDATE); - (void)HAL_TIM_PWM_Stop(htim, TIM_CHANNEL_1); - __HAL_TIM_CLEAR_FLAG(htim, TIM_FLAG_UPDATE); - __HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE); + PlsrPulseDriverOcHoldHigh(htim); } static void PlsrPulseDriverStartCommon(uint32_t freq_hz, uint8_t enable_update_it) @@ -377,24 +410,18 @@ static void PlsrPulseDriverStartCommon(uint32_t freq_hz, uint8_t enable_update_i __HAL_TIM_SET_COUNTER(htim, 0U); /* - * UG 把新 PSC/ARR/CCR 从影寄存器载入现行寄存器。 - * 它会置 UIF → 若先开 IT 会进一次假 ISR(多计一拍)。 - * 顺序:UG → 清 UIF → Start PWM → 开 IT。 + * UG 在 Forced active 下做:脚保持高,避免 UG 在 PWM 复用脚上打出针。 + * 再切回 PWM1 并开计数。 */ + PlsrPulseDriverOcHoldHigh(htim); htim->Instance->EGR = TIM_EGR_UG; __HAL_TIM_CLEAR_FLAG(htim, TIM_FLAG_UPDATE); __HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE); - if (HAL_TIM_PWM_Start(htim, TIM_CHANNEL_1) != HAL_OK) - { - TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); - (void)HAL_TIM_PWM_Start(htim, TIM_CHANNEL_1); - } + PlsrPulseDriverOcPwm1(htim); + htim->Instance->CCER |= TIM_CCER_CC1E; + __HAL_TIM_ENABLE(htim); - /* - * 清一次 UIF(Start 可能再触发 UG/UIF),然后才开中断。 - * 确保第一个真脉冲完成后才进 ISR,不多计。 - */ __HAL_TIM_CLEAR_FLAG(htim, TIM_FLAG_UPDATE); __HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE);