我是靠谱客的博主 光亮茉莉,最近开发中收集的这篇文章主要介绍定时器TIM2输出pwm波,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

#define TIM2_CLK_ENABLE()               ( RCC->APB1ENR |= RCC_APB1ENR_TIM2EN  )
#define TIM3_CLK_ENABLE()               ( RCC->APB1ENR |= RCC_APB1ENR_TIM3EN )

#define TIMx_CHANNEL_GPIOA_PORT()       ( RCC->IOPENR |= (RCC_IOPENR_GPIOAEN))
#define TIMx_CHANNEL_GPIOB_PORT()       ( RCC->IOPENR |= (RCC_IOPENR_GPIOBEN))

arm_drv_tim_pwm_channel_config (TIM2_BASE, GPIO_A, GPIO_A_15, GPIO_AF5_TIM2, TIM_CHANNEL_1);


short drv_io_config_pin( unsigned long pin, unsigned char config )
{
  unsigned short port, index, bits;
  GPIO_TypeDef* GPIO_Init_PORT;
  GPIO_InitTypeDef  GPIO_InitStruct;

  port = (unsigned short)(pin >> 16);   // port index for PORT A-H (0-4)
  if(port > (MAXIMUM_GPIO_PORT-1))   // only has 5 ports: PORT_[A~H]
  return 1;
  GPIO_Init_PORT = GPIO_PORT[port];
  GPIO_InitStruct.Pin = 0;

  bits = 0x8000;        // start from bit 15.

  // prepare configure register
  for( index = 0; index < 16; index++ )
  {
    if( pin & bits )
    {
      // the bit is selected.
      GPIO_InitStruct.Pin = bits;

      // config format: 0011,0001.pupd[7:6]=00=no pull-up, pull-down; ospeed[5:4]=11=high speed; otype[2]=0=push-pull;  mode[1:0]=01=output.
      GPIO_InitStruct.Mode = (GPIOMode_TypeDef) (config & 0x03); // GPIO_Mode;
      GPIO_InitStruct.OType = (GPIOOType_TypeDef)((config>>2)&0x01); //  GPIO_OType;
      GPIO_InitStruct.Speed = (GPIOSpeed_TypeDef)((config>>4)&0x03); // GPIO_OSpeed;
      GPIO_InitStruct.PuPd = (GPIOPuPd_TypeDef)((config>>6)&0x03); //GPIO_PuPd
      
      GPIO_Init(GPIO_Init_PORT, &GPIO_InitStruct);
    }
    bits >>= 1;
  }
  return 0;
}

void drv_io_af_config(unsigned long pin, unsigned char gpio_af)
{
  unsigned short port, GPIO_PinSource;
  unsigned long pos;
  GPIO_TypeDef* GPIOx;
  unsigned long temp = 0x00;
  unsigned long temp_2 = 0x00;
  unsigned long temp_3 = 0x00;

  port = (unsigned short)(pin >> 16); // port index for PORT A-H (0-4)
  if(port > (MAXIMUM_GPIO_PORT-1))    // only has 5 ports: PORT_[A~H]
  return;
  GPIOx = GPIO_PORT[port];
  
  for(GPIO_PinSource = 0x00; GPIO_PinSource < 0x10; GPIO_PinSource++)
  {
    pos = ((unsigned long)0x01) << GPIO_PinSource;
    if(pin & pos) //Get the port pin position
    {
      temp = (unsigned long)(gpio_af) << ((unsigned long)((unsigned long)GPIO_PinSource & (unsigned long)0x07) * 4);
      temp_2 = GPIOx->AFR[GPIO_PinSource >> 0x03] & (~((unsigned long)0xF << ((unsigned long)((unsigned long)GPIO_PinSource & (unsigned long)0x07) * 4)));
      temp_3 = temp_2 | temp;
      GPIOx->AFR[GPIO_PinSource >> 0x03] = temp_3;
    }
  }
}


