Procházet zdrojové kódy

板载指示灯共阳极,输出高电平指示灯熄灭,输出低电平指示灯点亮。为了让起始测到低电平,改为空闲输出高电平。

在空闲时强制高电平输出,解决段与段之间已经停表。HAL_TIM_PWM_Stop 会清 CC1E,比较通道关掉后,PF6 仍是 TIM 复用,但定时器不再推挽驱动,脚近似高阻。内部下拉只有几十 kΩ,挡不住飞线接地时那个很陡的沿。导线、地、探头之间的耦合电容会在 Y0 上顶出一根脉宽极短的针。所以它正好出现在接地的瞬间,而不是段内正常 PWM。

Signed-off-by: hanyongwei <2043702190@qq.com>
master
hanyongwei před 1 měsícem
rodič
revize
8e1dab0bf5
1 změnil soubory, kde provedl 48 přidání a 21 odebrání
  1. +48
    -21
      plsr/pulse_driver/plsr_pulse_driver.c

+ 48
- 21
plsr/pulse_driver/plsr_pulse_driver.c Zobrazit soubor

@@ -73,6 +73,44 @@ static void PlsrPulseDriverDirGpioInit(void)
HAL_GPIO_WritePin(PLSR_Y3_PORT, PLSR_Y3_PIN, GPIO_PIN_RESET); 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) void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim)
{ {
GPIO_InitTypeDef gpio = {0}; GPIO_InitTypeDef gpio = {0};
@@ -80,7 +118,7 @@ void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim)
__HAL_RCC_GPIOF_CLK_ENABLE(); __HAL_RCC_GPIOF_CLK_ENABLE();


gpio.Mode = GPIO_MODE_AF_PP; gpio.Mode = GPIO_MODE_AF_PP;
gpio.Pull = GPIO_PULLDOWN;
gpio.Pull = GPIO_PULLUP;
gpio.Speed = GPIO_SPEED_FREQ_HIGH; gpio.Speed = GPIO_SPEED_FREQ_HIGH;


if (htim->Instance == TIM10) if (htim->Instance == TIM10)
@@ -123,6 +161,8 @@ static void PlsrPulseDriverTimInitOne(TIM_HandleTypeDef *htim, TIM_TypeDef *inst
Error_Handler(); Error_Handler();
} }
htim->Instance->CCMR1 |= TIM_CCMR1_OC1PE; htim->Instance->CCMR1 |= TIM_CCMR1_OC1PE;
/* 复用保持:比较通道强制有效,推挽把脚拉高 */
PlsrPulseDriverOcHoldHigh(htim);
} }


void PlsrPulseDriverInit(void) void PlsrPulseDriverInit(void)
@@ -315,14 +355,7 @@ void PlsrPulseDriverUnlockPsc(void)


static void PlsrPulseDriverStopHtim(TIM_HandleTypeDef *htim) 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) 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); __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; htim->Instance->EGR = TIM_EGR_UG;
__HAL_TIM_CLEAR_FLAG(htim, TIM_FLAG_UPDATE); __HAL_TIM_CLEAR_FLAG(htim, TIM_FLAG_UPDATE);
__HAL_TIM_CLEAR_IT(htim, TIM_IT_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_FLAG(htim, TIM_FLAG_UPDATE);
__HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE); __HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE);




Načítá se…
Zrušit
Uložit