打印
[其他]

MM32F5270定时器单脉冲输出

[复制链接]
325|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
MM32F5270定时器单脉冲输出

一.单脉冲输出

定时器单脉冲输出是比较输出应用中的一种模式,所谓的单脉冲就是通过配置定时器使其在一个可控延时后,产生一个脉宽可控的脉冲。

单脉冲模式(One Pulse Mode)下,计数器响应一个激励,产生一个脉宽可调的脉冲。配置 TIMx_CR1 寄存器的OPM=1,选择单脉冲模式,触发信号有效沿或配置 CEN=1 都可以启动计数器,直到下个更新事件发生或配置 CEN=0 时,计数器停止计数。

产生脉冲的必要条件是比较值与计数器的初始值不同,所以在计数器启动之前的必要配置如下:
  • 递增计数方式:计数器 CNT < CCRx ≤ ARR
  • 递减计数方式:计数器 CNT > CCRx


例如,在 TI2 检测到上升沿,延迟 tDELAY 之后,在 OC2 上产生一个长度为 tPULSE 的正脉冲。配置 TI2FP2 作为触发源:
  • 配置 TIMx_CCMR1 寄存器中的 CC2S = 01,将 TI2FP2 映射到 TI2。
  • 配置 TIMx_CCER 寄存器中的 CC2P = 0,检测 TI2FP2 的上升沿。
  • 配置 TIMx_SMCR 寄存器中的 TS = 110, TI2FP2 作为从模式控制器的触发(TRGI)。
  • 配置 TIMx_SMCR 寄存器中的 SMS = 110,选择触发模式, TI2FP2 使能计数器工作。

OPM 的波形由 TIMx_ARR 和 TIMx_CCR1 决定(要考虑时钟频率和计数器预分频器):由 TIMx_CCR1寄存器的值和 CNT 初始值决定触发信号与单脉冲开始之间的延迟 tDELAY, TIMx_ARR - TIMx_CCR1 的值为脉冲的宽度 tPULSE。

下面是一个产生负脉冲的例子,即发生比较匹配时产生从 1 到 0 的波形,计数器达到预装载值时产生一个从 0 到 1 的波形:

  • 配置 TIMx_CCMR1 寄存器 OC1M = 111,选择 PWM 模式 2。
  • 配置 TIMx_CCER 寄存器 CC1P = 1,输出低电平有效。
  • 配置 TIMx_CCMR1 中 OC1PE = 1 和 TIMx_CR1 寄存器中 ARPE=1,使能预装载寄存器。
  • 配置 TIMx_CCR1 寄存器和 TIMx_ARR 寄存器。
  • 配置 TIMx_EGR 寄存器 UG=1 产生一个更新事件。
  • 等待在 TI2 上的一个外部触发事件。

此例中, TIMx_CR1 寄存器中的 DIR=0、 CMS=0、 OPM= 1,在下一个更新事件(当计数器从自动装载值返回到 0)时停止计数。

二. 实验
2.1 实验说明
配置TIM1_CH1单脉冲输出,TIM1_CH2输入捕获,TIM1从模式选择触发模式,TIM3_CH1输出PWM,触发TIM1计数器开始计数。当TIM1_CH2捕捉到有效信号时,TIM1计数器开始计数,按照配置好的脉宽,TIM1_CH1输出一个脉冲信号。

2.2 程序编写
程序部分参考MM32提供的例程,相关代码在此基础上更改。

2.21 GPIO初始化
配置PA8作为TIM1_CH1、PA9作为TIM1_CH2
void TIM1_GPIO_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;
    RCC_GPIO_ClockCmd(GPIOA, ENABLE);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_1);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1);

    GPIO_InitStruct.GPIO_Pin     = GPIO_Pin_8;
    GPIO_InitStruct.GPIO_Mode    = GPIO_Mode_AF_PP;
    GPIO_InitStruct.GPIO_Speed   = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStruct);
    GPIO_InitStruct.GPIO_Pin     = GPIO_Pin_9;
    GPIO_InitStruct.GPIO_Mode    = GPIO_Mode_IPD;
    GPIO_InitStruct.GPIO_Speed   = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStruct);
}

