精华内容
下载资源
问答
  • stm32高级定时器pwm输出
    千次阅读 多人点赞
    2020-09-30 20:36:01

    一、问题背景

    最近做了下门禁系统用到了舵机,但是用TIM1生成PWM驱动舵机时,发现给出命令后(程序改变完占空比),要等一会儿舵机才能响应转动。 于是四处查找,终于找到一些有用信息,在这里做下记录,防止自己忘掉了又找不到,也希望帮到遇到同样问题的人。

    问题符合且心急的小伙伴直接到最后~~~

    二、解决过程

    先来了解两点

    1、TIM_RepetitionCounter 参数

    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; //重复计数

    这是个高级定时器才有的一个配置参数,普通定时器并没有。它影响着高级定时器溢出次数和产生更新事件次数的关系。
    ------------- 更新事件次数 = 溢出次数 x(TIM_RepetitionCounter +1)

    于是它也就同时影响着:

    1. 进入更新中断的次数(这个好理解,开启了中断就是更新一次进一次)
    2. PWM占空比改变的延迟时间(下条说明)

    注意!!!不配置这个参数并且没有在开头复位外设(TIM_DeInit(TIM1))的情况下,这个参数是随机的!随机的!随机的!!!我就是,结果找问题找了两天。

    2、预装载使能

    就是下面这行代码:
    TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Disable);

    1. 这个函数使能

    只能在每次更新事件时改变占空比,就算程序执行了TIM_SetCompare2(TIM1,val),也要等更新事件产生才起作用。(也就是只写进了预装载寄存器,待到更新事件之后才会自动装进比较寄存器)

    1. 这个函数失能

    每次只要执行了 TIM_SetCompare2(TIM1,val) 就会立刻改变占空比。

    3、理解

    结合上面两点,举个例子:
    TIM1设置7200分频 ,周期200。即产生50HZ的PWM波。
    TIM_RepetitionCounter 设置为 199,使能OC预装载。(这个是8位寄存器,最大255)

    此时定时器每20ms溢出一次,每20*(199+1)= 4000ms产生一次更新事件,同样的每4000ms从预装载寄存器里搬运数值到比较寄存器,来改变输出的占空比。

    如果程序在刚产生更新事件之后执行了TIM_SetCompare2(TIM1,val)来试图改变占空比,那么就要等上4000ms实际输出PWM的占空比才会发生相应的改变。延迟相当大。
    尽管是为了突出问题,TIM_RepetitionCounter 特意取值大了点,但事实上延迟是的的确确存在的,而且很明显。

    (我也是做舵机的控制才发现延迟这么明显,如果是用于直流电机的控制大概就理解成系统自身的延迟了。)

    三、解决办法

    经过以上了解可知,解决办法:

    1. 简单粗暴 关掉TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Disable); 的使能,占空比就会在程序执行后立刻改变。缺点是,可能会有一个波形不完整(被强行打断了),只要不是特殊应用场合,这个应该问题不大。
    2. 将TIM_RepetitionCounter 设置为0,这样就算有延迟也最多一个PWM周期而已,可以接受。(不配置且开头没复位外设的话为随机数

    注:上述预装载寄存器仅仅指比较寄存器对应的,不是其他地方的预装载寄存器!!

    以上内容为查资料及自己的理解所得,如有错误还请指正。

    四、参考链接

    STM32 定时器中TIM_RepetitionCounter 作用详解

    关于TIM_ARRPreloadConfig函数与TIM_OCxPreloadConfig

    更多相关内容
  • STM32学习入门
  • stm32 高级定时器-PWM互补输出带死区时间 stm32 高级定时器-PWM互补输出带死区时间 stm32 高级定时器-PWM互补输出带死区时间
  • 高级定时器PWM波介绍及配置

    本人纯小白一枚,如有错误,还请大佬指出

    目录

    1.定时器引脚图

    2.总体框架

    2.1时基模块

    2.2比较寄存器

    2.3死区发生器

    2.4输出控制

    3.结构体

    4.编程

    5.说明


    1.定时器引脚图

    2.总体框架

    注:高级定时器除了通用定时器所具有的输入捕获和输出比较功能外,另外还添加了可编程死区互补输出、重复计 数器、带刹车 (断路) 功能,本文章只截取了其中的输出比较框图。

    我将高级定时器的框架分为4个部分:时基模块、比较寄存器、死区发生器、输出控制。

    2.1时基模块

    高级定时器时钟源有4个,这里仅介绍内部时钟源

     时基单元框架如图

    将此分为4部分:1.预分频器PSC,可实现1-65536的分频。2.计数器 CNT:三种计数模式,递增计数模式、递减计数模式和递增/递减 (中 心对齐) 计数模式。3.自动重载寄存器 ARR及4.重复计数器 RCR

    这里与基本定时器不一样的就是三种计数模式及重复计数器。

    通俗来讲就是,循环从0(或最大值)往上(或往下数),当数到最大值(或0),可以发生中断或者事件,而当使用了重复计数器后,数特定的遍数会产生中断1或者事件。其中往上或者往下计数则取决于计数模式。

    而本次输出PWM波,不需要采用中断,只需其计数功能即可。

    2.2比较寄存器

    当计数器 CNT 的值跟比较寄存器 CCR 的值相等的时候,输出参考信号 OCxREF 的信号的极性 就会改变,其中 OCxREF=1(高电平)称之为有效电平,OCxREF=0(低电平)称之为无效电平。

    此处输出的信号为OCxREF.

    在进入死区发生器之前,可以设置输出比较模式,对于输出PWM波而言,有两个模式可供选择,分别为PWM1,PWM2

    2.3死区发生器

    在经过死区发生器之后会产生两路带死区的互补 信号 OCx_DT 和 OCxN_DT。如果没有加入死区控制,那么进入输出控制电 路的信号就直接是 OCxREF。

    单纯的PWM波,此处不做详细介绍。

    2.4输出控制

    由死区发生器输出的信号会被分成两路,一路是原始信号,一路是被反向的信号,具体的由寄存器 CCER 的位 CCxP 和 CCxNP 控制。经过极性选择的信号是否由 OCx 引脚输出到外部引脚 CHx/CHxN (即是否使能),则由寄存器 CCER 的位 CxE/CxNE 配置。

    3.结构体

    typedef struct
    {
      uint16_t TIM_Prescaler;        //时钟预分频,对应PSC
                                     
      uint16_t TIM_CounterMode;      //时钟计数模式,对应3中计数方法
                                     
      uint16_t TIM_Period;           //定时器周期,对应ARR寄存器
                                                                 
      uint16_t TIM_ClockDivision;    //时钟分频,设置定时器时钟 CK_INT 频率与死区发生器以及数字滤 
                                     //波器,采样时钟频率分频比。可以选择 1、2、4 分频。
    
      uint8_t TIM_RepetitionCounter; //重复计数器,对应RAR
                                                                     
    } TIM_TimeBaseInitTypeDef;       
    
    
    typedef struct
    {
      uint16_t TIM_OCMode;          //输出模式,PWM1及PWM2,对应寄存器CCMR1->OCxM
                                 
      uint16_t TIM_OutputState;     //比较输出使能,对应CCER->CCxE
                                 
      uint16_t TIM_OutputNState;    //比较互补输出使能,对应CCER->CCxNE
                                  
      uint16_t TIM_Pulse;           //脉冲宽度,即比较寄存器的值,对应CCR1
                                 
      uint16_t TIM_OCPolarity;      //输出极性,对应CCER->CCxP
    
      uint16_t TIM_OCNPolarity;     //互补输出极性,对应CCER->CCxP
    
      uint16_t TIM_OCIdleState;     //空闲状态比较输出状态,对应CR2->OIS1
    
      uint16_t TIM_OCNIdleState;    //空闲状态下比较互补输出状态,对应CR2->OIS1N
                                   
    } TIM_OCInitTypeDef;
    
    

     配置pwm的结构体主要用到两个,一个是时基初始化的结构体,一个是输出比较的结构体,时基初始化的结构体

    其中输出比较的结构体对应图中的寄存器如下图

     但是我们除了要配备这两个结构体之外,还有一个寄存器要使能 

    对应BDER->MOE寄存器,官方介绍如下图

     就是使能输出引脚

    4.编程

    总结一下,编程的目标:

    1.对通道的GPIO引脚进行配置

    2.对两个结构体进行配置

    3.使能时钟源,使能输出通道

    以下程序配置的为1Khz,占空比为40%的PWM波

    void advance_tim1_gpio_config(void)
    {
    	//1.结构体
    	GPIO_InitTypeDef GPIO_InitStructure;
    	
    	//2.开时钟
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    
    	//3.配置
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    		
    	//4.初始化
    	GPIO_Init(GPIOA, &GPIO_InitStructure);
    	
    	//5.使能(无)	
    }
    
    void advance_tim1_mode_config()
    {
    	//1.结构体,时基结构体及输出比较结构体
    	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    	TIM_OCInitTypeDef TIM_OCInitStructure;
    	
    	//2.开时钟,TIM1的时钟
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
    	
    	//3.配置及初始化
    	/*--------------------时基结构体初始化-------------------------*/
    	// PWM 信号的频率 F = TIM_CLK/{(ARR+1)*(PSC+1)}
    	
    	TIM_TimeBaseStructure.TIM_Period = 9;	                      //ARR寄存器的值
    	TIM_TimeBaseStructure.TIM_Prescaler = 7199;	                  //PSC分频的值
    	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;   //向上计数
    	TIM_TimeBaseStructure.TIM_RepetitionCounter=0;                //重复计数器为0
    	TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
    	
    	/*--------------------输出比较结构体初始化-------------------*/
    	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;             //输出模式:PWM1
    	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
    	TIM_OCInitStructure.TIM_Pulse = 4;			                  //设置占空比
    	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;     //有效电平
    	TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;  //空闲时比较输出状态
    	TIM_OC1Init(TIM1, &TIM_OCInitStructure);
    
    	//4.使能,此处使能为将内部时钟作为TIM1时钟源的使能
    	TIM_Cmd(TIM1, ENABLE);									      //使能计数器
    	TIM_CtrlPWMOutputs(TIM1, ENABLE);				              //使能输出通道
    }
    

    说明:ARR寄存器与PSC寄存器都是从0开始计数,所以值要减一。

    PWM波频率=TIM_CLK/{(ARR+1)*(PSC+1)}

    其中TIM_CLK一般是APB2的频率,因为TIM1挂载在APB2中,APB2一般为72Mhz

    占空比=TIM_OCInitStructure.TIM_Pulse/(ARR+1)

    个人配置PWM波,一般如以下步骤

    1.确认PWM波的频率

    2.确认PWM波的精度(对应ARR寄存器)

    3.确认占空比,TIM_OCInitStructure.TIM_Pulse

    另外,有一个函数专门修改占空比(即修改TIM_OCInitStructure.TIM_Pulse的值),我之前不知道,还自己写了一个(大家避坑)

    void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1);

    5.说明

    除了本文章说明的寄存器,还有一些预装载函数,如TIM_OC1PreloadConfi();

    等,此函数对应CCMR->OC1PE,但是我暂时并不需要此功能,所以不做详细介绍。 

    官方说明如下:此外,对于时基单元,个别寄存器下有阴影,对应影子寄存器,也不作详细介绍。

    后续会出一篇PWM波控制电调的文章。

    参考文献有《STM32F10x-中文参考手册》《STM32库开发实战指南——基于野火指南者开发板》

    展开全文
  • 使用到STM32高级定时器TIM1的通道1和互补通道,电机的驱动模式采用单极模式,即驱动信号为1路的PWM,一路高电平,且这两种信号通过按钮可以交替实现电机的转向。
  • STM32使用定时器输出pwm到指定io口
  • STM32F407-高级定时器PWM输出功能

    注:1、根据数据手册初始化相应的GPIO和引脚通道。

            2、PWM的周期=((Prescaler+1)*(Period+1))/168000000,修改Period改变PWM的周期,Prescaler固定为167。

            3、RepetitionCounter为重复计数器寄存器的值,当此值为N时,那么更新事件将在定时器发生N+1次上溢或下溢时发生。

            4、OCPolarity为输出比较极性,也就是设置比较输出的有效电平。

            5、PWM模式1:向上计数时,CNT<CCRx为有效电平;向下计数时,CNT>CCRx为有效电平。

                  PWM模式2:向上计数时,CNT>CCRx为有效电平;向下计数时,CNT<CCRx为有效电平。

            6、通过__HAL_TIM_SET_COMPARE(__HANDLE__, __CHANNEL__, __COMPARE__)修改占空比。

    展开全文
  • stm32高级定时器输出PWM问题

    千次阅读 多人点赞 2021-03-29 09:11:47
    高级定时器没有输出PWM有以下几个方面: 如果采用更新中断翻转电平输出PWM,那么需要检查是否进入更新中断、中断配置是否配置正确和外设时钟是否正常打开; 如果使用PWM模式,一般出现在IO复用功能和重映射上。...

    高级定时器没有输出PWM有以下几个方面:

    • 如果采用更新中断翻转电平输出PWM,那么需要检查是否进入更新中断、中断配置是否配置正确和外设时钟是否正常打开;
    • 如果使用PWM模式,一般出现在IO复用功能和重映射上。如果没有使用IO的复用功能,那么它是不可能被定时器外设所驱动的。而如果你的IO不是该定时器默认的输出IO,那么就需要进行重映射。F1和F4的重映射机制如下:

    STM32F1

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);    // 开启复用时钟
    GPIO_PinRemapConfig(GPIO_FullRemap_TIM2, ENABLE);       // 开启TIM2全部重映射

    STM32F4

    GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_TIIM4);

    对比了F1和F4的重映射,可以看出F4的重映射直接与GPIO绑定,并且不需要开启外设时钟。但是F1重映射分为部分映射,全映射,还可能部分映射2

    如何确定这些映射对应哪些引脚?

    这时,我们应该打开相应的参考手册,找到GPIO这个章节,AFIO小节,找到定时器部分,可以查看所有定时器的IO映射关系。

    从图中可以看出:

    1)如果不开启重映射(没有重映射),定时器2默认输出 IO为:PA0、PA1、PA2、PA3。2)部分重映射1 :PA15、PB3、PA2、PA3。3)部分重映射2:PA0、PA1、PB10、PB11。4)完全重映射:PA15、PB3、PB10、PB11。从中我们也可以看到另一坑,那就是可能端口换了,而你的时钟并打开,导致初始化失败。
    
    • 高级定时器的坑

    1. 如果想要高级定时器输出脉冲,在配置高级定时器时增加一条语句
    TIM_CtrlPWMOutputs(TIM8, ENABLE);
    如果没有此函数,高级定时器的PWM功能是无法正常输出的。接下来测试做一下测试,使用相同的初始化函数,参数传递一样的情况下,定时器8可以正常输出,而定时器1却无法输出,这是怎么回事?在认真的。经过多方检查,一步一步的排查,最后发现是:把串口初始化函数屏蔽了。试了之后,发现定时器真的有输出了。
    2. 为什么串口还能干扰到定时器的输出?
        1. 这个时候就要说一说我们的栈了,关于栈的话题,基本上都是栈溢出,但是事实上,还有一个容易忽视的话题,栈值不确定。
        2. 调用一个函数时会进行压栈操作(用于保存寄存器的值),同时如果函数有局部变量,也可能会从栈中自动分配内存。

    因为局部变量用完就销毁,不会占用RAM资源,所以很多时候我们会选择局部变量。

    在使用局部变量时,如果使用不规范就会导致问题的发生。

    3. 现在解释一下,为什么串口会影响高级定时器的输出,而其他普通定时器并没有受影响?
       当串口函数执行时,使用的栈空间比较大,而在定时器函数执行时,刚好使用了这部分已被修改的栈空间,并且使用时没有初始化它,导致出现了问题。

    那为什么屏蔽了串口就没有问题?

    那是单片机开始运行时,__main函数会将栈空间全部清0,如果不运行串口函数,那么栈中的脏数据就不会很多,那么定时器函数的局部变量即使不初始化,也可认为是0,而正是定时器需要的默认值。

    那普通定时器什么不会被影响?拿TIM_TimeBaseInitTypeDef 结构体来举例。

    基本定时器一般会初始化这几个变量,但是你查看该结构体的定义时你会发现:

    该结构体还有一个变量是专为高级定时器准备的,你并没有对它进行初始化,此时它可能是任何值,并会直接赋值给高级定时器的寄存器中。

    所以为了解决这个问题,有两个方法。

    1. 使用库函数提前初始化局部变量:


    2. 直接在初始化时,将结构体成员变量都初始化一遍,确定没有任何一个遗漏:


       推荐使用第二种办法,这样高级定时器和普通定时器的代码可以统一,也能更直观的看出函数提供的功能。

    展开全文
  • STM32F4的定时器4输出4 路PWM波(寄存器版)
  • STM32定时器PWM输出

    2021-07-24 13:49:26
    对于stm32f103系列单片机,其定时器是一个通过可编程预分频器驱动的,16位自动装载计数器。 可编程预分频器驱动 计数器是16位的 自动装载 二、STM32中的定时器 定时器种类 捕获/比较通道 互补输出 特殊应用...
  • stm32高级定时器实现pwm互补输出

    千次阅读 2022-05-13 21:18:46
    stm32设备一般都有很多类型的定时器,常见的有systick timer、基本定时器、通用定时器高级定时器、看门狗定时器、RTC等等,本文简单介绍高级定时器是如何实现pwm互补输出。 详细 我这里使用的device是stm32f103rc...
  • 使用STM32高级定时器(TIM8)PWM互补通道输出PWM
  • STM32定时器学习-PWM输出

    千次阅读 2022-03-03 10:57:10
    基本定时器 最基础功能定时,两个基础定时器TM6和TM7,基本定时器时钟源只来自内部时钟。 如果我们想要一个1s的定时,那么我们应该怎么设置定时器呢?... uint32_t Period; // 定时器周期 uint16_t ClockDi
  • STM32CubeMX之定时器PWM输出

    千次阅读 2022-01-06 19:53:59
    STM32CubeMX之定时器PWM输出   脉冲宽度调制模式(PWM)可以产生一个由TIMx_ARR寄存器确定频率、由TIMx_CCRx寄存器确定占空比的信号。   本示例实现 IO 输出模式–PWM 波形输出。 以 LED 驱动为例, 使用定时器...
  • STM32定时器2PWM输出

    2019-08-12 11:56:51
    pwm输出实验 经过验证 TIM2定时器输出 输出4通道 通道1 PA0 通道2 PA1 通道3 PA2 通道4 PA3 可通过TIM_SetCompare1(TIM1, PWM);对PA1进行输出PWM 谢谢
  • STM32高级定时器PWM输出方式说明

    千次阅读 2019-05-07 14:03:06
    高级定时器1有5种计数模式:TIM_CounterMode_Up、TIM_CounterMode_DownTIM_CounterMode_CenterAligned1TIM_CounterMode_CenterAligned2TIM_CounterMode_CenterAligned3 PWM输出有2种模式:TIM_OCMode_PWM1、TIM_...
  • PWM输出 脉冲宽度调制模式可以生成一个信号,该信号频率由TIMx_ARR自动重载寄存器值决定,其占空比则由TIMx_CCRx捕获比较寄存器值决定。 通过向TIMx_CCMRx寄存器中的OCxM位写入110(PWM模式1)或111(PWM模式2)...
  • STM32高级定时器输出多路互补PWM

    千次阅读 2021-12-01 10:53:14
    STM32的两个高级定时器TIM1和TIM8都可以输出互补PWM,但是每个定时器只能输出三路互补PWM,本文使用TIM8同时输出三路互补PWM
  • STM32定时器PWM 输出

    千次阅读 2021-06-28 10:30:35
    26.1 关于 PWM 26.1.1 PWM 介绍 PWM(Pulse Width Modulation,脉冲宽度调制)。是一种利用微处理器的数字输出来对模拟电路进行控制的技术,广泛应用在测量、通信、功率控制等诸多领域。 举个最常见的例子,利用PWM...
  • 1.STM32向上计数模式产生占空比不变任意相位PWM 2.STM32中央对齐模式输出任意相位占空比移相全桥PWM
  • 目录(资料下载看最后)一、PWM简介二、硬件部分三、软件部分1. PWM初始化 pwm.c2. PWM初始化pwm.h3. 电机控制motor.c4. 电机控制motor.h5. 备注三、参考资料四、资料下载 一、PWM简介 简单来说,存在一个计数器,...
  • STM32定时器输出pwm

    千次阅读 2022-03-24 17:33:09
    对于STM32定时器输出PWM波需要了解定时器的基本使用方法和pwm的基本原理。这里使用STM32定时器3输出PWM波。 1.什么是PWM波 1.我们都知道单片机的引脚可以输出高低两种电平,高电平称之为1,而低电平称之为0;而所谓...
  • stm32配置PWM(标准库)
  • STM32F407 高级定时器配置像普通定时器输出PWM波 配置
  • 这个模式的特点是4个通道的输出周期频率是一样的.. 频率周期由 预装载寄存器 ARR 的大小确定. Cubmx中叫Counter Period … 这个值越大输出频率越低. 但是这个模式有个特点是, 每个通道的初相位可以通过各通道的CCRx...
  • STM32高级定时器1 库函数版本,针对可调PWM占空比,互补设置,死区时间的计算和设置,PWM1和PWM2模式的区别。对初学者有一定的帮助,不用去网上到处找资料来配置,和计算。
  • STM32高级定时器TIM1输出单个pwm和互补pwm
  • STM32通用定时器PWM输出

    千次阅读 2020-08-16 11:50:35
    ARR寄存器确定频率、TIMx_CCRx寄存器确定占空比的信号,在TIMx_CCMRx寄存器中的OCxM位写入‘110’(PWM模式1)或‘111’(PWM模式2),能够独立设置每个OCx输出通道产生一路PWM,下图以通道1为例。设置TIMx_CCMRx...
  • STM32CubeMX调试定时器PWM输出

    千次阅读 2020-04-09 17:17:05
    芯片型号:STM32F303CB 1.设置RCC,如下图 设置高速外部时钟HSE,选择外部时钟源 2.配置时钟树 3,设置定时器 1.选择TIM2 2.设置定时器市中院为内部时钟源 3.设置定时器CH2为PWM模式 4.可自行选择是否...
  • 原理:定时器PWM输出到蜂鸣器,通过改变定时器重装值,改变频率,从而改变音频,我采用stm32F407zet6,蜂鸣器接在PA8,如果你的不是在TIM_Beep_Control_Init()改io 使用实例: int main(void) { TIM_Beep_Control_...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 10,394
精华内容 4,157
关键字:

stm32高级定时器pwm输出