any012 发表于 2019-5-15 15:34:14

定时器能否用DMA方式控制任意GPIO输出PWM?

用定时器2的通道1的PWM功能,但不产生CH1的实际输出。而是在定时器2的更新回调函数和比较回调函数里分别置高/置低指定的GPIO引脚。
后来发现,有can接收中断时,输出的pwm波形有断续,造成外接的无源蜂鸣器响声断续。
想把定时器2的抢占中断优先级调到最高,但又担心影响can数据接收。

有没有办法通过DMA方式在任意GPIO引脚产生PWM波?

子曰好人 发表于 2019-5-15 16:38:03

定时器输出PWM不会被中断打断才对,看你的描述你这个算是模拟的PWM,不是硬件PWM,再检查一下配置

any012 发表于 2019-5-15 17:44:59

子曰好人 发表于 2019-5-15 16:38
定时器输出PWM不会被中断打断才对,看你的描述你这个算是模拟的PWM,不是硬件PWM,再检查一下配置 ...

如果把定时器的抢占优先级设成最高,那么can接收不会影响pwm输出。
但是,我想把can接收中断的优先级设成最高。

子曰好人 发表于 2019-5-15 18:36:28

不是优先级的问题,通常PWM设置之后不会通过中断的方式来拉高拉低引脚电平,这些动作都是硬件自动完成的,方便的话把代码贴出来看看

edmundlee 发表于 2019-5-15 18:54:22

可以的

any012 发表于 2019-5-16 08:33:32

定时器初始化部分:

void MX_TIM2_Init(void)
{
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};

htim2.Instance = TIM2;
htim2.Init.Prescaler = 79;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 500;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
{
    Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
{
    Error_Handler();
}
if (HAL_TIM_PWM_Init(&htim2) != HAL_OK)
{
    Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
{
    Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
    Error_Handler();
}

}
回调函数部分:
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    static uint32_t tim2_count;
    if (htim == &htim2)
    {
      tim2_count++;
      HAL_GPIO_WritePin(BEEP_PORT, BEEP, GPIO_PIN_RESET);
      htim2.Instance->CCR1 = plusValue;
      if (plusValue < (PWM_TIME_PERIOD*7/10))
                  plusValue++
...
}

void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
    if (htim == &htim2)
      HAL_GPIO_WritePin(BEEP_PORT, BEEP, GPIO_PIN_SET);
}



songshiqun2010 发表于 2019-6-4 09:48:42

any012 发表于 2019-5-16 08:33
定时器初始化部分:




可以看看 AN4655 AN4457
https://www.stmcu.org.cn/document/detail/index/id-216163
页: [1]
查看完整版本: 定时器能否用DMA方式控制任意GPIO输出PWM?