stm32高级定时器输出PWM问题

高级定时器没有输出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. 直接在初始化时,将结构体成员变量都初始化一遍,确定没有任何一个遗漏:


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

  • 41
    点赞
  • 172
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值