zoukankan      html  css  js  c++  java
  • 基于RT1170 使能PWM 输出功能 (三)

    本文主要是通过迁移的思维,记录本人初次使用NXP MCUXpresso SDK API进行BSP开发

    MCUXpresso SDK PWM API 接口链接
      在MCUXpresso SDK 框架下提供了对PWM output进行操作的接口。PWM接口一般会考滤它的时钟源,然后设置其分频系数,计数寄存器的位数,设置其占空比,然后出来波形。
    比如说要输出一个10kHz的频率。举例:时钟频率: 132MHz,时钟分频: 128 ,计数频率: 132MHz/128 约为 1.03MHz,计数寄存器是 16 位,最大计数约为 65535,输出 PWM 最低频率 =1030000/65535 约 16Hz。 如果需要的频率小于PWM输出最低频率时,就需要更换时钟源或者调整时钟分频系数。

    在这里插入图片描述

    1. 首先阅读原理图

      蜂鸣器的硬件设计电路如下所示:
      Buzzer----GPIO_AD_27----FLEXPWM2_PWM1_B
    在这里插入图片描述

    2. SDK api 应用

    2.1 PWM Init

    需要将对应的引脚复用成PWM引脚

    void BOARD_InitPins(void)
    {
      IOMUXC_SetPinMux(
          IOMUXC_GPIO_AD_27_FLEXPWM2_PWM1_B,      /* GPIO_AD_27 is configured as FLEXPWM2_PWM1_B */
          0U);                                    /* Software Input On Field: Input Path is determined by functionality */
    }
    

    BUS_CLK_ROOT时钟源配置,在 clock_config.c 文件下:

        /* Configure Bus using SysPll3 divided by 2 */
        rootCfg.mux = kCLOCK_BUS_ClockRoot_MuxSysPll3Out;
        rootCfg.div = 2;
        CLOCK_SetRootClock(kCLOCK_Root_Bus, &rootCfg);
    

    默认PLL3为480Mhz, 所以 BUS_CLK_ROOT为 240Mhz。

    PRINTF("
     PWM_SRC_CLK_FREQ  : %d  Hz 
    ",CLOCK_GetRootClockFreq(kCLOCK_Root_Bus));
    

    最终的打印结果如下:

     PWM_SRC_CLK_FREQ  : 240000000  Hz 
    

    2.2 PWM test

    在MCUXpresso SDK框架下, 测试代码如下所示:

    /*
     * Copyright (c) 2015, Freescale Semiconductor, Inc.
     * Copyright 2016-2017 NXP
     * All rights reserved.
     *
     * SPDX-License-Identifier: BSD-3-Clause
     */
    
    #include "fsl_debug_console.h"
    #include "board.h"
    #include "fsl_pwm.h"
    
    #include "pin_mux.h"
    #include "fsl_xbara.h"
    /*******************************************************************************
     * Definitions
     ******************************************************************************/
    /* The PWM base address */
    #define BOARD_PWM_BASEADDR PWM1
    
    #define PWM_SRC_CLK_FREQ CLOCK_GetRootClockFreq(kCLOCK_Root_Bus)
    #define DEMO_PWM_CLOCK_DEVIDER kPWM_Prescale_Divide_4
    /* Definition for default PWM frequence in hz. */
    #ifndef APP_DEFAULT_PWM_FREQUENCE
    #define APP_DEFAULT_PWM_FREQUENCE (1000UL)
    #endif
    /*******************************************************************************
     * Prototypes
     ******************************************************************************/
    
    /*******************************************************************************
     * Variables
     ******************************************************************************/
    
    /*******************************************************************************
     * Code
     ******************************************************************************/
    
    
    static void PWM_DRV_InitBuzzer(void)
    {
    	
    	  uint16_t deadTimeVal = 0;
        pwm_signal_param_t pwmSignal[2];
        uint32_t pwmSourceClockInHz;
        uint32_t pwmFrequencyInHz = APP_DEFAULT_PWM_FREQUENCE;
    
        pwmSourceClockInHz = PWM_SRC_CLK_FREQ;
    
        /* Set deadtime count, we set this to about 650ns */
        //deadTimeVal = ((uint64_t)pwmSourceClockInHz * 650) / 1000000000;	
    
    
        pwmSignal[0].pwmChannel       = kPWM_PwmB;
        pwmSignal[0].level            = kPWM_HighTrue;
        pwmSignal[0].dutyCyclePercent = 50; /* 1 percent dutycycle */
        pwmSignal[0].deadtimeValue    = deadTimeVal;
        pwmSignal[0].faultState       = kPWM_PwmFaultState0;
    
    
        /*********** PWMA_SM1 - phase B configuration, setup PWM A channel only ************/
        PWM_SetupPwm(PWM2, kPWM_Module_1, pwmSignal, 1, kPWM_SignedCenterAligned, pwmFrequencyInHz,
                     pwmSourceClockInHz);
    
    
    }
    
    int main(void)
    {
        /* Structure of initialize PWM */
        pwm_config_t pwmConfig;
        pwm_fault_param_t faultConfig;
        uint32_t pwmVal = 4;
    
        /* Board pin, clock, debug console init */
        BOARD_ConfigMPU();
        BOARD_InitPins();
        BOARD_BootClockRUN();
        BOARD_InitDebugConsole();
    	PWM2->SM[kPWM_Fault_1].DISMAP[kPWM_faultchannel_0] = 0;	// 这里需要对应 PWM的子模块通道
    	PWM2->SM[kPWM_Fault_1].DISMAP[kPWM_faultchannel_1] = 0;	// 这里需要对应 PWM的子模块通道
    
    
        PRINTF("FlexPWM driver example
    ");
    
    	PRINTF("
     PWM_SRC_CLK_FREQ  : %d  Hz 
    ",CLOCK_GetRootClockFreq(kCLOCK_Root_Bus));
    
    
        /*
         * pwmConfig.enableDebugMode = false;
         * pwmConfig.enableWait = false;
         * pwmConfig.reloadSelect = kPWM_LocalReload;
         * pwmConfig.clockSource = kPWM_BusClock;
         * pwmConfig.prescale = kPWM_Prescale_Divide_1;
         * pwmConfig.initializationControl = kPWM_Initialize_LocalSync;
         * pwmConfig.forceTrigger = kPWM_Force_Local;
         * pwmConfig.reloadFrequency = kPWM_LoadEveryOportunity;
         * pwmConfig.reloadLogic = kPWM_ReloadImmediate;
         * pwmConfig.pairOperation = kPWM_Independent;
         */
        PWM_GetDefaultConfig(&pwmConfig);
    
    
        /* PWM clock select */
        pwmConfig.clockSource = kPWM_BusClock;						// 选择为 IPBus clock
        /* The Prescaler divides frequency */
        pwmConfig.prescale = kPWM_Prescale_Divide_128;				// 设置时钟分频 选用 IPBus时钟后,PWM clock = BUS_CLK_ROOT/Div=240M/128 = 1.875Mhz
        /* Use full cycle reload */
        pwmConfig.reloadLogic = kPWM_ReloadPwmFullCycle;			// 全周期更新
        /* PWM A & PWM B operate as 2 independent channels */
        pwmConfig.pairOperation   = kPWM_Independent;				// PWMA,PWMB各自独立输出
        pwmConfig.enableDebugMode = true;							      // 使能工作在 DEBUG模式
    
        /* Initialize submodule 1 */
        if (PWM_Init(PWM2, kPWM_Module_1, &pwmConfig) == kStatus_Fail)
        {
            PRINTF("PWM initialization failed
    ");
            return 1;
        }
    
        /* Call the init function with demo configuration */
        PWM_DRV_InitBuzzer();
        /* Set the load okay bit for all submodules to load registers from their buffer */
        PWM_SetPwmLdok(PWM2, kPWM_Control_Module_1, true);
        /* Start the PWM generation from Submodules 0, 1 and 2 */
        PWM_StartTimer(PWM2, kPWM_Control_Module_1);
        while (1U)
        {
            /* Delay at least 100 PWM periods. */
            SDK_DelayAtLeastUs((1000000U / APP_DEFAULT_PWM_FREQUENCE) * 100, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
    
            pwmVal = pwmVal + 4;
    
            /* Reset the duty cycle percentage */
            if (pwmVal > 100)
            {
                pwmVal = 4;
            }
    
            /* Update duty cycles  */
    
            PWM_UpdatePwmDutycycle(PWM2, kPWM_Module_1, kPWM_PwmB, kPWM_SignedCenterAligned, pwmVal);
    
            /* Set the load okay bit  to load registers from their buffer */
            PWM_SetPwmLdok(PWM2, kPWM_Control_Module_1, true);
        }
    }
    

    3. 代码生成

    在NXP提供的工具里可以通过 MCUXpresso Config Tools v9 生成初始化代码。
    先将引脚配置成PWM功能。
    在这里插入图片描述


    点击更新源代码

    即可生成对应的初始化代码。
    在这里插入图片描述

    4. 总结

      PWM编程时,需要注意的就是需要关闭对应的故障检测功能,否则PWM没有输出。

  • 相关阅读:
    用 Python 带你看各国 GDP 变迁
    Fluent Interface(流式接口)
    probing privatePath如何作用于ASP.NET MVC View
    Word插入htm文件导致文本域动态增加的一个问题
    Visual Studio 2013附加进程调试IE加载的ActiveX Control无效解决方法
    Ubuntu下Chrome运行Silverlight程序
    Windows Phone Bing lock screen doesn't change解决方法
    SPClaimsUtility.AuthenticateFormsUser的证书验证问题
    Web Service Client使用Microsoft WSE 2.0
    Visual Studio 2013安装Update 3启动crash的解决方法
  • 原文地址:https://www.cnblogs.com/lianghong881018/p/15169534.html
Copyright © 2011-2022 走看看