查看: 5670|回复: 9

[求助] RT1170的FLEXPWM输出固定脉冲数

[复制链接]

该用户从未签到

8

主题

38

帖子

0

中级会员

Rank: 3Rank: 3

积分
382
最后登录
2025-3-3
发表于 2021-8-26 14:34:47 | 显示全部楼层 |阅读模式
各位,我在使用RT1170的FLEXPWM外设的时候,希望输出固定PWM数目,我的方法是在比较中断里计数,到达期望值就停止,以此来实现输出固定PWM的目的,在测试中,发现输出第一次的时候没问题,后面再开始定时器的时候,发现其第一个脉冲的时间变多了。不知道这个应该怎么解决

第一次输出

第一次输出

第二次输出

第二次输出




回复

使用道具 举报

  • TA的每日心情
    慵懒
    21 小时前
  • 签到天数: 1883 天

    连续签到: 8 天

    [LV.Master]伴坛终老

    203

    主题

    3万

    帖子

    64

    超级版主

    Rank: 8Rank: 8

    积分
    112746
    最后登录
    2025-9-10
    发表于 2021-8-26 18:34:01 | 显示全部楼层
    你这个时间好短啊,是否可能是有些寄存器还没有复位呢?

    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    8

    主题

    38

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    382
    最后登录
    2025-3-3
     楼主| 发表于 2021-8-27 09:23:49 | 显示全部楼层
    stm1024 发表于 2021-8-26 18:34
    你这个时间好短啊,是否可能是有些寄存器还没有复位呢?

    我发现在使能OUTEN的时候,会拉高了他的电平,这导致了在启动定时器前就已经出现高电平,(在中断里我禁止了OUTEN和停止了定时器),有点像你说的上一次停止定时器时可能有些寄存器没复位。那些寄存器会对OUTEN有影响呢?
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    723

    主题

    6382

    帖子

    0

    超级版主

    Rank: 8Rank: 8

    积分
    25499
    最后登录
    2025-9-11
    发表于 2021-8-27 14:28:15 | 显示全部楼层
    emmmmmmmmmmm 发表于 2021-8-27 09:23
    我发现在使能OUTEN的时候,会拉高了他的电平,这导致了在启动定时器前就已经出现高电平,(在中断里我禁 ...

    建议你第二次尽量还是相关寄存器复位下,counter也可以清一下,然后再试试看。
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    8

    主题

    38

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    382
    最后登录
    2025-3-3
     楼主| 发表于 2021-8-27 16:03:49 | 显示全部楼层
    小恩GG 发表于 2021-8-27 14:28
    建议你第二次尽量还是相关寄存器复位下,counter也可以清一下,然后再试试看。 ...

    后面我把好多寄存器清0了,还是相同结果,能帮我看下代码有啥子问题吗?
    1. /*
    2. * Copyright (c) 2015, Freescale Semiconductor, Inc.
    3. * Copyright 2016-2017 NXP
    4. * All rights reserved.
    5. *
    6. * SPDX-License-Identifier: BSD-3-Clause
    7. */

    8. #include "fsl_debug_console.h"
    9. #include "pin_mux.h"
    10. #include "board.h"
    11. #include "fsl_pwm.h"

    12. #include "fsl_xbara.h"

    13. #include "fsl_iomuxc.h"
    14. #include "pin_mux.h"

    15. #include "fsl_edma.h"
    16. #include "fsl_dmamux.h"
    17. /*******************************************************************************
    18. * Definitions
    19. ******************************************************************************/

    20. #define PWM_SRC_CLK_FREQ       CLOCK_GetRootClockFreq(kCLOCK_Root_Bus)

    21. /*******************************************************************************
    22. * Prototypes
    23. ******************************************************************************/

    24. /*******************************************************************************
    25. * Variables
    26. ******************************************************************************/
    27. volatile uint32_t Target_PWM2_Module2A_number = 0;

    28. volatile uint32_t PWM2_Module2A_number = 0;
    29. /*******************************************************************************
    30. * Code
    31. ******************************************************************************/

    32. void PWM2_2_IRQHandler(void)
    33. {
    34.            PWM2->SM[kPWM_Module_2].STS = ((uint16_t)kPWM_CompareVal5Flag);
    35.            PWM2_Module2A_number++;
    36.                  if(PWM2_Module2A_number == Target_PWM2_Module2A_number)
    37.                  {
    38.                            PWM2->OUTEN  &= ~(kPWM_Control_Module_2 << 8 | kPWM_Control_Module_2 << 4);
    39.                            PWM_StopTimer(PWM2, kPWM_Control_Module_2);
    40.                  }
    41. }
    42. int pwmInit()
    43. {
    44.           pwm_config_t pwmConfig;
    45.           CLOCK_EnableClock(kCLOCK_Iomuxc);                                          /**< \brief 使能引脚开关时钟 */
    46.           /* 设置FLEXPWM的分频系数,模式 */
    47.     PWM_GetDefaultConfig(&pwmConfig);
    48.     pwmConfig.prescale = kPWM_Prescale_Divide_1;                               /**< \brief 1分频 240M/1 = 240MHZ */
    49.     pwmConfig.reloadLogic = kPWM_ReloadImmediate;                              /**< \brief 立即加载 */
    50.     pwmConfig.pairOperation   = kPWM_Independent;                              /**< \brief 独立模式 */
    51.     pwmConfig.enableDebugMode = true;       
    52.        
    53.                 IOMUXC_SetPinMux(IOMUXC_GPIO_AD_28_FLEXPWM2_PWM2_A, 0);         /**< \brief 初始化 STEP4 脉冲引脚 */
    54.                 IOMUXC_SetPinMux(IOMUXC_GPIO_AD_29_FLEXPWM2_PWM2_B, 0);         /**< \brief 初始化 STEP4 方向引脚 */
    55.                 GPIO_WritePinOutput(GPIO3, 27, 0);
    56.                 GPIO_WritePinOutput(GPIO3, 28, 0);
    57.                 if(PWM_Init(PWM2, kPWM_Module_2, &pwmConfig) == kStatus_Fail)
    58.                 {
    59.                                 return -1;
    60.                 }
    61.                 PWM2->SM[2].DISMAP[0]=0;               
    62.                
    63.                 return 0;
    64. }
    65. void set_pwm_out(uint16_t pulse, uint8_t duty)
    66. {
    67.           uint32_t pwmFrequencyInHz = 1000000;                            /**< \brief 1MHZ*/
    68.           pwm_signal_param_t pwmSignal[2];
    69.        
    70.                 PWM2_Module2A_number          = 0;
    71.                 Target_PWM2_Module2A_number   = pulse;                                       
    72.                 pwmSignal[0].pwmChannel       = kPWM_PwmA;
    73.                 pwmSignal[0].level            = kPWM_HighTrue;
    74.                 pwmSignal[0].dutyCyclePercent = duty;
    75.                 pwmSignal[1].pwmChannel       = kPWM_PwmB;
    76.                 pwmSignal[1].level            = kPWM_HighTrue;
    77.                 pwmSignal[1].dutyCyclePercent = duty;
    78.                 PWM_SetupPwm(PWM2, kPWM_Module_2, pwmSignal, 2, kPWM_EdgeAligned,
    79.                                          pwmFrequencyInHz,PWM_SRC_CLK_FREQ);                  /**< \brief OUTEN 写1电平会被拉高 */
    80.           PRINTF("VAL3=%d\n",PWM2->SM[2].VAL3);
    81.                 PWM_SetPwmLdok(PWM2, kPWM_Control_Module_2, true);
    82.           PRINTF("VAL5=%d\n",PWM2->SM[2].VAL5);
    83.           PRINTF("VAL5=%d\n",PWM2->SM[2].VAL1);
    84.                 PWM_EnableInterrupts(PWM2,kPWM_Module_2,kPWM_CompareVal5Flag);      /**< \brief 使能中断 */
    85.                 EnableIRQ(PWM2_2_IRQn);
    86.           PWM_StartTimer(PWM2, kPWM_Control_Module_2);
    87.        
    88. }
    89. /*!
    90. * @brief Main function
    91. */
    92. int main(void)
    93. {
    94.     /* Board pin, clock, debug console init */
    95.     BOARD_ConfigMPU();
    96.     BOARD_InitPins();
    97.     BOARD_BootClockRUN();
    98.     BOARD_InitDebugConsole();

    99.     /* Set the PWM Fault inputs to a low value */
    100.     XBARA_Init(XBARA1);
    101.     XBARA_SetSignalsConnection(XBARA1, kXBARA1_InputLogicHigh, kXBARA1_OutputFlexpwm1Fault0);
    102.     XBARA_SetSignalsConnection(XBARA1, kXBARA1_InputLogicHigh, kXBARA1_OutputFlexpwm1Fault1);
    103.     XBARA_SetSignalsConnection(XBARA1, kXBARA1_InputLogicHigh, kXBARA1_OutputFlexpwm1234Fault2);
    104.     XBARA_SetSignalsConnection(XBARA1, kXBARA1_InputLogicHigh, kXBARA1_OutputFlexpwm1234Fault3);
    105.           
    106.     PRINTF("FlexPWM driver example\n");
    107.     pwmInit();


    108.     while (1U)
    109.     {
    110.                           PRINTF("please input a key\n");
    111.                           GETCHAR();
    112.                           PWM2->SM[kPWM_Module_2].INIT = 0;
    113.                           PWM2->SM[kPWM_Module_2].CTRL2 = 0;
    114.                           PWM2->SM[kPWM_Module_2].CTRL = 0X400;
    115.                           PWM2->SM[kPWM_Module_2].VAL0 = 0;
    116.                           PWM2->SM[kPWM_Module_2].FRACVAL1 = 0;
    117.                           PWM2->SM[kPWM_Module_2].VAL1 = 0;
    118.                           PWM2->SM[kPWM_Module_2].FRACVAL2 = 0;
    119.                           PWM2->SM[kPWM_Module_2].VAL2 = 0;
    120.                           PWM2->SM[kPWM_Module_2].FRACVAL3 = 0;
    121.                           PWM2->SM[kPWM_Module_2].VAL3 = 0;
    122.                           PWM2->SM[kPWM_Module_2].FRACVAL4 = 0;
    123.                           PWM2->SM[kPWM_Module_2].VAL4 = 0;
    124.                           PWM2->SM[kPWM_Module_2].FRACVAL5 = 0;
    125.                           PWM2->SM[kPWM_Module_2].VAL5 = 0;
    126.                           PWM2->SM[kPWM_Module_2].FRCTRL = 0;
    127.                           PWM2->SM[kPWM_Module_2].OCTRL = 0;
    128.                           PWM2->SM[kPWM_Module_2].STS = 0xffff;           /**< \brief 清除中断标志 */
    129.                           PWM2->SM[kPWM_Module_2].INTEN = 0;
    130.                           PWM2->SM[kPWM_Module_2].DMAEN = 0;
    131.                                 PWM2->SM[kPWM_Module_2].TCTRL = 0;
    132.                                 PWM2->SM[kPWM_Module_2].DISMAP[0] = 0XFFFF;
    133.                                 PWM2->SM[kPWM_Module_2].DTCNT0 =0x7ff;
    134.                                 PWM2->SM[kPWM_Module_2].DTCNT1 =0x7ff;
    135.                                 PWM2->DTSRCSEL = 0;
    136.                                 PWM2->FCTRL = 0;
    137.                                 PWM2->FCTRL2 = 0;
    138.                                 PWM2->FFILT = 0;
    139.                                 PWM2->FFILT = 0;
    140.                                 PWM2->FSTS = 0;
    141.                                 PWM2->FTST = 0;
    142.                                 PWM2->MASK = 0;
    143.                                 PWM2->MCTRL = 0;
    144.                                 PWM2->MCTRL2 = 0;
    145.                                 PWM2->OUTEN = 0;
    146.                                 PWM2->SWCOUT = 0;
    147.                                 pwmInit();
    148.                           set_pwm_out(1000,80); /**< \brief 输出1000个PWM,占空比80%*/

    149.     }
    150. }
    复制代码
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    723

    主题

    6382

    帖子

    0

    超级版主

    Rank: 8Rank: 8

    积分
    25499
    最后登录
    2025-9-11
    发表于 2021-8-31 11:20:24 | 显示全部楼层
    你现在是输出脉冲个数都准确了,只是后面的再次发出的,第一次脉宽不对,是吧?
    你 GETCHAR();之后调用下PWM_Deinit试试。
    还有,我看你是用逻辑分析仪,你再用那个示波器抓两组波形出来看看,是否是毛刺导致的脉宽,还是真实的就这样。然后把示波器波形也贴出来。
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    8

    主题

    38

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    382
    最后登录
    2025-3-3
     楼主| 发表于 2021-9-1 10:21:59 | 显示全部楼层
    小恩GG 发表于 2021-8-31 11:20
    你现在是输出脉冲个数都准确了,只是后面的再次发出的,第一次脉宽不对,是吧?
    你 GETCHAR();之后调用下PW ...

    1、是的,脉冲个数是正确的,后面发出的脉冲第一次脉宽会多点
    2、用了PWM_Deint没有改善情况
    3、这个不是应该毛刺引起的,我在PWM_SetupPwm和PWM_StartTimer之间添加了PRINTF,第一个脉冲的就会增加几ms
    1.png

    回复 支持 反对

    使用道具 举报

    该用户从未签到

    8

    主题

    38

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    382
    最后登录
    2025-3-3
     楼主| 发表于 2021-9-1 10:29:07 | 显示全部楼层
    我怀疑是在中断里执行PWM_StopTimer语句前,计数器的值已经到了VAL1,重新从INIT值计数,这就导致此时的状态是高电平状态,下次开启OUTEN的时候就会拉高电平 3.png
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    723

    主题

    6382

    帖子

    0

    超级版主

    Rank: 8Rank: 8

    积分
    25499
    最后登录
    2025-9-11
    发表于 2021-9-1 14:30:23 | 显示全部楼层
    emmmmmmmmmmm 发表于 2021-9-1 10:29
    我怀疑是在中断里执行PWM_StopTimer语句前,计数器的值已经到了VAL1,重新从INIT值计数,这就导致此时的状态 ...

    你这样测试看看,就是关闭了timer,然后在下一次开启之前,直接开启OUTEN,看看对应的引脚是不是已经拉高了?
    如果是,那么要先想办法把这个状态给清成0再开启第二次的timer。
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    8

    主题

    38

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    382
    最后登录
    2025-3-3
     楼主| 发表于 2021-9-1 17:16:25 | 显示全部楼层
    小恩GG 发表于 2021-9-1 14:30
    你这样测试看看,就是关闭了timer,然后在下一次开启之前,直接开启OUTEN,看看对应的引脚是不是已经拉高 ...

    嗯,确实是来不及关闭定时器导致的,我将PWM2->OUTEN  &= ~(kPWM_Control_Module_2 << 8 | kPWM_Control_Module_2 << 4);注释掉或者将pwm_stoptimer放在OUTEN前执行,结果都正常。
    如果在停止定时器的时候,counter在VAL4(INIT)到VAL5之间,这个时候PWMB输出高电平,这个状态怎么清除呢?
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-9-11 21:59 , Processed in 0.107520 second(s), 29 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表