打印
[N32G43x]

如何使用定时器输出指定数量的脉冲

[复制链接]
561|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
sy12138|  楼主 | 2022-12-30 10:15 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
#每日话题# #技术资源#

目前我们有两种方式来实现定时器输出指定数量的脉冲
方法1:定时器级联
方法2:高级定时器
接下来给大家简单讲一下两种方式具体的实现原理

定时器级联:这里我们用到的是TIM2和TIM3,是两个通用定时器;然后我们TIM2从模式配置为外部时钟模式1,触发源选择TIM3,即利用TIM3来驱动TIM2,TIM3每更新一次,TIM2计数器+1,所以TIM3输出PWM的个数 = TIM2的计数值,这里如果我们选择输出10个PWM,就需要配置TIM2_ARR = 10-1,然后使能TIM2的更新中断,当TIM3输出指定数量的PWM之后,进入TIM2更新中断,在中断中关闭TIM3,停止PWM输出。
void TIM3_Master_Config(void)
{
    GPIO_InitType GPIO_InitStructure;
    TIM_TimeBaseInitType TIM_TimeBaseStructure;
    OCInitType TIM_OCInitStructure;

    /** RCC Config */
    RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_AFIO | RCC_APB2_PERIPH_GPIOA, ENABLE);
    RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_TIM3, ENABLE);

    /** GPIO Config */
    GPIO_InitStruct(&GPIO_InitStructure);
    GPIO_InitStructure.Pin            = GPIO_PIN_6 ;
    GPIO_InitStructure.GPIO_Mode      = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Alternate = GPIO_AF2_TIM3;
    GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);

    /** Time Base Config */
    TIM_InitTimBaseStruct(&TIM_TimeBaseStructure);
    TIM_TimeBaseStructure.Period    = 1000 - 1;
    TIM_TimeBaseStructure.Prescaler = 108 - 1;
    TIM_TimeBaseStructure.CntMode   = TIM_CNT_MODE_UP;
    TIM_TimeBaseStructure.ClkDiv    = TIM_CLK_DIV1;
    TIM_InitTimeBase(TIM3, &TIM_TimeBaseStructure);

    /** PWM Config */
    TIM_InitOcStruct(&TIM_OCInitStructure);
    TIM_OCInitStructure.OcMode       = TIM_OCMODE_PWM2;
    TIM_OCInitStructure.OutputState  = TIM_OUTPUT_STATE_ENABLE;
    TIM_OCInitStructure.Pulse        = 500;
    TIM_OCInitStructure.OcPolarity   = TIM_OC_POLARITY_LOW;
    TIM_InitOc1(TIM3, &TIM_OCInitStructure);

    TIM_ConfigOc1Preload(TIM3, TIM_OC_PRE_LOAD_ENABLE);
    TIM_ConfigArPreload(TIM3, ENABLE);

    TIM_SelectOutputTrig(TIM3, TIM_TRGO_SRC_OC1REF);               // 选择OC1REF作为主定时器的TRGO信号
}
void TIM2_Slave_Config(uint32_t countpluse)
{
    NVIC_InitType NVIC_InitStructure;
    TIM_TimeBaseInitType TIM_TimeBaseStructure;

    /** RCC Config */
    RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_TIM2, ENABLE);

    /** NVIC Config */
    NVIC_InitStructure.NVIC_IRQChannel                   = TIM2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    /** Time Base Config */
    TIM_InitTimBaseStruct(&TIM_TimeBaseStructure);
    TIM_TimeBaseStructure.Period    = (countpluse - 1);
    TIM_TimeBaseStructure.Prescaler = 0;
    TIM_TimeBaseStructure.CntMode   = TIM_CNT_MODE_UP;
    TIM_TimeBaseStructure.ClkDiv    = TIM_CLK_DIV1;
    TIM_InitTimeBase(TIM2, &TIM_TimeBaseStructure);

    TIM_SelectInputTrig(TIM2, TIM_TRIG_SEL_IN_TR2);
    TIM_SelectSlaveMode(TIM2, TIM_SLAVE_MODE_EXT1);

    TIM_ConfigInt(TIM2, TIM_INT_UPDATE, DISABLE);
    TIM_ClearFlag(TIM2, TIM_FLAG_UPDATE);
    TIM_ConfigInt(TIM2, TIM_INT_UPDATE, ENABLE);

    TIM_Enable(TIM2, ENABLE);
}
TIM_Enable(TIM3, ENABLE);
void TIM2_IRQHandler(void)
{
        if(TIM_GetIntStatus(TIM2, TIM_INT_UPDATE) != RESET)
        {
                TIM_Enable(TIM3, DISABLE);
                TIM_ConfigInt(TIM2, TIM_INT_UPDATE, DISABLE);
                  TIM_ClrIntPendingBit(TIM2, TIM_INT_UPDATE);
        }
}
然后我们来看一下TIM3输出的PWM波形:

