基于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("\r\n PWM_SRC_CLK_FREQ  : %d  Hz \n",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\n");

	PRINTF("\r\n PWM_SRC_CLK_FREQ  : %d  Hz \n",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\n");
        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没有输出。

posted @ 2021-08-21 14:45  嵌入式实操  阅读(305)  评论(0编辑  收藏  举报