同样的,配置PB4作为TIM3_CH1,代码略。

2.22 TIM1初始化
程序中调用TIM1_Monopulse_Init()函数配置TIM1的自动预装载值为(10000-1),预分频器的值为(SystemCoreClock / 1000000 - 1),即TIM1定时器发生更新事件的周期为10ms。
TIM1_Monopulse_Init(10000 - 1, SystemCoreClock / 1000000 - 1);

在该函数中配置了TIM1_CH1输出PWM,输出信号极性为高电平有效,脉冲宽度为50%,使能TIM1单脉冲输出模式。配置TIM1_CH2输入捕获,从模式触发源选择TI2FP2作为计数器的触发输入,在信号的上升沿启动。详见函数定义如下:
void TIM1_Monopulse_Init(u16 arr, u16 psc)  
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStruct;
    TIM_OCInitTypeDef  TIM_OCInitStruct;
    TIM_ICInitTypeDef  TIM_ICInitStruct;

    RCC_APB2PeriphClockCmd(RCC_APB2ENR_TIM1, ENABLE);
    TIM_DeInit(TIM1);
    TIM_TimeBaseStructInit(&TIM_TimeBaseStruct);
    TIM_TimeBaseStruct.TIM_Period = arr;
    TIM_TimeBaseStruct.TIM_Prescaler = psc;
    TIM_TimeBaseStruct.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseStruct.TIM_RepetitionCounter = 0;
    TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStruct);

    TIM_OCStructInit(&TIM_OCInitStruct);
    TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM2;
    TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStruct.TIM_Pulse = arr / 2;
    TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OCInitStruct.TIM_OCIdleState = TIM_OCIdleState_Reset;
    TIM_OC1Init(TIM1, &TIM_OCInitStruct);  
    TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
    TIM_ICStructInit(&TIM_ICInitStruct);

    TIM_ICInitStruct.TIM_Channel     = TIM_Channel_2;
    TIM_ICInitStruct.TIM_ICPolarity  = TIM_ICPolarity_Rising;  
    TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI;
    TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;
    TIM_ICInitStruct.TIM_ICFilter    = 0x0;
    TIM_ICInit(TIM1, &TIM_ICInitStruct);  
    TIM_ARRPreloadConfig(TIM1, ENABLE);
    TIM_SelectOnePulseMode(TIM1, TIM_OPMode_Single);
    TIM_SelectInputTrigger(TIM1, TIM_TS_TI2FP2);
    TIM_SelectSlaveMode(TIM1, TIM_SlaveMode_Trigger);
    TIM_SetCounter(TIM1, 0);
    TIM_CtrlPWMOutputs(TIM1, ENABLE);
    TIM_Cmd(TIM1, ENABLE);
}

2.23 TIM3初始化
程序中调用TIM3_PWM_Init()函数配置TIM3的自动预装载值为(10000-1),预分频器的值为(SystemCoreClock / 1000000 - 1),即TIM3定时器发生更新事件的周期为20ms。
TIM3_PWM_Init(10000 - 1, SystemCoreClock / 1000000 - 1);

在该函数中配置了TIM3_CH1输出PWM,输出信号极性为高电平有效,脉冲宽度为25%。详见函数定义如下:
void TIM3_PWM_Init(u16 arr, u16 psc)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStruct;
    TIM_OCInitTypeDef  TIM_OCInitStruct;
    RCC_APB1PeriphClockCmd(RCC_APB1ENR_TIM3, ENABLE);
    TIM_TimeBaseStructInit(&TIM_TimeBaseStruct);
    TIM_TimeBaseStruct.TIM_Period = arr;
    TIM_TimeBaseStruct.TIM_Prescaler = psc;
    TIM_TimeBaseStruct.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseStruct.TIM_RepetitionCounter = 0;
    TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStruct);
    TIM_OCStructInit(&TIM_OCInitStruct);
    TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM2;
    TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStruct.TIM_Pulse = (arr / 4) * 3;
    TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OC1Init(TIM3, &TIM_OCInitStruct);
    TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);
    TIM_ARRPreloadConfig(TIM3, ENABLE);  
    TIM_SetCounter(TIM3, 0);  
    TIM_Cmd(TIM3, ENABLE);
}

