当前位置:   article > 正文

基于STM32配置PWM的输出和相关GPIO口的配置(有关重映像问题解答)_stm32pwm输出引脚

stm32pwm输出引脚

使用STM32定时器进行PWM的配置有以下几个步骤,以下是参考例差可以作为历程参考。

  1. /******************************************************************************************************************************
  2. *使用PWM来实现对电机的控制,实现开环的速度控制
  3. *
  4. *使用四个直流电机 motor1: motor2:
  5. * motor3: motor4:
  6. *
  7. cnt = 0 对应占空比0
  8. TIM3:(部分重映像)
  9. CH1:PB4
  10. CH2:PB5
  11. CH3:PB0
  12. CH4:PB1
  13. TIM4:
  14. CH1:PB6
  15. CH2:PB7
  16. CH3:PB8
  17. CH4:PB9
  18. *******************************************************************************************************************************/
  19. void TIM_PWM_Init(void)
  20. {
  21. //设置变量
  22. GPIO_InitTypeDef GPIO_InitStructure;
  23. TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  24. TIM_OCInitTypeDef TIM_OCInitStructure;
  25. //使能时钟
  26. RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM3 | RCC_APB1Periph_TIM4 , ENABLE);
  27. RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
  28. GPIO_PinRemapConfig( GPIO_PartialRemap_TIM3 , ENABLE);//使定时器TIM4进行部分重映像操作
  29. //GPIO_PinRemapConfig(GPIO_Remap_TIM4,ENABLE);
  30. TIM_TimeBaseStructure.TIM_Period = 899;
  31. TIM_TimeBaseStructure.TIM_Prescaler = 0;
  32. TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  33. TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  34. TIM_TimeBaseInit(TIM3 , &TIM_TimeBaseStructure);
  35. TIM_TimeBaseInit(TIM4 , &TIM_TimeBaseStructure);
  36. //端口复用
  37. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 ;
  38. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  39. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  40. GPIO_Init(GPIOB, &GPIO_InitStructure);
  41. //PB4:TIM3_CH1
  42. TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  43. TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  44. TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  45. TIM_OCInitStructure.TIM_Pulse = 0;
  46. TIM_OC1Init(TIM3 , &TIM_OCInitStructure);
  47. TIM_OC1PreloadConfig(TIM3 , TIM_OCPreload_Enable);
  48. //PB5:TIM3_CH2
  49. TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  50. TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  51. TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  52. TIM_OCInitStructure.TIM_Pulse = 450;
  53. TIM_OC2Init(TIM3 , &TIM_OCInitStructure);
  54. TIM_OC2PreloadConfig(TIM3 , TIM_OCPreload_Enable);
  55. //PB0:TIM3_CH3
  56. TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  57. TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  58. TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  59. TIM_OCInitStructure.TIM_Pulse = 0;
  60. TIM_OC3Init(TIM3 , &TIM_OCInitStructure);
  61. TIM_OC3PreloadConfig(TIM3 , TIM_OCPreload_Enable);
  62. //PB1:TIM3_CH4
  63. TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  64. TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  65. TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  66. TIM_OCInitStructure.TIM_Pulse = 0;
  67. TIM_OC4Init(TIM3 , &TIM_OCInitStructure);
  68. TIM_OC4PreloadConfig(TIM3 , TIM_OCPreload_Enable);
  69. //
  70. //PB6:TIM4_CH1
  71. TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  72. TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  73. TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  74. TIM_OCInitStructure.TIM_Pulse = 900;
  75. TIM_OC1Init(TIM4 , &TIM_OCInitStructure);
  76. TIM_OC1PreloadConfig(TIM4 , TIM_OCPreload_Enable);
  77. //PB7:TIM4_CH2
  78. TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  79. TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  80. TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  81. TIM_OCInitStructure.TIM_Pulse = 900;
  82. TIM_OC2Init(TIM4 , &TIM_OCInitStructure);
  83. TIM_OC2PreloadConfig(TIM4 , TIM_OCPreload_Enable);
  84. //PB8:TIM4_CH3
  85. TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  86. TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  87. TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  88. TIM_OCInitStructure.TIM_Pulse = 0;
  89. TIM_OC3Init(TIM4 , &TIM_OCInitStructure);
  90. TIM_OC3PreloadConfig(TIM4 , TIM_OCPreload_Enable);
  91. //PB9:TIM4_CH4
  92. TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  93. TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  94. TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  95. TIM_OCInitStructure.TIM_Pulse = 900;
  96. TIM_OC4Init(TIM4 , &TIM_OCInitStructure);
  97. TIM_OC4PreloadConfig(TIM4 , TIM_OCPreload_Enable);
  98. TIM_Cmd(TIM3, ENABLE);
  99. TIM_Cmd(TIM4, ENABLE);
  100. }

