STM32F1 PWM @ TIM2 Example

发布时间:2024年01月22日

PWM使用 Compare Output mode.

频率透过 TIMx->ARR 来调整。
DUTY透过 设定 TIMx->CCRx来产生。
TIMx->PSC 产生TIMX计算时基。
STM32系统版 TIM2 CH1 ~ CH4对应 PA0 ~ PA3, 测试很方便。
可以在相同频率下(共享PSC, ARR), 设定四个(CCRx)不同 DUTY的输出。

ARR Timing在这里插入图片描述<图片撷自 STM RM0008 Reference Manual. >

Example 1:

Timer Clock = 72MHz.
PWM 频率20KHz, 20KHz period = 50us.

简单运算, 将TIMX计算时基设定成 0.5us
TIMx->PSC = 72/2 – 1 = 35 ;
所以,
TIMx-> ARR = 50x2 -1 = 99;
Duty 0 ~ 100
TIMx->CCRx = Duty; // 0 ~ 100

Example 2: ( Servo Control )

Timer Clock = 72MHz.
PWM 频率50Hz , 50Hz period = 20ms.

将TIMX计算时基设定成 1us
TIMx->PSC = 72 – 1 = 71 ;
TIMx->ARR = 20000 -1;
Duty Time ( 500us ~ 2500us ) // 0 ~ 180 degree
TIMx->CCRx = Duty Time-1 ; // 499 ~ 2499 .

Example Code: TIM2 Init

void vPWMonGPIO_A0(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; 
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);    
}

/*******************************************************************************
* Function Name  : void vServoPWMInit(void) 
* Description    : PWM @TIM2 Init
* Return         : n/a
*                                                     By Jason Lu. 2024/01/22
********************************************************************************/ 
#define  PERIOD    20000  
void vServoPWMInit(void) 
{
    RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM2,   ENABLE);    
    TIM2->CR1     =   0x0004;     // Up mode, ARR PreLoad enable
    TIM2->CCMR1   =   0x0064;     // Individual Output mode, CCR1 PreLoad enable
    TIM2->PSC     =   72-1;       // 1 us base @SYSTEMCLK=72MHz
    TIM2->ARR     =   PERIOD-1;   // Set PWM period, FREQ  
    TIM2->CCR1    =   1500-1;     // Duty time 1.5ms = 90 degree, center
    TIM2->CCER    =   0x0003;     // OC1/CC1 Enable,  CC1P=1 Acitve High.  
 
    TIM2->EGR    |=   0x0001;     // UG=1 -> CNT=0, Preloaded
    TIM2->SR      =        0;     // Clear pending flags 
    TIM2->CR1    |= TIM_CR1_CEN;  // Enable TIM2 PWM
}

Duty Control

/*******************************************************************************
* Function Name  : void uSetPWMDuty( uint16_t  uDuty)
* Description    : Set PWM CCR1 as duty time  
* Praameters     : uDuty  duty cycle = 0 ~ 100
* Return         : n/a
*                                                     By Jason Lu. 2024/01/22
********************************************************************************/ 
void uSetPWMDuty( uint16_t  uDuty)     // Duty 0 ~ 100  
{
    if(   0 == uDuty) { TIM2->CCR1 = PERIOD;  return;}    // Always Low
    if( 100 <= uDuty) { TIM2->CCR1 =      0;  return;}    // Always High
    uint16_t   CCR1Value = PERIOD - ((uint32_t)PERIOD * uDuty/100);       
    TIM2->CCR1 = --CCR1Value; 
}

PS:

  1. TIM 设定成 Center Mode 时 (CR1= 0x006x), 因PWM信号连续, 量测频率=1/2 FREQ。
  2. PWM输出为 TIMx AFIO, 要设定 GPIO 为 GPIO_AF_PP or GPIO_AF_OD, 才会输出。
  3. PSC值设定可以简化计算和理解, 但是会影响分辨率, 要依实际状况取舍。
  4. ARR/ CCR1 pre-load 可以避免因值更新时造成的频率飘移过界and DUTY跳动。
  5. 伺服舵机可以用1 x TIM 对 4 channels, 减少资源耗用。

<笔记>天才脑袋比不上烂笔头, 写给自己看, 自用资料。
档案取自互联网!如有侵权或不适用情形, 请联系移除!
#STM32F103
#PWM
#Servo PWM

文章来源:https://blog.csdn.net/weixin_44679008/article/details/135748577
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。