打印
[应用相关]

STM32 定时器单脉冲模式的使用记录

[复制链接]
1090|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tpgf|  楼主 | 2023-11-15 09:45 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
一、我要解决的问题
我的需求
需要单片机几乎同时在A,B,C 三个IO 分别输出T1,T2,T3 时长的高电平,时间结束后,恢复低电平。

初步思路
面对这个需求,我第一时间想到的是用三个定时器,分别设置T1,T2,T3 时间的定时,定时结束之后,在中断处理函数,将对应的IO 拉低,但是这个做法有几点不好:

产生了很多中断。
如果程序有更高级的中断在响应,当前中断会得不到及时响应,影响时间的精度。
程序结构比较分散。
解决办法
重新研究了一次定时器的功能,发现定时器的pwm 单脉冲功能,能完美解决这个问题。

二、定时器 pwm
先来整理一下普通的 定时器 pwm 功能的相关知识点。下面默认以计数器向上计数为例说明。

2.1 定时器是如何产生pwm的?

图1

介绍一个pwm信号产生的过程

计时器从0 开始计数,在达到CCRx 值之前,输出口维持初始电平。
在计数值达到CCRx 时,电平翻转。
在计数值到达ARR 值时,电平再翻转(恢复初始电平),计数值复位为0。重新回到第1步。
上面流程循环执行,产生连续的pwm 波形。

2.2 几个重要的参数
2.2.1 预分频器(PSC)
值的范围是0 - 65535。定时器计数频率 = 定时器时钟频率/ ( PSC + 1)。

假设定时器的时钟频率的64M,PSC 设置为63,那么定时器计数频率是1MHZ,也就是每1us,计数值加1。

2.2.2 周期(Counter Period)
pwm 周期 = (ARR + 1)/ 定时器计数频率。

2.2.3 有效电平(CH Polarity)
可以设置为 High 或 Low。有效电平的影响,参考下面的PWM1 和PWM2 模式。

2.2.4 PWM1 和 PWM2 的区别
                      CNT < CCRx        CNT > CCRx
PWM模式1                  有效电平               无效电平
pwm 模式2          无效电平           有效电平
三、pwm 输出的特例:单脉冲输出
3.1 简介
单脉冲输出,就是只有一个输出周期的pwm。当计数器向上计数时,计数值到ARR时,计数器自动停止。当计数器向下计数时,计数值到0时,计数器自动停止。



图2

3.2 如何配置单脉冲模式
配置 TIMx_CR1 的OPM bit 为1,进入one-pulse mode。使用Cubemx 配置定时器时,勾选One Pulse Mode 前面的勾。



图3

3.3 如何使用单脉冲模式
单脉冲模式,分成两个阶段:Delay 阶段,脉冲输出阶段。

uint16_t pulse_delay = 50;
uint16_t pulse_width = 1000;
__HAL_TIM_SET_AUTORELOAD( &htim16, pulse_delay + pulse_width - 2 );
__HAL_TIM_SET_COMPARE( &htim16, TIM_CHANNEL_1, pulse_delay - 1 );
HAL_TIM_PWM_Start( &htim16, TIM_CHANNEL_1);


调用 __HAL_TIM_SET_AUTORELOAD 设置ARR 寄存器值,设置整个周期的长度。

调用 __HAL_TIM_SET_COMPARE 设置CCR1值,设置Delay 阶段的时间

四、我遇到的问题
4.1 问题描述
输出单脉冲信号之后,切换状态输出pwm,无法正常输出。步骤如下:

先在TIM_CHANNEL_1 输出 常规pwm 波形,pwm 输出正常。
然后在TIM_CHANNEL_1 输出单脉冲信号,单脉冲输出正常。
再在TIM_CHANNEL_1 输出常规pwm 波形,无法输出pwm 信号。
4.2 解决步骤
4.2.1 重新初始化定时器
每次输出pwm 和单脉冲信号时,都重新完整初始化一次定时器,问题依然存在。

4.2.2 清空单脉冲配置位
配置输出pwm 信号之前,调用以下函数,复位单脉冲配置的状态

HAL_TIM_OnePulse_DeInit( &htim16 );
HAL_TIM_PWM_DeInit( &htim16 );


4.2.3 逐个寄存器比较定时器的配置
每次配置输出pwm 之前,打印一次当前定时器的配置(htim16. Instance 里面的各个成员函数),通过比较,发现 htim16.Instance->DMAR 这个参数被修改了。执行如下代码,问题解决:

HAL_TIM_OnePulse_DeInit( &htim16 );
HAL_TIM_PWM_DeInit( &htim16 );
htim16.Instance->DMAR = 0x00;


检查了一遍代码,无论是配置单脉冲输出模式,还是pwm 输出模式,都没配置dma 功能。但是在输出单脉冲信号之后,切换到pwm 模式,这个DMAR 寄存器的值就被改变了,暂时没找到原因。
————————————————
版权声明:本文为CSDN博主「gdut_llkkyy」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/gdut_liujiangyi/article/details/128151711

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2028

主题

15904

帖子

14

粉丝