STM32单片机输出频率及占空比可调的PWM波

19 篇文章 2 订阅
8 篇文章 0 订阅

一、测试用环境

STM32F103C8T6,HAL库。
只考虑PWM的频率和占空比两个参数,死区、极性、对齐方式等不做讨论。

二、STM32Cube MX配置

1.PWM原理

在这里插入图片描述
上图中,定时器向上计数,当CNT<CCRx时,输出0,当CNT>CCRx时输出1,当CNT达到ARR值的时候,重新归零,再次向上计数,如此循环。改变CCRx的值,就可以改变PWM输出的占空比,改变ARR的值,就可以改变PWM输出的的频率。计算频率和占空比的公式如下:

f p w m = f_{pwm}= fpwm= f T I M ( P S C + 1 ) ∗ ( A R R + 1 ) f_{TIM} \over (PSC+1)*(ARR+1) (PSC+1)(ARR+1)fTIM

D u t y C y c l e DutyCycle DutyCycle = C C R A R R CCR\over ARR ARRCCR *100%
由以上两公式可知,时钟频率确定后,频率与分频系数PSC和自动重装载值ARR都有关系,占空比是CCR和ARR的比值;

2.CubeMX配置

以通用定时器TIM3的通道1为例,时钟为72MHz,主要配置如下图,因为频率和占空比我们需要可改变,在程序运行过程中需要修改参数,所以在CubeMX里,这些参数可以不配置;为了方便,我们配置PSC为72-1,这样当ARR从0~65535变化时,可以得到约15Hz-1MHz的频率,如果想要其他频率,则可以修改PSC的值。
在这里插入图片描述

三、主要代码

生成代码以后,在stm32f1xx_hal_tim.h头文件中,有开启或停止PWM的函数:

HAL_StatusTypeDef HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel)
HAL_StatusTypeDef HAL_TIM_PWM_Stop(TIM_HandleTypeDef *htim, uint32_t Channel)

因为我们使用的是TIM3、通道1,因此可通过如下代码开启PWM功能:

HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);

同样,停止PWM功能代码如下:

HAL_TIM_PWM_Stop(&htim3,TIM_CHANNEL_1);

接下来,需要写一个修改PWM频率及占空比的函数,在stm32f1xx_hal_tim.h头文件中

#define __HAL_TIM_SET_AUTORELOAD(__HANDLE__, __AUTORELOAD__) \
  do{                                                    \
    (__HANDLE__)->Instance->ARR = (__AUTORELOAD__);  \
    (__HANDLE__)->Init.Period = (__AUTORELOAD__);    \
  } while(0)

用来设置ARR的的值,而__HAL_TIM_SET_AUTORELOAD在stm32_hal_legacy.h中又有如下宏定义:

#define __HAL_TIM_SetAutoreload         __HAL_TIM_SET_AUTORELOAD

同样,设置CCR的功能定义如下:

#define __HAL_TIM_SetCompare            __HAL_TIM_SET_COMPARE

利用这两个宏我们可以写出配置频率和占空比的函数:

/*******************************************************************************
  * 函数名:PWM_Config
  * 功  能:PWM配置,设置频率和占空比
  * 参  数:Freq频率,Hz
            Duty占空比,*100
  * 返回值:无
  * 说  明:TIM3,Channel1;
            时钟72MHz,PSC=72-1,f=72M/((PSC+1)*(ARR+1)),PSC不变;
            Duty=ccr/arr*100%; 取值0~100,所以计算ccr要除以100         
*******************************************************************************/
void PWM_Config(uint32_t Freq, uint8_t Duty)
{
    uint32_t arr = 1000000 / Freq - 1;
    uint32_t ccr = (uint32_t)Duty * arr / 100;
    __HAL_TIM_SetAutoreload(&htim3, arr);
    __HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_1, ccr);    
}

四、试验验证

频率1KHz、占空比70%

PWM_Config(1000, 70);

在这里插入图片描述
从逻辑分析仪捕捉的波形图可看出,一个完整周期时间为1ms,即频率为1KHz,其中高电平为700us,即占空比为70%;
将配置改为2500Hz,占空比为35%,

PWM_Config(2500, 35);

在这里插入图片描述
上图可看出,周期为400us,即频率2500Hz,高电平宽度的140us,即占空比为35%;

五、总结

1.使用定时器的PWM输出模式,同一个定时器的不同通道输出的PWM频率必须相同,如果想要同时输出不同频率的PWM,则需要使用不同的定时器,或者使用同一个定时器的输出比较模式。
2.PWM模式下,同一个定时器的不同通道,输出的PWM占空比可以不一样。

  • 17
    点赞
  • 81
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
要在32单片机输出65%占空比PWM,需要按照以下步骤进行: 1. 配置定时器:选择一个合适的定时器,并根据需要设置计数值和分频系数。 2. 配置IO口:将需要输出PWM的IO口配置为输出模式。 3. 计算周期和占空比:根据所需的占空比和定时器的计数值来计算PWM的周期和占空比。例如,如果定时器的计数值为10000,需要输出65%占空比PWM,则周期为10000,占空比为6500。 4. 编写程序:根据以上计算结果编写程序,实现输出指定占空比PWM。 下面是一个简单的示例程序: ```c #include <stm32f10x.h> int main(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; TIM_OCInitTypeDef TIM_OCInitStructure; GPIO_InitTypeDef GPIO_InitStructure; // 使能定时器时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // 使能GPIO时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 配置GPIO口为复用输出模式 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // 配置定时器 TIM_TimeBaseInitStructure.TIM_Period = 10000; // 周期为10000 TIM_TimeBaseInitStructure.TIM_Prescaler = 71; // 分频系数为72 TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure); // 配置PWM输出模式 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 6500; // 占空比为65% TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC2Init(TIM2, &TIM_OCInitStructure); // 启动定时器 TIM_Cmd(TIM2, ENABLE); while (1) { } } ``` 在上述程序中,使用了定时器2和GPIOA0口来输出65%占空比PWM。需要注意的是,程序中的计数值和分频系数需要根据实际情况进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值