FlexPWM输出

RT1052自带了一个很强大的PWM输出模块FlexPWM,一共有4个模块,每一个模块又有4个通道,每个通道又有PWMA、PWMB和PWMX(不好配,以后有时间再研究研究,主要手上没有示波器,貌似配出来固定占空比的了,没示波器没法验证)三路构成,支持独立输出、互补输出、输入捕捉等一大堆功能,很是强大。

先上代码
引脚配置(话说飞凌的RT1052引出的脚比较少(2.0间距的排针真心没法用,没线。。。不好用),找一个能到外面的FlexPWM输出引脚,可真不容易。)
  1. void BOARD_InitPins(void) {
  2.   CLOCK_EnableClock(kCLOCK_Iomuxc);           /* iomuxc clock (iomuxc_clk_enable): 0x03u */
  3.         
  4. //转换速率       0 慢     1 快
  5. //驱动强度       0 无     1 R0     2 R0/2   3 R0/3    4 R0/4    5 R0/5    6 R0/6    7 R0/7
  6. //输出速度       0 50MHz  1 100MHz   2 100MHz   3 200MHz
  7. //开漏输出       0 关闭   1 开启
  8. //拉/保持器      0 关闭   1 开启
  9. //拉/保持器设置  0 保持    1 拉
  10. //上下拉电阻     0 100K下拉   1 47K上拉   2 100K上拉   3 22K上拉
  11. //滞回器设置     0 关闭       1开启                                                                                                                                                                                    
  12. IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_12_LPUART1_TX,0);         //复用为GPIO
  13. IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_12_LPUART1_TX, IOMUXC_SW_PAD_CTL_PAD_SRE(0)   //转换速率慢
  14.                                                      |IOMUXC_SW_PAD_CTL_PAD_DSE(6)    //驱动强度R0/6
  15.                                                      |IOMUXC_SW_PAD_CTL_PAD_SPEED(2)  //速度100MHz
  16.                                                      |IOMUXC_SW_PAD_CTL_PAD_ODE(0)    //关闭开漏
  17.                                                      |IOMUXC_SW_PAD_CTL_PAD_PKE(1)    //拉/保持器开启
  18.                                                      |IOMUXC_SW_PAD_CTL_PAD_PUE(0)    //选择为保持
  19.                                                      |IOMUXC_SW_PAD_CTL_PAD_PUS(0)    //100K下拉
  20.                                                      |IOMUXC_SW_PAD_CTL_PAD_HYS(0));  //关闭滞回
  21.                                                                                                                
  22. IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_13_LPUART1_RX,0);         //复用为GPIO
  23. IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_13_LPUART1_RX, IOMUXC_SW_PAD_CTL_PAD_SRE(0)    //转换速率慢
  24.                                                       |IOMUXC_SW_PAD_CTL_PAD_DSE(6)    //驱动强度R0/6
  25.                                                       |IOMUXC_SW_PAD_CTL_PAD_SPEED(2)  //速度100MHz
  26.                                                       |IOMUXC_SW_PAD_CTL_PAD_ODE(0)    //关闭开漏
  27.                                                       |IOMUXC_SW_PAD_CTL_PAD_PKE(1)    //拉/保持器开启
  28.                                                       |IOMUXC_SW_PAD_CTL_PAD_PUE(0)    //选择为保持
  29.                                                       |IOMUXC_SW_PAD_CTL_PAD_PUS(0)    //100K下拉
  30.                                                       |IOMUXC_SW_PAD_CTL_PAD_HYS(0));  //关闭滞回  
  31. IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_10_FLEXPWM1_PWMA03,0);         //复用为FLEXPWM1_PWMA03功能
  32. IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_10_FLEXPWM1_PWMA03, IOMUXC_SW_PAD_CTL_PAD_SRE(0)    //转换速率慢
  33.                                                        |IOMUXC_SW_PAD_CTL_PAD_DSE(6)    //驱动强度R0/6
  34.                                                        |IOMUXC_SW_PAD_CTL_PAD_SPEED(2)  //速度100MHz
  35.                                                        |IOMUXC_SW_PAD_CTL_PAD_ODE(0)    //关闭开漏
  36.                                                        |IOMUXC_SW_PAD_CTL_PAD_PKE(1)    //拉/保持器开启
  37.                                                        |IOMUXC_SW_PAD_CTL_PAD_PUE(0)    //选择为保持
  38.                                                        |IOMUXC_SW_PAD_CTL_PAD_PUS(0)    //100K下拉
  39.                                                        |IOMUXC_SW_PAD_CTL_PAD_HYS(0));  //关闭滞回        
  40.                                                                                                                
  41. }
