yin_wu_qing 发表于 2025-1-18 23:12

【KW41Z开发板测评】②PWM输出呼吸灯

<p><span style="font-size:16px;">&nbsp; &nbsp; 承接上期的<a href="https://bbs.eeworld.com.cn/thread-1304609-1-1.html" target="_blank">【KW41Z开发板测评】①开箱及搭建环境并点灯</a>帖子,使用NXP官方的MCUXpresso IDE很容易导出体验官方的参考例程。</span></p>

<p><span style="font-size:16px;">&nbsp; &nbsp; 这期借助&ldquo;frdmkw41z_driver_examples_tpm_simple_pwm&rdquo;参考例程来实现呼吸灯效果。官方的例程是通过串口给开发板发&ldquo;0&rdquo;~&ldquo;9&rdquo;来手动调节占空比,从而使RGB灯的蓝色管脚输出固定值的占空比,调节灯的亮度。</span></p>

<p><span style="font-size:16px;">&nbsp; &nbsp; 根据RGB灯部分的原理图,可知控制RGB灯蓝色输出的信号脚为PTA18,复用为TPM2_CH0通道,这里简单分享一下。</span></p>

<div style="text-align: left;"></div>

<div style="text-align: left;"><span style="font-size:16px;">根据数据手册可知,PTA18复用关系。</span></div>

<div style="text-align: left;"></div>

<div style="text-align: left;"></div>

<div style="text-align: left;"><span style="font-size:16px;">修改部分代码,工程源码关键部分展示如下:</span></div>

<div style="text-align: left;"><span style="font-size:16px;">pin_mux.c</span></div>

<div style="text-align: left;">
<pre>
<code class="language-cpp">#include "fsl_common.h"
#include "fsl_port.h"
#include "pin_mux.h"

#define PIN6_IDX                         6u   /*!&lt; Pin number for pin 6 in a port */
#define PIN7_IDX                         7u   /*!&lt; Pin number for pin 7 in a port */
#define PIN18_IDX                     18u   /*!&lt; Pin number for pin 18 in a port */
#define SOPT4_TPM2CH0SRC_TPM          0x00u   /*!&lt; TPM2 Channel 0 Input Capture Source Select: TPM2_CH0 signal */
#define SOPT5_LPUART0RXSRC_LPUART_RX0x00u   /*!&lt; LPUART0 Receive Data Source Select: LPUART_RX pin */

/*
* TEXT BELOW IS USED AS SETTING FOR THE PINS TOOL *****************************
BOARD_InitPins:
- options: {coreID: singlecore, enableClock: 'true'}
- pin_list:
- {pin_num: '42', peripheral: LPUART0, signal: RX, pin_signal: TSI0_CH2/PTC6/LLWU_P14/XTAL_OUT_EN/I2C1_SCL/UART0_RX/TPM2_CH0/BSM_FRAME}
- {pin_num: '43', peripheral: LPUART0, signal: TX, pin_signal: TSI0_CH3/PTC7/LLWU_P15/SPI0_PCS2/I2C1_SDA/UART0_TX/TPM2_CH1/BSM_DATA}
- {pin_num: '6', peripheral: TPM2, signal: 'CH, 0', pin_signal: TSI0_CH12/PTA18/LLWU_P6/SPI1_SCK/TPM2_CH0}
* BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR THE PINS TOOL ***
*/

/*FUNCTION**********************************************************************
*
* Function Name : BOARD_InitPins
* Description   : Configures pin routing and optionally pin electrical features.
*
*END**************************************************************************/
void BOARD_InitPins(void) {
CLOCK_EnableClock(kCLOCK_PortA);                           /* Port A Clock Gate Control: Clock enabled */
CLOCK_EnableClock(kCLOCK_PortC);                           /* Port C Clock Gate Control: Clock enabled */

PORT_SetPinMux(PORTA, PIN18_IDX, kPORT_MuxAlt5);         /* PORTA18 (pin 6) is configured as TPM2_CH0 */
PORT_SetPinMux(PORTC, PIN6_IDX, kPORT_MuxAlt4);            /* PORTC6 (pin 42) is configured as UART0_RX */
PORT_SetPinMux(PORTC, PIN7_IDX, kPORT_MuxAlt4);            /* PORTC7 (pin 43) is configured as UART0_TX */
SIM-&gt;SOPT4 = ((SIM-&gt;SOPT4 &amp;
    (~(SIM_SOPT4_TPM2CH0SRC_MASK)))                        /* Mask bits to zero which are setting */
      | SIM_SOPT4_TPM2CH0SRC(SOPT4_TPM2CH0SRC_TPM)         /* TPM2 Channel 0 Input Capture Source Select: TPM2_CH0 signal */
    );
SIM-&gt;SOPT5 = ((SIM-&gt;SOPT5 &amp;
    (~(SIM_SOPT5_LPUART0RXSRC_MASK)))                        /* Mask bits to zero which are setting */
      | SIM_SOPT5_LPUART0RXSRC(SOPT5_LPUART0RXSRC_LPUART_RX) /* LPUART0 Receive Data Source Select: LPUART_RX pin */
    );
}</code></pre>

