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

这篇具有很好参考价值的文章主要介绍了基于STM32配置PWM的输出和相关GPIO口的配置(有关重映像问题解答)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

/******************************************************************************************************************************
*使用PWM来实现对电机的控制,实现开环的速度控制
*
*使用四个直流电机 motor1:     motor2:     
*                motor3:     motor4:
*
cnt = 0 对应占空比0

TIM3:(部分重映像)
CH1:PB4
CH2:PB5
CH3:PB0
CH4:PB1

TIM4:
CH1:PB6
CH2:PB7
CH3:PB8
CH4:PB9
*******************************************************************************************************************************/
void TIM_PWM_Init(void)
{
	//设置变量
	GPIO_InitTypeDef GPIO_InitStructure;
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
	TIM_OCInitTypeDef TIM_OCInitStructure; 
	
	//使能时钟
	RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM3 | RCC_APB1Periph_TIM4 , ENABLE);
	RCC_APB2PeriphClockCmd(  RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
	GPIO_PinRemapConfig( GPIO_PartialRemap_TIM3 , ENABLE);//使定时器TIM4进行部分重映像操作
	//GPIO_PinRemapConfig(GPIO_Remap_TIM4,ENABLE);
	 
	
	TIM_TimeBaseStructure.TIM_Period = 899;
	TIM_TimeBaseStructure.TIM_Prescaler = 0;
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseStructure.TIM_ClockDivision = 0;
	TIM_TimeBaseInit(TIM3 , &TIM_TimeBaseStructure);
	TIM_TimeBaseInit(TIM4 , &TIM_TimeBaseStructure);
	
	//端口复用
	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 ;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 	
	GPIO_Init(GPIOB, &GPIO_InitStructure);   
	
	
	//PB4:TIM3_CH1
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
	TIM_OCInitStructure.TIM_Pulse = 0;
	TIM_OC1Init(TIM3 , &TIM_OCInitStructure);
	TIM_OC1PreloadConfig(TIM3 , TIM_OCPreload_Enable);
	
	//PB5:TIM3_CH2
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
	TIM_OCInitStructure.TIM_Pulse = 450;
	TIM_OC2Init(TIM3 , &TIM_OCInitStructure);
	TIM_OC2PreloadConfig(TIM3 , TIM_OCPreload_Enable);
	
	//PB0:TIM3_CH3
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
	TIM_OCInitStructure.TIM_Pulse = 0;
	TIM_OC3Init(TIM3 , &TIM_OCInitStructure);
	TIM_OC3PreloadConfig(TIM3 , TIM_OCPreload_Enable);
	
	//PB1:TIM3_CH4 
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
	TIM_OCInitStructure.TIM_Pulse = 0;
	TIM_OC4Init(TIM3 , &TIM_OCInitStructure);
	TIM_OC4PreloadConfig(TIM3 , TIM_OCPreload_Enable);
	
	
//	
	//PB6:TIM4_CH1
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
	TIM_OCInitStructure.TIM_Pulse = 900;
	TIM_OC1Init(TIM4 , &TIM_OCInitStructure);
	TIM_OC1PreloadConfig(TIM4 , TIM_OCPreload_Enable);
	
	//PB7:TIM4_CH2
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
	TIM_OCInitStructure.TIM_Pulse = 900;
	TIM_OC2Init(TIM4 , &TIM_OCInitStructure);
	TIM_OC2PreloadConfig(TIM4 , TIM_OCPreload_Enable);
	
	//PB8:TIM4_CH3
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
	TIM_OCInitStructure.TIM_Pulse = 0;
	TIM_OC3Init(TIM4 , &TIM_OCInitStructure);
	TIM_OC3PreloadConfig(TIM4 , TIM_OCPreload_Enable);
	
	//PB9:TIM4_CH4
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
	TIM_OCInitStructure.TIM_Pulse = 900;
	TIM_OC4Init(TIM4 , &TIM_OCInitStructure);
	TIM_OC4PreloadConfig(TIM4 , TIM_OCPreload_Enable);

	TIM_Cmd(TIM3, ENABLE);
	TIM_Cmd(TIM4, ENABLE);
}

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

stm32pwm配置详解,stm32,单片机,嵌入式硬件

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

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

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

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

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

(1)使能时钟        

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

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

typedef struct
{
  uint16_t TIM_Prescaler;         /*!< Specifies the prescaler value used to divide the TIM clock.
                                       This parameter can be a number between 0x0000 and 0xFFFF */

  uint16_t TIM_CounterMode;       /*!< Specifies the counter mode.
                                       This parameter can be a value of @ref TIM_Counter_Mode */

  uint16_t TIM_Period;            /*!< Specifies the period value to be loaded into the active
                                       Auto-Reload Register at the next update event.
                                       This parameter must be a number between 0x0000 and 0xFFFF.  */ 

  uint16_t TIM_ClockDivision;     /*!< Specifies the clock division.
                                      This parameter can be a value of @ref TIM_Clock_Division_CKD */

  uint8_t TIM_RepetitionCounter;  /*!< Specifies the repetition counter value. Each time the RCR downcounter
                                       reaches zero, an update event is generated and counting restarts
                                       from the RCR value (N).
                                       This means in PWM mode that (N+1) corresponds to:
                                          - the number of PWM periods in edge-aligned mode
                                          - the number of half PWM period in center-aligned mode
                                       This parameter must be a number between 0x00 and 0xFF. 
                                       @note This parameter is valid only for TIM1 and TIM8. */
} TIM_TimeBaseInitTypeDef;

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

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

