【记录】PWM

概要

脉冲宽度调制(Pulse Width Modulation,PWM),可实现对脉冲宽度进行控制。

在MCU中,使用定时器实现的。TIM2,3,4,5,9~14都支持PWM输出。定时器框图的输出部分。

这里写图片描述

原理如下图所示,计数值从0到CCRx,输出低电平,计数值从CCRx到ARR,输出高电平。

这里写图片描述

时序图如下

这里写图片描述

操作步骤

  1. 使能定时器时钟,配置对应的输出引脚,复用功能
  2. 设置自动重载值
  3. 设置定时器的PWM模式(共两个)
  4. 使能定时器输出通道,使能定时器
  5. 设置CCR,调整占空比

实验要求

使用定时器14的PWM功能,输出占空比可变的PWM波,用来驱动LED灯,从而达到LED【PF9]亮度由暗变亮,又从亮变暗,如此循环。

void TIM14_PWM_Init(u32 arr, u32 psc)
{
    RCC->APB1ENR |= 1<<8;
    RCC->AHB1ENR |= 1<<5;
    GPIO_Set(GPIOF, PIN9, GPIO_MODE_AF, GPIO_OTYPE_PP, GPIO_SPEED_100M, GPIO_PUPD_PU);
    GPIO_AF_Set(GPIOF, 9, 9);

    TIM14->ARR = arr;
    TIM14->PSC = psc;
    TIM14->CCMR1 |= 6<<4;
    TIM14->CCMR1 |= 1<<3;
    TIM14->CCER |= 1<<0;
    TIM14->CCER |= 1<<1;
    TIM14->CR1 |= 1<<7;
    TIM14->CR1 |= 1<<0;
}
int main(void)
{
    u16 pwm_val = 0;
    u8 dir = 1;
    sys_init();

    while(1)
    {
        delay_ms(10);
        if(dir) pwm_val++;
        else pwm_val--;

        if(pwm_val>300) dir = 0;
        if(pwm_val==0) dir = 1;
        LED0_PWM_VAL = pwm_val;
    }
}

static void sys_init(void)
{
    Stm32_Clock_Init(336, 8, 2, 7);
    delay_init(168);
    TIM14_PWM_Init(500-1, 84-1);
}

参考

STM32F3与 F4 系列 Cortex M4 内核编程手册
STM32F4xxx中文参考手册
STM32F4xxx英文参考手册
STM32F4 开发指南(寄存器版)

hal库是一个功能强大的硬件抽象层,用于简化嵌入式系统的开发过程。它提供了许多功能来控制外设,例如PWM(脉冲宽度调制)输出。 要记录输出PWM数量,我们可以使用HAL库提供的TIM(定时器)功能。首先,我们需要初始化一个TIM实例,并设置其相关参数,例如频率和占空比。然后,将TIM连接到GPIO引脚,并使能TIM以开始定时器计数。 接下来,我们需要在代码中创建一个变量来保存PWM数量。在每次PWM输出完成后,我们可以通过检查TIM的状态寄存器来确定是否已经输出完整的PWM周期。如果输出完成,则将PWM数量增加1。 以下是一个使用HAL库记录输出PWM数量的示例代码: ```c #include "stm32f4xx_hal.h" TIM_HandleTypeDef htim1; // TIM1实例 uint32_t pwmCount = 0; // 记录PWM数量的变量 void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim) { if (htim->Instance == TIM1) { pwmCount++; } } int main(void) { HAL_Init(); // HAL库初始化 SystemClock_Config(); // 系统时钟配置(需要根据具体的MCU修改) // 初始化TIM1 htim1.Instance = TIM1; htim1.Init.Prescaler = 0; htim1.Init.CounterMode = TIM_COUNTERMODE_UP; htim1.Init.Period = 999; htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; HAL_TIM_PWM_Init(&htim1); // 使用GPIO引脚连接TIM1输出通道 GPIO_InitTypeDef GPIO_InitStruct; __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_8; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Alternate = GPIO_AF1_TIM1; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // 启动TIM1 HAL_TIM_PWM_Start_IT(&htim1, TIM_CHANNEL_1); while (1) { // 主循环代码 } } ``` 在上面的示例中,我们使用了HAL库的定时器驱动功能来输出PWM。在每次PWM输出完成后,回调函数`HAL_TIM_PWM_PulseFinishedCallback`将被调用。我们在该回调函数中检查TIM的实例是否为TIM1,并在符合条件时将PWM数量增加1。 通过这种方式,我们就可以使用HAL库记录输出的PWM数量了!当然,具体的实现方式可能因系列和型号的MCU而有所区别,但基本的思路是一样的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值