【KW41Z开发板测评】②PWM输出呼吸灯
<p><span style="font-size:16px;"> 承接上期的<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;"> 这期借助“frdmkw41z_driver_examples_tpm_simple_pwm”参考例程来实现呼吸灯效果。官方的例程是通过串口给开发板发“0”~“9”来手动调节占空比,从而使RGB灯的蓝色管脚输出固定值的占空比,调节灯的亮度。</span></p>
<p><span style="font-size:16px;"> 根据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 /*!< Pin number for pin 6 in a port */
#define PIN7_IDX 7u /*!< Pin number for pin 7 in a port */
#define PIN18_IDX 18u /*!< Pin number for pin 18 in a port */
#define SOPT4_TPM2CH0SRC_TPM 0x00u /*!< TPM2 Channel 0 Input Capture Source Select: TPM2_CH0 signal */
#define SOPT5_LPUART0RXSRC_LPUART_RX0x00u /*!< 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->SOPT4 = ((SIM->SOPT4 &
(~(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->SOPT5 = ((SIM->SOPT5 &
(~(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(&tpmInfo);
/* Initialize TPM module */
TPM_Init(BOARD_TPM_BASEADDR, &tpmInfo);
TPM_SetupPwm(BOARD_TPM_BASEADDR, &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 > 90)
var = 1;
else if(dutyCycle < 10)
var = 0;
}
}
</code></pre>
<p><span style="font-size:16px;">然后Debug,将编译完的固件程序烧写到开发板中,运行程序,呈现呼吸道效果,见如下视频。</span></p>
<p>6a152fadf75f0a3e1a9a77b07faac7df</p>
路过围观,这种三色RGB彩灯有没有立贴的啊? <p>单片机界的hello world</p>
页:
[1]