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没有输出。

  • 相关阅读:
    apache22与mod_mono
    设计模式之行为型模式
    jquery实现excel导出
    桥本分数式问题的C++算法
    [深入浅出iOS库]之图形库Core Plot
    HDU 1069 Monkey and Banana
    程序员咋学习
    JavaSocket通信(双向,有界面)
    BZOJ 3098(Hash Killer II生日攻击)
    [置顶] iPhone 5S及iWatch或将采用指纹验证技术
  • 原文地址:https://www.cnblogs.com/lianghong881018/p/15169534.html
Copyright © 2011-2022 走看看