按照上述配置,PB4(TIM3_CH1)作为PA9(TIM1_CH2)的输入端,当PA9捕捉到PB4输出的PWM的上升沿时,TIM1计数器启动计数,控制延时为5ms,PA8输出一个脉宽为5ms的脉冲。

2.3 下载验证
连接PA9(TIM1_CH2)和PB4(TIM3_CH1),使用逻辑分析仪连接PA8和PA9,运行程序观测波形如下:


其中,通道8连接PA8,通道9连接PA9:


测量两段间距均为5ms,运行结果和上述配置一致。


使用特权

评论回复
沙发
tpgf| | 2023-2-3 11:25 | 只看该作者
估计单脉冲输出是定时器应用的一种比较简单的模式了

使用特权

评论回复
板凳
qcliu| | 2023-2-3 11:49 | 只看该作者
单片机引脚输出脉冲的极限收到什么参数的限制呢

使用特权

评论回复
地板
drer| | 2023-2-3 11:55 | 只看该作者
单脉冲输出的话  需要注意引脚上的负载吗

使用特权

评论回复
5
coshi| | 2023-2-3 12:07 | 只看该作者
计数器需要响应的这个激励 可以是外部激励或者是内部激励吗

使用特权

评论回复
6
kxsi| | 2023-2-3 12:15 | 只看该作者
单脉冲输出模式允许定时器响应多个激励吗

使用特权

评论回复
7
wiba| | 2023-2-3 13:10 | 只看该作者
单脉冲模式的时候定时器只能使用计数模式吗

使用特权

评论回复
8
MindMotion|  楼主 | 2023-2-21 14:07 | 只看该作者
qcliu 发表于 2023-2-3 11:49
单片机引脚输出脉冲的极限收到什么参数的限制呢

主要是时钟、ARR、PSC配置
1)单片机引脚输出脉冲的频率受到最高输出速度的限制。
2)产生脉冲的必要条件是比较器与计数器的初始值不同。

使用特权

评论回复
9
MindMotion|  楼主 | 2023-2-21 14:08 | 只看该作者
drer 发表于 2023-2-3 11:55
单脉冲输出的话  需要注意引脚上的负载吗

一般适用于通过脉冲信号控制的负载,注意该单脉冲信号(正脉冲、负脉冲)对负载作用的影响,是否与预期效果一致。

使用特权

评论回复
10
MindMotion|  楼主 | 2023-2-21 14:08 | 只看该作者
coshi 发表于 2023-2-3 12:07
计数器需要响应的这个激励 可以是外部激励或者是内部激励吗

可以是外部激励或者是内部激励。

使用特权

评论回复
11
MindMotion|  楼主 | 2023-2-21 14:08 | 只看该作者
kxsi 发表于 2023-2-3 12:15
单脉冲输出模式允许定时器响应多个激励吗

触发信号有效沿都可以启动计数器,只要有触发信号就有单脉冲输出。
如果多个激励满足有效触发信号则是允许的,否则不允许。

使用特权

评论回复
12
MindMotion|  楼主 | 2023-2-21 14:08 | 只看该作者
wiba 发表于 2023-2-3 13:10
单脉冲模式的时候定时器只能使用计数模式吗

对定时器的配置是比较输出模式。

使用特权

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

本版积分规则

认证:上海灵动微电子股份有限公司
简介:上海灵动微电子股份有限公司成立于 2011 年,是中国本土通用 32 位 MCU 产品及解决方案供应商。 灵动股份的 MCU 产品以 MM32 为标识,基于 Arm Cortex-M 系列内核,自主研发软硬件和生态系统。目前已量产近 300 多款型号,累计交付超 4 亿颗,在本土通用 32 位 MCU 公司中位居前列。

67

主题

88

帖子

4

粉丝