<p><span style="font-size:16px;">tpm_simple_pwm.c</span></p>
</div>

<pre>
<code class="language-cpp">#include "fsl_debug_console.h"
#include "board.h"
#include "fsl_tpm.h"

#include "pin_mux.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#define BOARD_TPM_BASEADDR TPM2
#define BOARD_TPM_CHANNEL 0U

/* Interrupt to enable and flag to read; depends on the TPM channel used */
#define TPM_CHANNEL_INTERRUPT_ENABLE kTPM_Chnl0InterruptEnable
#define TPM_CHANNEL_FLAG kTPM_Chnl0Flag

/* Interrupt number and interrupt handler for the TPM instance used */
#define TPM_INTERRUPT_NUMBER TPM2_IRQn
#define TPM_LED_HANDLER TPM2_IRQHandler

/* Get source clock for TPM driver */
#define TPM_SOURCE_CLOCK CLOCK_GetFreq(kCLOCK_McgFllClk)

/*******************************************************************************
* Variables
******************************************************************************/
volatile bool brightnessUp = true; /* Indicate LED is brighter or dimmer */
volatile uint8_t updatedDutycycle = 10U;
volatile uint8_t getCharValue = 0U;

volatile uint32_t g_systickCounter;
uint8_t dutyCycle = 0;
uint8_t var = 0;
/*******************************************************************************
* Code
******************************************************************************/

void SysTick_Handler(void)
{
    if (g_systickCounter != 0U)
    {
      g_systickCounter--;
    }
}

void SysTick_DelayTicks(uint32_t n)
{
    g_systickCounter = n;
    while (g_systickCounter != 0U)
    {
    }
}

/*!
* @brief Main function
*/
int main(void)
{
    tpm_config_t tpmInfo;
    tpm_chnl_pwm_signal_param_t tpmParam;
    tpm_pwm_level_select_t pwmLevel = kTPM_LowTrue;

    /* Configure tpm params with frequency 24kHZ */
    tpmParam.chnlNumber = (tpm_chnl_t)BOARD_TPM_CHANNEL;
    tpmParam.level = pwmLevel;
    tpmParam.dutyCyclePercent = updatedDutycycle;

    /* Board pin, clock, debug console init */
    BOARD_InitPins();
    BOARD_BootClockRUN();
    BOARD_InitDebugConsole();

    /* Select the clock source for the TPM counter as MCGPLLCLK */
    CLOCK_SetTpmClock(1U);

    /* Set systick reload value to generate 1ms interrupt */
    if (SysTick_Config(SystemCoreClock / 1000U))
    {
      while (1)
      {
      }
    }
    TPM_GetDefaultConfig(&amp;tpmInfo);
    /* Initialize TPM module */
    TPM_Init(BOARD_TPM_BASEADDR, &amp;tpmInfo);

    TPM_SetupPwm(BOARD_TPM_BASEADDR, &amp;tpmParam, 1U, kTPM_CenterAlignedPwm, 24000U, TPM_SOURCE_CLOCK);

    TPM_StartTimer(BOARD_TPM_BASEADDR, kTPM_SystemClock);

    while (1)
    {
            if(var == 0)
                {
                        dutyCycle+=10;
                }
                else if(var == 1)
                {
                        dutyCycle-=10;
                }

                /* Disable channel output before updating the dutycycle */
                TPM_UpdateChnlEdgeLevelSelect(BOARD_TPM_BASEADDR, (tpm_chnl_t)BOARD_TPM_CHANNEL, 0U);

                /* Update PWM duty cycle */
                TPM_UpdatePwmDutycycle(BOARD_TPM_BASEADDR, (tpm_chnl_t)BOARD_TPM_CHANNEL, kTPM_CenterAlignedPwm,
                                dutyCycle);

                /* Start channel output with updated dutycycle */
                TPM_UpdateChnlEdgeLevelSelect(BOARD_TPM_BASEADDR, (tpm_chnl_t)BOARD_TPM_CHANNEL, pwmLevel);
                SysTick_DelayTicks(60U);

                if(dutyCycle &gt; 90)
                        var = 1;
                else if(dutyCycle &lt; 10)
                        var = 0;
    }
}
</code></pre>

<p><span style="font-size:16px;">然后Debug,将编译完的固件程序烧写到开发板中,运行程序,呈现呼吸道效果,见如下视频。</span></p>

<p>6a152fadf75f0a3e1a9a77b07faac7df</p>

lkh747566933 发表于 2025-1-21 15:09

路过围观,这种三色RGB彩灯有没有立贴的啊?

freebsder 发表于 2025-1-21 18:49

<p>单片机界的hello world</p>
页: [1]
查看完整版本: 【KW41Z开发板测评】②PWM输出呼吸灯