大家好,欢迎来到IT知识分享网。
本文主要介绍了什么是PWM,PWM的基本结构,PWM波的生成过程,如何用代码生成PWM波以及通过示波器观察生成的PWM波形。
前期准备:32芯片、示波器。
一、PWM的概念
1.引言
关于PWM,常听到的有“用示波器抓PWM波啊”“PWM的占空比”……这些都是啥,我很好奇,所以我去学习了PWM波,知道了什么是占空比、频率是什么、怎样用PWM实现呼吸灯、为啥提及PWM就会提到定时器……
2.PWM的概念
PWM:Pulse Width Modulation,脉冲宽度调制。如下图所示三种信号,皆为脉冲信号,脉冲是指电子技术中经常运用的一种像脉搏似的短暂起伏的电冲击(电压或电流)信号。PWM脉冲宽度调制是一种调制技术,用于控制输出(模拟)信号的平均值。如下图所示,在PWM中,信号由一系列固定周期的脉冲组成。脉冲的宽度表示信号的高电平时间,而周期表示脉冲的重复时间。通过改变脉冲的宽度与周期之间的比例,即占空比(占空比:高电平在一个脉冲周期之内所占的时间比),即改变高电平时间,可以模拟出不同的电压或功率级别,即控制信号的平均电压或功率。
3.PWM基本结构
要想通过单片机输出一个PWM波形需要两部分动作,如图上蓝框所示,一是时基单元,即TIM定时器,用于生成PWM信号,即计数和重装载,它只能发送PWM信号,并不能生成PWM波;二是输出比较单元GPIO端口,用于接收PWM信号,并通过GPIO口输出相应的高低电平信号,即PWM波。简单介绍一下大概过程:
1.首先选择可用于生成PWM的定时器,一般选择通用定时器,并配置好定时器的时钟频率CK_PSC。定时器的时钟频率来源有内部时钟模式、外部时钟模式2、外部时钟模式1和编码器模式,一般选择RCC内部时钟生成(其他用得较少,可自行CSDN),RCC内部时钟取决于定时器TIM挂载的总线的时钟频率,可通过时钟树查询(详情见嵌入式——时钟一文),一般为72MHz。
2.确定CK_PSC后,由PWM的频率计算公式,根据需要生成的PWM波的频率确定预分频值PSC和自动重装值ARR。预分频器PSC即对定时器的时钟频率进行分频,得到较小的所需的频率;自动重装器ARR即用于设置PWM波的周期,综合可得单个PWM波的频率/周期。
PWM的频率计算公式:Frequence=CK_PSC/(PSC+1)/(ARR+1)。
3.确定PSC和ARR后即确定了PWM波的周期,CNT为定时器自动计数值,它是自动增加的,当CNT增加到ARR即计数一个周期后会清零重新计数。同时,CNT会传递给输出比较单元与CCR进行比较确定输出高电平或低电平。
4.CCR捕获/比较器,CCR的值是自己确定的,它主要用于与计数值CNT作比较,当CNT<CCR时,输出高电平;当CNT≥CCR时,输出低电平(PWM模式1如此),此时即可得到PWM信号。所以,CCR是控制输出高电平值的参数,当CCR较大,则高电平占整个PWM周期的时间则较多,也就是占空比越大。故CCR决定了PWM波的占空比。
5.得到PWM信号后,由输出比较单元通道传递给GPIO端口,进而输出PWM波,用示波器即可看到生成的PWM波形。一个定时器有4个输出比较单元。
二、PWM实操
利用单片机生成PWM波的步骤如下:
- 定时器时钟源选择,RCC开启时钟(TIM外设、GPIO外设)。
- 配置GPIO(把定时器PWM通道对应的GPIO口初始化为复用推挽输出)。
- 配置时基单元(PSC和ARR的值)。
- 配置输出比较单元(CCR的值、输出比较模式、极性选择、输出使能)。
- 运行控制,启动计数器。
- 通过示波器连接GPIO口观察PWM波形(可选)。
以下代码均来自于国民N32G455芯片官方例程!不同芯片函数名可能会不同,但大抵是相似的。
1.选择定时器时钟源,开启TIM和GPIO的RCC时钟。
void RCC_Configuration(void) { /* TIM3 clock enable */ RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_TIM3, ENABLE); /* GPIOA and GPIOB clock enable */ RCC_EnableAPB2PeriphClk( RCC_APB2_PERIPH_GPIOA | RCC_APB2_PERIPH_GPIOB | RCC_APB2_PERIPH_GPIOC | RCC_APB2_PERIPH_AFIO, ENABLE); }
选择定时器3(TIM3)作为PWM波生成的时钟源,时钟频率为72MHz,开启TIM3和GPIO所挂载的总线的RCC时钟,TIM3挂载在APB1,GPIO挂载在APB2。
2.配置GPIO(把定时器PWM通道对应的GPIO口初始化为复用推挽输出)。
void GPIO_Configuration(void) { GPIO_InitType GPIO_InitStructure; /* GPIOA Configuration:TIM3 Channel1, 2, 3 and 4 as alternate function push-pull */ GPIO_InitStructure.Pin = GPIO_PIN_6 | GPIO_PIN_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.Pin = GPIO_PIN_0 | GPIO_PIN_1; GPIO_InitPeripheral(GPIOB, &GPIO_InitStructure); }
TIM3所对应的4路PWM输出通道为CH1(PA6)、CH2(PA7)、CH3(PB0)、CH4(PB1),这四个GPIO口均配置为复用推挽输出模式。
3.配置时基单元(PSC和ARR的值)
/* Compute the prescaler value */ PrescalerValue = (uint16_t)(SystemCoreClock / ) - 1; //5 /* Time base configuration */ TIM_TimeBaseStructure.Period = 665; //ARR TIM_TimeBaseStructure.Prescaler = PrescalerValue; //PSC TIM_TimeBaseStructure.ClkDiv = 0; TIM_TimeBaseStructure.CntMode = TIM_CNT_MODE_UP;//向上计数 TIM_InitTimeBase(TIM3, &TIM_TimeBaseStructure);
PrescalerValue预分频值即为PSC,Period周期即为ARR,定时器计数模式为向上计数。
4.配置输出比较单元(CCR的值、输出比较模式、极性选择、输出使能)
/* PWM1 Mode configuration: Channel1 */ TIM_OCInitStructure.OcMode = TIM_OCMODE_PWM1; TIM_OCInitStructure.OutputState = TIM_OUTPUT_STATE_ENABLE; TIM_OCInitStructure.Pulse = CCR1_Val; //CCR1 TIM_OCInitStructure.OcPolarity = TIM_OC_POLARITY_HIGH; TIM_InitOc1(TIM3, &TIM_OCInitStructure); TIM_ConfigOc1Preload(TIM3, TIM_OC_PRE_LOAD_ENABLE); /* PWM1 Mode configuration: Channel2 */ TIM_OCInitStructure.OutputState = TIM_OUTPUT_STATE_ENABLE; TIM_OCInitStructure.Pulse = CCR2_Val; //CCR2 TIM_InitOc2(TIM3, &TIM_OCInitStructure); TIM_ConfigOc2Preload(TIM3, TIM_OC_PRE_LOAD_ENABLE); /* PWM1 Mode configuration: Channel3 */ TIM_OCInitStructure.OutputState = TIM_OUTPUT_STATE_ENABLE; TIM_OCInitStructure.Pulse = CCR3_Val; //CCR3 TIM_InitOc3(TIM3, &TIM_OCInitStructure); TIM_ConfigOc3Preload(TIM3, TIM_OC_PRE_LOAD_ENABLE); /* PWM1 Mode configuration: Channel4 */ TIM_OCInitStructure.OutputState = TIM_OUTPUT_STATE_ENABLE; TIM_OCInitStructure.Pulse = CCR4_Val; //CCR4 TIM_InitOc4(TIM3, &TIM_OCInitStructure); TIM_ConfigOc4Preload(TIM3, TIM_OC_PRE_LOAD_ENABLE); TIM_ConfigArPreload(TIM3, ENABLE);
CCR1、CCR2、CCR3、CCR4为定时器四个PWM输出通道的占空比。
5.运行控制,启动计数器
void TIM_Enable(TIM_Module* TIMx, FunctionalState Cmd) { /* Check the parameters */ assert_param(IsTimAllModule(TIMx)); assert_param(IS_FUNCTIONAL_STATE(Cmd)); if (Cmd != DISABLE) { /* Enable the TIM Counter */ TIMx->CTRL1 |= TIM_CTRL1_CNTEN; } else { /* Disable the TIM Counter */ TIMx->CTRL1 &= (uint32_t)(~((uint32_t)TIM_CTRL1_CNTEN)); } }
-
通过示波器连接GPIO口观察PWM波形(可选)
由上图可知,
PWM波的频率为18.0184KHz。(Frequence=f=CK_PSC/(PSC+1)/(ARR+1)=72MHz/6/666=18.0180KHz)
PWM波的周期为55.50μs。(T=1/f=1/18018=55.5μs)
通道一(CH1)PWM波的占空比为50%。(333/665≈50%)
通道二(CH2)PWM波的占空比为37.38%。(249/665≈37.38%)
通道三(CH3)PWM波的占空比为24.91%。(166/665≈24.91%)
通道四(CH4)PWM波的占空比为12.44%。(83/665≈12.44%)
以上内容仅为个人学习分享,若有错误,敬请指正。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/130248.html