stm32使用一个定时器输出多路不同频率、占空比pwm

使用定时器的输出比较模式实现:当定时器计数值与比较寄存器值相等时,电平翻转

在这里插入图片描述在这里插入图片描述
使用定时器3的通道1,2进行实验
在这里插入图片描述
打开全局中断
在这里插入图片描述
在tim.c中加入上面代码,f1和f2用于修改通道频率,duty_cycle用于修改通道占空比。arr的自动装载值设置为最大65535,相当于计数器从0开始计数,直到65535才结束,分频系数为72,计算器计数一次为1us;对通道1:f1=100,即一个脉冲周期为100us,则频率为10khz
中断函数如下:

void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
{
  uint16_t OC_Count = 0;
  if(htim->Instance == TIM3)
  {
    if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
    {
		OC_Count=__HAL_TIM_GET_COMPARE(&htim3,TIM_CHANNEL_1);//获取定时器计数值
      if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_6))
      {
        __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,OC_Count +f1*duty_cycle1);
      }
      else
      {
        __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,OC_Count + f1*(1-duty_cycle1));
      }
    }
	
    else if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
    {
		OC_Count=__HAL_TIM_GET_COMPARE(&htim3,TIM_CHANNEL_2);
      if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_7))
      {
        __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_2,OC_Count + f2*duty_cycle2);
      }
      else
      {
        __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_2,OC_Count + f2*(1-duty_cycle2));
      }	 
    }       
  }
}

定时器一直都在计数,因此每次设置比较值时,都要用__HAL_TIM_GET_COMPARE获取计数值。对通道1:当其输出为低电平时,设置低电平翻转时间OC_Count +f1duty_cycle1;OC_Count为当前计数值,OC_Count +f1duty_cycle1为翻转时计数器的值,等待时间为f1duty_cycle1=50个计数值,即为50us。相同,当其输出为高电平时,设置高电平持续时间OC_Count + f1(1-duty_cycle1)。高低电平的总时间即为一个脉冲的周期duty_cycle1。
输出波形如下:
在这里插入图片描述
一个通道频率为10khz,另外一个通道为5khz,和预期相同

  • 0
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
GD32定时器可以用来输出PWM波形,通常的做法是设置定时器的计数值和预分频值,从而控制输出PWM的周期和占空比。以下是计算输出PWM频率的方法: 1. 计算定时器的时钟频率 假设定时器使用的是APB2总线时钟,可以通过如下代码计算出定时器时钟频率: ``` #include "gd32f1x0.h" // 定义APB2时钟频率 #define APB2_CLK_FREQ SystemCoreClock // 计算定时器时钟频率 uint32_t timer_clk_freq = APB2_CLK_FREQ; ``` 2. 计算预分频值 预分频值可以通过以下公式计算得到: ``` timer_prescaler = (timer_clk_freq / pwm_freq) / timer_period ``` 其中,pwm_freq是期望的PWM输出频率,timer_period是定时器的计数值。 例如,如果期望输出1000Hz的PWM波形,定时器计数值为100,那么预分频值可以计算得到: ``` timer_prescaler = (timer_clk_freq / 1000) / 100 = 72 ``` 3. 设置定时器的预分频值和计数值 根据上面计算得到的预分频值和计数值,可以设置定时器的寄存器,从而输出期望的PWM波形。以下是设置定时器的代码示例: ``` #include "gd32f1x0.h" // 定义APB2时钟频率 #define APB2_CLK_FREQ SystemCoreClock // 定义PWM输出频率和计数值 #define PWM_FREQ 1000 #define TIMER_PERIOD 100 int main(void) { // 计算定时器时钟频率 uint32_t timer_clk_freq = APB2_CLK_FREQ; // 计算预分频值 uint32_t timer_prescaler = (timer_clk_freq / PWM_FREQ) / TIMER_PERIOD; // 设置定时器的预分频值和计数值 TIMER_PSC(TIMER0) = timer_prescaler - 1; TIMER_CAR(TIMER0) = TIMER_PERIOD - 1; // 其他定时器设置,如PWM模式、输出极性等 // 启动定时器 TIMER_CTL(TIMER0) |= TIMER_CTL_CNTEN; while (1) { // 循环处理其他事情 } return 0; } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sense_long

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值