STM32F1 PWM @ TIM2 Example

PWM使用 Compare Output mode.

HAL/ StdLib 有点云来雾去的, 看了一下文件, 把TIM Registers捋一捋, 笔记笔记。
免得急用, 有虫查不出来, 浪费时间.

思路

频率透过 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; 
}

划重点:

  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, 减少资源耗用。
  6. 500Hz, 点高亮LED, DUTY 1% 就会亮, DUTY 30%之后就达到亮度80%以上,用在电池上,妥妥的。

<笔记>
天才脑袋比不上烂笔头, 写给自己看, 自用资料。
档案取自互联网! 如有侵权或不适用情形, 请联系移除!
请勿转载! 不建议 Ctrl-C + Ctrl-V 请自行考虑!
#STM32F103
#PWM
#Servo PWM

  • 10
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值