复制代码
主程序
  1. #include "fsl_device_registers.h"
  2. #include "fsl_debug_console.h"
  3. #include "board.h"
  4. #include "pin_mux.h"
  5. #include "clock_config.h"
  6. #include "fsl_lpuart.h"
  7. #include "fsl_pwm.h"
  8. #include "fsl_xbara.h"
  9. #include "delay.h"
  10. #define DISPLAY_CLK(name) (PRINTF("%s:%d\r\n",#name,CLOCK_GetFreq(name)))    //打印对应时钟
  11. int main(void)
  12. {
  13.     int8_t pwmVal = 0;        
  14.     pwm_signal_param_t pwmSignal[1];
  15.     pwm_config_t pwmConfig;
  16.     BOARD_ConfigMPU();
  17.     BOARD_InitPins();
  18.     BOARD_BootClockRUN();
  19.     BOARD_InitDebugConsole();
  20.     delay_init();     //初始化延时
  21.         
  22.         
  23.      DISPLAY_CLK(kCLOCK_AhbClk);
  24.      DISPLAY_CLK(kCLOCK_IpgClk);        
  25.         
  26. //    XBARA_Init(XBARA1);
  27. //    XBARA_SetSignalsConnection(XBARA1, kXBARA1_InputLogicHigh, kXBARA1_OutputFlexpwm1Fault0);
  28. //    XBARA_SetSignalsConnection(XBARA1, kXBARA1_InputLogicHigh, kXBARA1_OutputFlexpwm1Fault1);
  29. //    XBARA_SetSignalsConnection(XBARA1, kXBARA1_InputLogicHigh, kXBARA1_OutputFlexpwm1234Fault2);
  30. //    XBARA_SetSignalsConnection(XBARA1, kXBARA1_InputLogicHigh, kXBARA1_OutputFlexpwm1234Fault3);
  31.         
  32.     PWM1->SM[3].DISMAP[0]=0;
  33.         
  34.         
  35.     PWM_GetDefaultConfig(&pwmConfig);                     //快速配置
  36.     pwmConfig.reloadLogic = kPWM_ReloadPwmFullCycle; //全周期更新
  37.     pwmConfig.pairOperation = kPWM_Independent;      //PWMA,PWMB各自独立输出
  38.     PWM_Init(PWM1, kPWM_Module_3, &pwmConfig);       //初始化PWM1的通道3
  39.     pwmSignal[0].pwmChannel = kPWM_PwmA;             //配置PWMA
  40.     pwmSignal[0].level = kPWM_HighTrue;              //有效电平为高
  41.     pwmSignal[0].dutyCyclePercent = 50;              //占空比50%
  42.         
  43.     /*配置PWM1 通道3 有符号中心对齐 PWM信号频率为1000Hz*/
  44.     PWM_SetupPwm(PWM1, kPWM_Module_3, pwmSignal, 1, kPWM_SignedCenterAligned, 1000, CLOCK_GetFreq(kCLOCK_IpgClk));        
  45.     PWM_SetPwmLdok(PWM1, kPWM_Control_Module_3, true);    //更新有关设置
  46.     PWM_StartTimer(PWM1, kPWM_Control_Module_3);              //开始计数
  47.         
  48.     while (1)
  49.     {
  50.         delay_ms(50);
  51.         pwmVal = pwmVal + 1;
  52.         if (pwmVal >= 100)
  53.         {
  54.             pwmVal = 0;
  55.         }
  56.         PWM_UpdatePwmDutycycle(PWM1,kPWM_Module_3, kPWM_PwmA, kPWM_SignedCenterAligned, pwmVal); //更新占空比
  57.         PWM_SetPwmLdok(PWM1, kPWM_Control_Module_3, true);    //更新有关设置
  58.     }
  59. }
