关于timer的pwm的使用

我们首先需要知道的是PWM的产生方式

通过STM32控制板,有两种方式能产生PWM,第一是利用普通IO口输出PWM,第二种是利用定时器的PWM的IO口或复用IO口

第一种为普通IO口产生PWM

普通IO口如何产生一个pwm?其实就是通过一个高低电平周期性的变化。这种思想很重要,确定频率就可以确定周期(T=1/f)也就是在一个周期内产生pwm的时间可以确定下来了。

如何改变占空比?确定了时间,高电平的时间不就是想要的占空比么,比如要产生一个频率1khz,占空比为70%的pwm,根据频率我们知道了pwm的周期为1ms,产生一个占空比为70%的不就是0.7ms的时间给高电平么,(我们用定时器中断的方式,使0.1ms产生一次更新中断,计数中断次数,中断处理函数前七次中断都给高电平就ok了。

我们用的是第二种

设置输出时是按输出通道分的库函数。即需要初始化哪个通道,就调用哪个函数。不同的通道对应的GPIO口也是不一样的。

也就是说,使用这个PWM波形,是用来等效地实现一个模拟信号的输出。
比如我们以一个很快的频率给电机进行通电、断电,那么电机的速度就能维持在一个速度中。
LED在熄灭时,由于余晖和人眼视觉暂留现象,LED不会应马熄灭。而是有定的惯性,过一小段时间才会熄灭。电机也是。当电机断电时。电机的转动不会立马停止。这就是惯性的系统

分析捕获/比较通道的输出部分

在这里插入图片描述
在这个图的左边输入的数据就是CNT和CRR1,他们进行比较,当满足CNT>CRR1CNT=CRR1时,进入输出模式控制器。
输出模式控制器改变它输出OC1ref(reference参考信号)的高低电平。
接着这个ref信号往后转递。
首先他可以转递到上部分的主模式控制器中。可以把这个ref映射到主模式的TRGO输出上去。
主要是进行下面这一路。
这一个模块是一个极性选择电路。如果给CC1P写0,信号往上走,电平信号不反转。来啥样走啥样。如果给CC1P写1,信号进入下面一路,通过非门取反,电平信号反转。
这就是进行极性选择,就是选择要不要反转高低电平。
然后进入使能电路,决定要不要输出。
然后进入OC1引脚,就是TIMx_CH1通道的引脚,通过对引脚定义的查询可以知道具体是对应哪个GPIO口。

然后来细看一下输出比较模式控制器,这个是这个电路中非常重要的部分。
在这里插入图片描述
在这个模块里面可以选择多种模式来更加灵活地控制ref的输出,通过下面的寄存器进行配置。
在这里插入图片描述
第一个模式是冻结模式,即CNT=CCR时维持原状态。假如你正在输出PWM波形,想暂停,可以设置成这个模式。切换为冻结模式后,输出暂停。并且高低电平维持暂停时的状态保持不变。

接下来的2,3,4模式,配时置有效电平,配时置无效电平,匹配时电平翻转。这个有效电平和无效电平。一般是高级定时器里面的一个说法,可以暂且理解为,置有效电平就是置高电平。置无效电平就是置低电平。第四个模式匹配时电平翻转可以方便得输出一个频率可调且占空比始终为50%的波形。

第五、六个模式强制为无效电平和强制为有效电平。这两个模式和冻结模式相似。如果你想暂停波形输出,并且在暂停期间保持低电平或者高电平,就可以设置成这两个强制输出模式。

最后的两个模式也是最有用的模式,他们可以用于输出频率和占空比都可调的PWM波形。PWM模式1和PWM模式2只有ref置有效电平和无效电平换了一下。PWM模式2实际上就是PWM1模式输出的取反。

 此部分转自基于STM32呼吸灯(PWM)_叫什么呀的博客-CSDN博客_stm32呼吸灯

PA1/USART2_RTS/
ADC_IN1/TIM2_CH2

所以我们要把pa1开复用,复用为TIM2_CH2,TIM2_CH2为捕获,比较的通道

    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //Ñ¡ÔñPWMģʽ2

与TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;搭配使用,设置有效电平为高电平并在周期内进行分配

TIM_OCInitStructure.TIM_Pulse=500;//设置占空比时间

如果后续需要更改占空比则需要配置

TIM_PrescalerConfig与TIM_OC3PreloadConfig区别

TIM_OC3PreloadConfig:使能预加载寄存器PWM占空比不一样,IO口电压就不一样,灯的亮度就不一样,配置CCR寄存器预装功能。
这个预装功能。就是影子寄存器,
就是你写入的值不会立即生效。而是在更新事件才会生效

具体原理为,通过改变单位时间内脉冲的个数可以实现调频;通过改变占空比可以实现调压。占空比越大,所得到的平均电压也就越大,幅值也就越大;占空比越小,所得到的平均电压也就越小,幅值也就越小

(脉冲通常是指电子技术中经常运用的一种象脉搏似的短暂起伏的电冲击(电压或电流)。脉冲宽度是指电子领域中,脉冲所能达到最大值所持续的周期。)

人眼太慢了,所以灯如果以非常快的速度闪烁,你只能看到亮度变化,而闪烁你是看不到的,这个就是通过PWM送出不同的脉宽,也是LED的灰度实现原理

TIM_PrescalerConfig(TIM2,71, TIM_PSCReloadMode_Immediate);

/**
  * @brief  Configures the TIMx Prescaler.
  * @param  TIMx: where x can be 1 to 17 to select the TIM peripheral.
  * @param  Prescaler: specifies the Prescaler Register value
  * @param  TIM_PSCReloadMode: specifies the TIM Prescaler Reload mode
  *   This parameter can be one of the following values:
  *     @arg TIM_PSCReloadMode_Update: The Prescaler is loaded at the update event.
  *     @arg TIM_PSCReloadMode_Immediate: The Prescaler is loaded immediately.
  * @retval None
  */
void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode)
{
  /* Check the parameters */
  assert_param(IS_TIM_ALL_PERIPH(TIMx));
  assert_param(IS_TIM_PRESCALER_RELOAD(TIM_PSCReloadMode));
  /* Set the Prescaler value */
  TIMx->PSC = Prescaler;
  /* Set or reset the UG Bit */
  TIMx->EGR = TIM_PSCReloadMode;
}

TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable); //你写入的CCRx值,立即生效 或者在更新事件之后生效,你就会用到这个预装载函数

*
  * @brief  Enables or disables the TIMx peripheral Preload register on CCR3.
  * @param  TIMx: where x can be  1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
  * @param  TIM_OCPreload: new state of the TIMx peripheral Preload register
  *   This parameter can be one of the following values:
  *     @arg TIM_OCPreload_Enable
  *     @arg TIM_OCPreload_Disable
  * @retval None
  */

@brief启用或禁用CCR3上的TIMx外围预加载寄存器。

*@param TIMx:其中x可以是1、2、3、4、5或8以选择TIM外围设备。

*@param TIM_OCPreload:TIMx外围预加载寄存器的新状态

*此参数可以是以下值之一:

*@arg TIM_OCPreload_启用

*@arg TIM_OCPreload_禁用

*@retval无


void TIM_OC3PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload)
{
  uint16_t tmpccmr2 = 0;
  /* Check the parameters */
  assert_param(IS_TIM_LIST3_PERIPH(TIMx));
  assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload));
  tmpccmr2 = TIMx->CCMR2;
  /* Reset the OC3PE Bit */
  tmpccmr2 &= (uint16_t)~((uint16_t)TIM_CCMR2_OC3PE);
  /* Enable or Disable the Output Compare Preload feature */
  tmpccmr2 |= TIM_OCPreload;
  /* Write to TIMx CCMR2 register */
  TIMx->CCMR2 = tmpccmr2;
}
 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这段代码是使用定时器2的通道1来生成PWM信号的配置代码。下面是对每个配置项的解释: - `timer_ocintpara.outputstate = TIMER_CCX_ENABLE;`:主输出通道开启。 - `timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE;`:互补输出通道关闭。 - `timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH;`:主输出极性高电平有效。 - `timer_ocintpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH;`:互补输出极性高电平有效。 - `timer_ocintpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW;`:主输出空闲状态为低电平。 - `timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;`:互补输出空闲状态为低电平。 - `timer_channel_output_config(TIMER2, TIMER_CH_1, &timer_ocintpara);`:配置定时器2的通道1的输出参数。 接下来是对PWM信号的具体配置: - `timer_channel_output_pulse_value_config(TIMER2, TIMER_CH_1, 500);`:设置PWM脉冲宽度为500。 - `timer_channel_output_mode_config(TIMER2, TIMER_CH_1, TIMER_OC_MODE_PWM0);`:设置PWM0模式,即高电平持续时间从计数器开始到达比较值时,输出为高电平,否则为低电平。 - `timer_channel_output_shadow_config(TIMER2, TIMER_CH_1, TIMER_OC_SHADOW_DISABLE);`:关闭输出通道的预装载功能。 通过以上配置,定时器2的通道1将以PWM0模式生成PWM信号,脉冲宽度为500。主输出通道开启,互补输出通道关闭,并且主输出极性和互补输出极性均为高电平有效。在空闲状态时,主输出通道和互补输出通道都为低电平。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值