其实定时器级联还有一种配置也可以达到这种效果,我们主定时器TIM3选择更新事件触发,TIM2从模式选择门控模式;

接下来讲一下第二种实现方式,高级定时器
高级定时器:N32高级定时器独有一个重复计数器的模块,每次计数器更新都会让重复计数器-1,当重复计数器=0时,触发更新事件,在更新中断中关闭定时器,停止PWM输出。
void TIM1_PWM_Config(uint8_t num)
{
    GPIO_InitType GPIO_InitStructure;
    NVIC_InitType NVIC_InitStructure;
    TIM_TimeBaseInitType TIM_TimeBaseStructure;
    OCInitType TIM_OCInitStructure;

    /** RCC Config */
    RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_AFIO | RCC_APB2_PERIPH_GPIOA, ENABLE);
    RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_TIM1, ENABLE);

    TIM_EnableCtrlPwmOutputs(TIM1, ENABLE);

    /** GPIO Config */
    GPIO_InitStruct(&GPIO_InitStructure);
    GPIO_InitStructure.Pin            = GPIO_PIN_8;
    GPIO_InitStructure.GPIO_Mode      = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Alternate = GPIO_AF2_TIM1;
    GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);

    /** NVIC Config */
    NVIC_InitStructure.NVIC_IRQChannel                   = TIM1_UP_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    /** Time Base Config */
    TIM_InitTimBaseStruct(&TIM_TimeBaseStructure);
    TIM_TimeBaseStructure.Period    = 1000 - 1;
    TIM_TimeBaseStructure.Prescaler = 108 - 1;
    TIM_TimeBaseStructure.CntMode   = TIM_CNT_MODE_UP;
    TIM_TimeBaseStructure.ClkDiv    = TIM_CLK_DIV1;
    TIM_TimeBaseStructure.RepetCnt  = (num - 1);
    TIM_InitTimeBase(TIM1, &TIM_TimeBaseStructure);

    /** PWM Config */
    TIM_InitOcStruct(&TIM_OCInitStructure);
    TIM_OCInitStructure.OcMode       = TIM_OCMODE_PWM1;
    TIM_OCInitStructure.OutputState  = TIM_OUTPUT_STATE_ENABLE;
    TIM_OCInitStructure.Pulse        = 500;
    TIM_OCInitStructure.OcPolarity   = TIM_OC_POLARITY_LOW;
    TIM_OCInitStructure.OcIdleState  = TIM_OC_IDLE_STATE_SET;
    TIM_InitOc1(TIM1, &TIM_OCInitStructure);

    TIM_ConfigOc1Preload(TIM1, TIM_OC_PRE_LOAD_ENABLE);
    TIM_ConfigArPreload(TIM1, ENABLE);

    TIM_ConfigInt(TIM1, TIM_INT_UPDATE, DISABLE);
    TIM_ClearFlag(TIM1, TIM_FLAG_UPDATE);
    TIM_ConfigInt(TIM1, TIM_INT_UPDATE, ENABLE);

    TIM_Enable(TIM1, ENABLE);
}
void TIM1_UP_IRQHandler(void)
{
        if(TIM_GetIntStatus(TIM1, TIM_INT_UPDATE) != RESET)
        {
                TIM_Enable(TIM1, DISABLE);
                TIM_ConfigInt(TIM1, TIM_INT_UPDATE, DISABLE);
                TIM_ClrIntPendingBit(TIM1, TIM_INT_UPDATE);
        }
}
输出PWM波形展示:

使用特权

评论回复
沙发
zhouchen605768| | 2023-1-1 21:05 | 只看该作者
这种波形图是用逻辑分析仪抓出来的嘛

使用特权

评论回复
板凳
sy12138|  楼主 | 2023-1-3 09:47 | 只看该作者
zhouchen605768 发表于 2023-1-1 21:05
这种波形图是用逻辑分析仪抓出来的嘛

是的,用逻辑分析仪

使用特权

评论回复
地板
zhouchen605768| | 2023-1-4 22:02 | 只看该作者
sy12138 发表于 2023-1-3 09:47
是的,用逻辑分析仪

逻辑分析仪采样率可以推荐下不?就当前国民的MCU这块100M的采样率完全够用不?打算买一个逻辑分析仪

使用特权

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

本版积分规则

92

主题

404

帖子

15

粉丝