复制代码


引脚配置复用没啥好说的。
要写程序,先配置时钟,不过这次直接用的默认配置,使用IPG_CLK作为时钟源。如果要修改分频的话,见下图

<ignore_js_op>

首先可以看到注释了一大段代码,这一段代码和 PWM1->SM[3].DISMAP[0]=0; 有一个在就行。(这一段代码暂时不提,可以看了下一篇贴子,再回来理解。大概的意思就是置位故障输出位。没有而且还没有关闭故障检测功能的话,就无法输出)DISMAP寄存器如下,作用可以控制故障检测功能的开关。

<ignore_js_op>

这里调用了PWM_GetDefaultConfig 进行快速配置,先看一下默认配置

    config->enableDebugMode = false;   //调试模式下暂停
    config->enableWait = false;             //等待模式下暂停
    config->reloadSelect = kPWM_LocalReload; //使用本地再加载
    config->faultFilterCount = 0;                      //故障过滤器计数为0
    config->faultFilterPeriod = 0;                     //禁用故障过滤器
    config->clockSource = kPWM_BusClock;     //使用IPBus作为时钟
    config->prescale = kPWM_Prescale_Divide_1;//分频为1
    config->initializationControl = kPWM_Initialize_LocalSync;//本地同步导致初始化
    config->forceTrigger = kPWM_Force_Local;        //CTRL2[FORCE]信号触发强制输出
    config->reloadFrequency = kPWM_LoadEveryOportunity;  //重载频率
    config->reloadLogic = kPWM_ReloadImmediate; //设置LDOK时,加载值
    config->pairOperation = kPWM_Independent;  //PWMA,PWMB各自独立输出



下面是补充的配置
pwmConfig.reloadLogic = kPWM_ReloadPwmFullCycle; //全周期更新
pwmConfig.pairOperation = kPWM_Independent;      //PWMA,PWMB各自独立输出
然后调用PWM_Init初始化

然后配置通道的情况
pwmSignal[0].pwmChannel = kPWM_PwmA;             //配置PWMA
pwmSignal[0].level = kPWM_HighTrue;              //有效电平为高
pwmSignal[0].dutyCyclePercent = 50;              //占空比50%


调用PWM_SetupPwm。

status_t PWM_SetupPwm(PWM_Type *base,
                      pwm_submodule_t subModule,
                      const pwm_signal_param_t *chnlParams,
                      uint8_t numOfChnls,
                      pwm_mode_t mode,
                      uint32_t pwmFreq_Hz,
                      uint32_t srcClock_Hz);


一共7个参数分别是,需要配置的模块,需要配置的通道,用于配置的数组地址,需要配置的数目(应该和数组的大小相同,这里只配置了PWMA),输出模式,输出PWM的频率,主时钟的频率。
这里的输出模式

typedef enum _pwm_mode
{
    kPWM_SignedCenterAligned = 0U, /*!< Signed center-aligned */
    kPWM_CenterAligned,            /*!< Unsigned cente-aligned */
    kPWM_SignedEdgeAligned,        /*!< Signed edge-aligned */
    kPWM_EdgeAligned               /*!< Unsigned edge-aligned */
} pwm_mode_t;


有这些,对于现在配置单通道输出来说,都差不多。
调用PWM_SetPwmLdok PWM_StartTimer设置,开始计数

最后说一下PWM_UpdatePwmDutycycle

void PWM_UpdatePwmDutycycle(PWM_Type *base,
                            pwm_submodule_t subModule,
                            pwm_channels_t pwmSignal,
                            pwm_mode_t currPwmMode,
                            uint8_t dutyCyclePercent);


一共5个参数,分别是,设置的模块,设置的通道,设置是PWMA还是PWMB,设置输出模式(和上面的一样),设置占空比

实验效果见附件(没有示波器啊。。。只能用电压表来指示输出。。。。)

posted on 2022-06-15 22:15  张凌001  阅读(511)  评论(1编辑  收藏  举报

导航