void arm_drv_tim_pwm_channel_config (uint32_t  u32TimerBase,
                                     uint32_t  u16GpioPortNo,
                                     uint32_t  u16GpioPinNo,
                                     uint32_t  u16GpioAltNo,
                                     uint16_t  u16TimerChannel)
{
    TIM_TypeDef  *TIMx;
    GPIO_TypeDef *GPIOx;

    TIMx    = (TIM_TypeDef *)u32TimerBase;

    TIM_Base_InitTypeDef TIM_InitStructure;

    TIM_OC_InitTypeDef sConfig;

//    uint32_t u32PinAddr;
    uint32_t tmpcr1 = 0;

    switch (u16GpioPortNo)
    {
        case GPIO_A:  GPIOx = GPIOA;     break;
        case GPIO_B:  GPIOx = GPIOB;     break;
        case GPIO_C:  GPIOx = GPIOC;     break;
        case GPIO_D:  GPIOx = GPIOD;     break;
    }

    /*##-1- Enable peripherals and GPIO Clocks #################################*/
    /* TIMx Peripheral clock enable */
    if ( TIMx == TIM2)
    {
        TIM2_CLK_ENABLE();
    }
    else if ( TIMx == TIM3)
    {
        TIM3_CLK_ENABLE();
    }

    /* Enable all GPIO Channels Clock requested */
    if ( GPIOx == GPIOA)
    {
        TIMx_CHANNEL_GPIOA_PORT();
    }
    else if ( GPIOx == GPIOB)
    {
        TIMx_CHANNEL_GPIOB_PORT();
    }

     /*##-1.1- setup GPIO port accordingly     #################################*/
    /* Common configuration for all channels */
    drv_io_config_pin(u16GpioPinNo, GPIO_AFO_PP_HIGH_UP);
//    // setup AFR with pin number
    drv_io_af_config(u16GpioPinNo, u16GpioAltNo);

    /*##-2.1- initialize the timer to be the PWM with known period ##############*/
    // fill up the common initialization settings
    TIM_InitStructure.Prescaler= (uint32_t)(SystemCoreClock / 2000000) - 1;
    TIM_InitStructure.CounterMode= TIM_COUNTERMODE_UP;
    //TIM_InitStructure.Period= PERIOD_VALUE;
    TIM_InitStructure.Period= *DEVICE_CONFIG_1_BIAS_PWM_PERIOD_COUNT;
    TIM_InitStructure.ClockDivision= 0;

    //arm_drv_tim_Base_SetConfig(TIMx, &TIM_InitStructure);
    // can create a new standalone function for this functionality
    /* save CR1 content first */
    tmpcr1 = TIMx->CR1;

    /* set the counter Mode */
    tmpcr1 &= ~(TIM_CR1_DIR | TIM_CR1_CMS);
    tmpcr1 |= TIM_InitStructure.CounterMode;

    /* set the clock division*/
    tmpcr1 &= ~TIM_CR1_CKD;
    tmpcr1 |= (uint32_t)TIM_InitStructure.ClockDivision;

    TIMx->CR1 = tmpcr1;

    /* Set the Autoreload value */
    TIMx->ARR = (uint32_t)TIM_InitStructure.Period ;

    /* Set the Prescaler value */
    TIMx->PSC = (uint32_t)TIM_InitStructure.Prescaler;

    /* Generate an update event to reload the Prescaler value immediatly */
    TIMx->EGR = TIM_EGR_UG;

    //arm_drv_tim_Base_SetConfig(TIMx, &TIM_InitStructure);

    /*##-2- Configure the PWM channels #########################################*/
    /* Common configuration for all channels */
    sConfig.OCMode       = TIM_OCMODE_PWM1;
    sConfig.OCPolarity   = TIM_OCPOLARITY_HIGH;
    sConfig.OCFastMode   = TIM_OCFAST_DISABLE;

    /* configure the timer with the given channel # */
    arm_drv_tim_pwm_channel_setting (TIMx, &sConfig, u16TimerChannel);

    /* start the timer for the desired channel */

    arm_drv_tim_pwm_start (TIMx,  (uint32_t)u16TimerChannel);
}

1、配置GPIO口
2、初始化定时器
3、设置TIM2_CH1的PWM模式,使能TIM2的CH1输出
4、使能定时器2
5、使用PWM

最后

以上就是光亮茉莉为你收集整理的定时器TIM2输出pwm波的全部内容,希望文章能够帮你解决定时器TIM2输出pwm波所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(55)

评论列表共有 0 条评论

立即
投稿
返回
顶部