在上述PWM初始化函数中使用定时器TIM3和TIM4来输出PWM波,其中为了更好的应用IO口的布局等等TIM3进行了部分重映像的操作,这意味着部分引脚可以使用重映像的操作使之拥有另外的功能,即让TIM4本来该复用的引脚重映像到了其他引脚上。这个时候我们就需要查找相关的参考手册来对比引脚关系。如我使用的STM32F103。

通过表格我们就可以知道我想要使用PB4和PB5作为PWM的输出引脚,所以对TIM3使用了部分重映像的功能,实现这个功能的代码是:

GPIO_PinRemapConfig( GPIO_PartialRemap_TIM3 , ENABLE);//使定时器TIM3进行部分重映像操作

     这里有一个值得注意的地方,若是其他的功能引脚需要复用IO口,同样也是需要相同的方法来对该外设进行部分重映像或完全重映像(若是没有重映象则不需要),而需要重映像对象则可以在库函数中找到。如我需要使用PD8和PD9作为USART3的TXD和RXD引脚则需要完全重映像USART3:

  1. RCC_APB1PeriphClockCmd( RCC_APB1Periph_USART3, ENABLE ); /* 使能USART1,GPIOA时钟 */
  2. GPIO_PinRemapConfig(GPIO_FullRemap_USART3,ENABLE); //完全重映像USART3,使用PD8和PD9作为USART3的TXD和RXD引脚

除了重映像的问题其余就是以下几个步骤:

(1)使能时钟        

(2)配置GPIO口  pin、speed、mode等,其中mode需选择为GPIO_Mode_AF_PP复用输出。

(3)配置基本的定时器参数,

  1. typedef struct
  2. {
  3. uint16_t TIM_Prescaler; /*!< Specifies the prescaler value used to divide the TIM clock.
  4. This parameter can be a number between 0x0000 and 0xFFFF */
  5. uint16_t TIM_CounterMode; /*!< Specifies the counter mode.
  6. This parameter can be a value of @ref TIM_Counter_Mode */
  7. uint16_t TIM_Period; /*!< Specifies the period value to be loaded into the active
  8. Auto-Reload Register at the next update event.
  9. This parameter must be a number between 0x0000 and 0xFFFF. */
  10. uint16_t TIM_ClockDivision; /*!< Specifies the clock division.
  11. This parameter can be a value of @ref TIM_Clock_Division_CKD */
  12. uint8_t TIM_RepetitionCounter; /*!< Specifies the repetition counter value. Each time the RCR downcounter
  13. reaches zero, an update event is generated and counting restarts
  14. from the RCR value (N).
  15. This means in PWM mode that (N+1) corresponds to:
  16. - the number of PWM periods in edge-aligned mode
  17. - the number of half PWM period in center-aligned mode
  18. This parameter must be a number between 0x00 and 0xFF.
  19. @note This parameter is valid only for TIM1 and TIM8. */
  20. } TIM_TimeBaseInitTypeDef;

TIM_Prescaler:定时器分频系数psc,对时钟频率进行分频;

TIM_CounterMode:计数模式,向上计数或是向下计数

TIM_Period:时钟周期

TIM_ClockDivision:时钟分频。(设置为0即可)

(4)配置定时器的输出参数:

  1. //PB4:TIM3_CH1 TIM3通道1
  2. TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//PWM1输出模式
  3. TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  4. TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  5. TIM_OCInitStructure.TIM_Pulse = 0;//cnt捕获值,和占空比有关
  6. TIM_OC1Init(TIM3 , &TIM_OCInitStructure);
  7. TIM_OC1PreloadConfig(TIM3 , TIM_OCPreload_Enable);

PWM的占空比为n = pul/arr

PWM的周期计算为 T = psc/72M(f103的时钟频率)*arr 如arr=1000,psc=7200,arr=1000则可计算PWM周期为T=7200/72000000*1000=0.1s f=1/T=10HZ

(5)使能TIM定时器

  1. TIM_Cmd(TIM3, ENABLE);
  2. TIM_Cmd(TIM4, ENABLE);
  3. TIM_Cmd(TIM2, ENABLE);

这就是初始化PWM的整个流程,希望可以帮助到你。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/302068
推荐阅读
相关标签
  

闽ICP备14008679号