TIM_Period:时钟周期

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

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

	//PB4:TIM3_CH1 TIM3通道1
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//PWM1输出模式
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
	TIM_OCInitStructure.TIM_Pulse = 0;//cnt捕获值,和占空比有关
	TIM_OC1Init(TIM3 , &TIM_OCInitStructure);
	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定时器

    TIM_Cmd(TIM3, ENABLE);
	TIM_Cmd(TIM4, ENABLE);
	TIM_Cmd(TIM2, ENABLE);

这就是初始化PWM的整个流程,希望可以帮助到你。文章来源地址https://www.toymoban.com/news/detail-732734.html

到了这里,关于基于STM32配置PWM的输出和相关GPIO口的配置(有关重映像问题解答)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32F407 GPIO口输出配置配置步骤

    STM32F407ZGT6 是意法半导体(STMicroelectronics)公司推出的一款高性能ARM Cortex-M4核心的32位微控制器(MCU)。它是 STM32F4 系列的一员,具备强大的处理能力和丰富的外设功能,适用于各种应用领域。 说明:STM32F4 的主频最高是 168Mhz,所以我们一般设置 PLLCLK 为 168Mhz(M=8,N=336,P=2),通

    2024年02月12日
    浏览(52)
  • STM32 HAL库 通用定时器介绍及相关应用例程 定时器中断 输出PWM (点亮LED呼吸灯、输出PWM、输入捕获) CubeMX

    (部分图引自于ATK) 前情提要(基本定时器) 点此进入 通用定时器类别 通用定时器和基本定时器相比大致的工作方式是相似的,不过通用定时器比基本定时器多了一些很好用的功能,比如: 外部输入捕获 输出比较 输出PWM 时钟源 CubeMX为我们提供了配置时钟的非常方便的工

    2024年04月15日
    浏览(86)
  • STM32高级定时器输出指定数量PWM(STM32CubeMx配置)

    高级定时器中有一个重复计数器,本实验输出指定个数PWM就是利用了重复计数器的特性,先来看看重复计数器的特性是什么: 计数器每次上溢或下溢都能使重复计数器减1,减到0时,再发生一次溢出就会产生更新事件 这是什么意思呢,这里举个例子比如说我设定重复计数器的

    2024年02月02日
    浏览(88)
  • STM32初学入门笔记(2):STM32CubeMX配置STM32输出可调PWM方波

    PWM是一种应用广泛的利用微处理器的数字输出来对模拟电路进行控制的一种技术(即对脉冲宽度的控制)PWM同时也是驱动蜂鸣器,驱动舵机,通信等重要的一环,而对于初学者而言,点完灯的下一个程序就是驱动蜂鸣器,本篇将讲述如何使用及调整PWM输出频率,占空比 工程文

    2024年02月14日
    浏览(46)
  • STM32使用CubeMx配置定时器输出PWM

            项目中经常使用到STM32来输出PWM,每次配置过后过不了多久就会忘记,稍微需要对配置做出修改时都要翻很久的手册,所以决定结合实例把PWM配置的详细步骤记录下来,这样在下次配置时可以很快的捡起来。         本文档的行文结构如下,首先,说明实际需

    2024年02月03日
    浏览(70)
  • STM32一个定时器同时配置编码器和PWM输出时PWM无法正常输出的原因【避坑】

             最近我在做写代码的时候,因为定时器的资源紧张,就在一个定时器上同时配置了编码器和PWM,发现PWM无法正常输出,查了很久发现网上资料不多,在仔细翻阅手册研究后才发现是 时钟信号 的问题。 具体原因 定时器在设置编码器模式后,计数的时钟源就会变成编

    2024年02月04日
    浏览(57)
  • 用STM32CubeMX配置输出PWM信号控制多路舵机(HAL)

    (1)编程平台:Keil5 (2)CubeMX (1)本此使用最小核心板STM32F103C8T6为例 (2)一个舵机:SG90或者MG996等均可 (3)ST-link 下载器 (4)杜邦线若干         舵机的控制一般需要一个20ms左右的时基脉冲,该脉冲的高电平部分一般为0.5ms-2.5ms范围内的角度控制脉冲部分,总间隔为2ms。以180度角度

    2023年04月09日
    浏览(45)
  • 嵌入式-Stm32-江科大基于标准库的GPIO通用输入输出口

    (推荐先看文章:《 嵌入式-32单片机-GPIO推挽输出和开漏输出》) 下文图都是从参考手册借阅:STM32F10xxx(中文),大概页数是110/775左右 GPIO (General Purpose Input Output)通用输入输出口 可配置为8种输入输出模式 引脚电平:0V~3.3V,部分引脚可容忍5V(有FT标识) 输出模式 下可控

    2024年01月17日
    浏览(63)
  • STM32 PWM模式与输出比较模式的区别。PWM占空比不生效,在STM32CubeMX中配置PWM的两种模式——蓝桥杯嵌入式

      🎊【蓝桥杯嵌入式】专题正在持续更新中,原理图解析✨,各模块分析✨以及历年真题讲解✨都已更新完毕,欢迎大家前往订阅本专题🎏 🎏【蓝桥杯嵌入式】蓝桥杯第十届省赛真题 🎏【蓝桥杯嵌入式】蓝桥杯第十二届省赛程序真题 🎏【蓝桥杯嵌入式】蓝桥杯第十三届

    2023年04月15日
    浏览(80)
  • 步进电机简单使用:STM32 PWM输出固定数目的脉冲数(基于CubeMX)

    使用步进电机之前,我们需要了解步距角的概念:步进电机接收到一个脉冲转动的角度,步进电机步距角通常 为1.8°,即步进电机接收到一个脉冲转动1.8°,则若步进电机接收到360°/1.8°=200个脉冲,步进电机就能转动一圈 步进电机通过驱动器控制,驱动器如下图所示(都比较

    2024年02月06日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包