本例使用官方例程
frdmmcxa366_ctimer_pwm_example
CTIMER是MCX系列MCU的标准计数器/计时器
支持生成PWM信号、输入捕获以及定时器。
直接上官方代码。
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2020, 2025 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*/
//RED P3_18
//GREEN P3_19
//BLUE P3_21
/*******************************************************************************
* 头文件包含
******************************************************************************/
#include "fsl_debug_console.h"
#include "board.h"
#include "app.h"
#include "fsl_ctimer.h"
/*******************************************************************************
* 宏定义
******************************************************************************/
#ifndef CTIMER_MAT_PWM_PERIOD_CHANNEL
// PWM周期使用的CTimer匹配通道
#define CTIMER_MAT_PWM_PERIOD_CHANNEL kCTIMER_Match_3
#endif
/*******************************************************************************
* 函数声明
******************************************************************************/
/*******************************************************************************
* 全局变量
******************************************************************************/
volatile uint32_t g_pwmPeriod = 0U; // PWM周期对应的匹配计数值
volatile uint32_t g_pulsePeriod = 0U; // PWM高/低电平对应的匹配计数值
/*******************************************************************************
* 代码实现
******************************************************************************/
/*!
* @brief 计算PWM周期与脉冲宽度对应的CTimer匹配值
* @param pwmFreqHz PWM输出频率,单位Hz
* @param dutyCyclePercent 占空比百分比 0~100
* @param timerClock_Hz CTimer定时器时钟频率,单位Hz
* @return 函数执行状态,kStatus_Success表示成功
*/
status_t CTIMER_GetPwmPeriodValue(uint32_t pwmFreqHz, uint8_t dutyCyclePercent, uint32_t timerClock_Hz)
{
/* 计算PWM周期匹配值:定时器计数到该值时完成一个PWM周期 */
g_pwmPeriod = (timerClock_Hz / pwmFreqHz) - 1U;
/*
* 计算脉冲宽度匹配值
* 公式:总周期计数 * (100 - 占空比) /100
* 注:此处逻辑为匹配到时输出翻转,代表低电平时间,可根据硬件输出极性调整理解
*/
g_pulsePeriod = (g_pwmPeriod + 1U) * (100 - dutyCyclePercent) / 100;
return kStatus_Success;
}
/*!
* @brief 主函数
*/
int main(void)
{
ctimer_config_t config; // CTimer配置结构体
uint32_t srcClock_Hz; // CTimer源时钟频率(Hz)
uint32_t timerClock; // 经过预分频后的定时器工作时钟(Hz)
/* 初始化板级硬件 */
BOARD_InitHardware();
PRINTF("MCUX SDK version: %s\r\n", MCUXSDK_VERSION_FULL_STR);
/* CTimer0计数器使用AHB时钟 */
srcClock_Hz = CTIMER_CLK_FREQ;
PRINTF("CTimer example to generate a PWM signal\r\n");
/* 获取CTimer默认配置参数 */
CTIMER_GetDefaultConfig(&config);
/* 计算预分频之后的定时器时钟频率 */
timerClock = srcClock_Hz / (config.prescale + 1);
/* 初始化CTimer外设 */
CTIMER_Init(CTIMER, &config);
/* 获取20KHz、指定占空比的PWM周期与脉冲匹配计数值 */
CTIMER_GetPwmPeriodValue(20000, (uint8_t)DUTY_CYCLE, timerClock);
/* 配置CTimer生成PWM:周期通道、输出通道、周期计数值、脉冲计数值,不开启中断 */
CTIMER_SetupPwmPeriod(CTIMER, CTIMER_MAT_PWM_PERIOD_CHANNEL, CTIMER_MAT_OUT, g_pwmPeriod, g_pulsePeriod, false);
/* 启动CTimer定时器开始计数,输出PWM波形 */
CTIMER_StartTimer(CTIMER);
/* 主循环,PWM由硬件持续输出,无需软件干预 */
while (1)
{
}
}在app.h中 CTIMER被设置为CTIMER1的通道2
#define CTIMER CTIMER1 /* Timer 1 */ #define CTIMER_MAT_OUT kCTIMER_Match_2 /* Match output 2 */ #define CTIMER_CLK_FREQ CLOCK_GetCTimerClkFreq(1U)
在pinmux.c中 PORT3_12被设置为 CT1_MAT2(CTIMER1的通道2),所以最终PWM信号是通过P3_12输出。
/*
* Copyright 2025 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/***********************************************************************************************************************
* This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file
* will be overwritten if the respective MCUXpresso Config Tools is used to update this file.
**********************************************************************************************************************/
/* clang-format off */
/*
* TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
!!GlobalInfo
product: Pins v16.0
processor: MCXA366
package_id: MCXA366VLQ
mcu_data: ksdk2_0
processor_version: 0.0.0
* BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS ***********
*/
/* clang-format on */
#include "fsl_common.h"
#include "fsl_port.h"
#include "pin_mux.h"
/* FUNCTION ************************************************************************************************************
*
* Function Name : BOARD_InitBootPins
* Description : Calls initialization functions.
*
* END ****************************************************************************************************************/
void BOARD_InitBootPins(void)
{
BOARD_InitPins();
}
/* clang-format off */
/*
* TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
BOARD_InitPins:
- options: {callFromInitBoot: 'true', coreID: cm33_core0, enableClock: 'true'}
- pin_list:
- {pin_num: '35', peripheral: LPUART2, signal: TX, pin_signal: P2_2/TRIG_IN6/LPUART0_RTS_B/LPUART2_TXD/CT_INP12/CT2_MAT2/FLEXIO0_D10/EZH_PIO26/ADC0_A4/CMP0_IN0/DAC0_OUT,
slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, input_buffer: enable, invert_input: normal}
- {pin_num: '36', peripheral: LPUART2, signal: RX, pin_signal: P2_3/WUU0_IN19/TRIG_IN7/LPUART0_CTS_B/LPUART2_RXD/CT_INP13/CT2_MAT3/FLEXIO0_D11/EZH_PIO27/ADC0_A3/CMP1_IN0/ADC1_A4,
slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, input_buffer: enable, invert_input: normal}
- {pin_num: '92', peripheral: CTIMER1, signal: 'MATCH, 2', pin_signal: P3_12/LPUART2_RTS_B/LPUART3_TXD/CT1_MAT2/PWM0_X0/FLEXIO0_D20/PWM1_A2/LCD_P40/EZH_PIO12/ADC3_A14,
slew_rate: fast, open_drain: disable, drive_strength: low, pull_select: down, pull_enable: disable, input_buffer: enable, invert_input: normal}
* BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS ***********
*/
/* clang-format on */
/* FUNCTION ************************************************************************************************************
*
* Function Name : BOARD_InitPins
* Description : Configures pin routing and optionally pin electrical features.
*
* END ****************************************************************************************************************/
void BOARD_InitPins(void)
{
/* PORT2: Peripheral clock is enabled */
CLOCK_EnableClock(kCLOCK_GatePORT2);
/* PORT3: Peripheral clock is enabled */
CLOCK_EnableClock(kCLOCK_GatePORT3);
/* LPUART2 peripheral is released from reset */
RESET_ReleasePeripheralReset(kLPUART2_RST_SHIFT_RSTn);
/* PORT2 peripheral is released from reset */
RESET_ReleasePeripheralReset(kPORT2_RST_SHIFT_RSTn);
/* CTIMER1 peripheral is released from reset */
RESET_ReleasePeripheralReset(kCTIMER1_RST_SHIFT_RSTn);
/* PORT3 peripheral is released from reset */
RESET_ReleasePeripheralReset(kPORT3_RST_SHIFT_RSTn);
const port_pin_config_t port2_2_pin35_config = {/* Internal pull-up/down resistor is disabled */
.pullSelect = kPORT_PullDisable,
/* Low internal pull resistor value is selected. */
.pullValueSelect = kPORT_LowPullResistor,
/* Fast slew rate is configured */
.slewRate = kPORT_FastSlewRate,
/* Passive input filter is disabled */
.passiveFilterEnable = kPORT_PassiveFilterDisable,
/* Open drain output is disabled */
.openDrainEnable = kPORT_OpenDrainDisable,
/* Low drive strength is configured */
.driveStrength = kPORT_LowDriveStrength,
/* Normal drive strength is configured */
.driveStrength1 = kPORT_NormalDriveStrength,
/* Pin is configured as LPUART2_TXD */
.mux = kPORT_MuxAlt3,
/* Digital input enabled */
.inputBuffer = kPORT_InputBufferEnable,
/* Digital input is not inverted */
.invertInput = kPORT_InputNormal,
/* Pin Control Register fields [15:0] are not locked */
.lockRegister = kPORT_UnlockRegister};
/* PORT2_2 (pin 35) is configured as LPUART2_TXD */
PORT_SetPinConfig(PORT2, 2U, &port2_2_pin35_config);
const port_pin_config_t port2_3_pin36_config = {/* Internal pull-up/down resistor is disabled */
.pullSelect = kPORT_PullDisable,
/* Low internal pull resistor value is selected. */
.pullValueSelect = kPORT_LowPullResistor,
/* Fast slew rate is configured */
.slewRate = kPORT_FastSlewRate,
/* Passive input filter is disabled */
.passiveFilterEnable = kPORT_PassiveFilterDisable,
/* Open drain output is disabled */
.openDrainEnable = kPORT_OpenDrainDisable,
/* Low drive strength is configured */
.driveStrength = kPORT_LowDriveStrength,
/* Normal drive strength is configured */
.driveStrength1 = kPORT_NormalDriveStrength,
/* Pin is configured as LPUART2_RXD */
.mux = kPORT_MuxAlt3,
/* Digital input enabled */
.inputBuffer = kPORT_InputBufferEnable,
/* Digital input is not inverted */
.invertInput = kPORT_InputNormal,
/* Pin Control Register fields [15:0] are not locked */
.lockRegister = kPORT_UnlockRegister};
/* PORT2_3 (pin 36) is configured as LPUART2_RXD */
PORT_SetPinConfig(PORT2, 3U, &port2_3_pin36_config);
const port_pin_config_t port3_12_pin92_config = {/* Internal pull-up/down resistor is disabled */
.pullSelect = kPORT_PullDisable,
/* Low internal pull resistor value is selected. */
.pullValueSelect = kPORT_LowPullResistor,
/* Fast slew rate is configured */
.slewRate = kPORT_FastSlewRate,
/* Passive input filter is disabled */
.passiveFilterEnable = kPORT_PassiveFilterDisable,
/* Open drain output is disabled */
.openDrainEnable = kPORT_OpenDrainDisable,
/* Low drive strength is configured */
.driveStrength = kPORT_LowDriveStrength,
/* Normal drive strength is configured */
.driveStrength1 = kPORT_NormalDriveStrength,
/* Pin is configured as CT1_MAT2 */
.mux = kPORT_MuxAlt4,
/* Digital input enabled */
.inputBuffer = kPORT_InputBufferEnable,
/* Digital input is not inverted */
.invertInput = kPORT_InputNormal,
/* Pin Control Register fields [15:0] are not locked */
.lockRegister = kPORT_UnlockRegister};
/* PORT3_12 (pin 92) is configured as CT1_MAT2 */
PORT_SetPinConfig(PORT3, 12U, &port3_12_pin92_config);
}
/***********************************************************************************************************************
* EOF
**********************************************************************************************************************/逻辑分析仪测量结果:频率20 KHZ,占空比20%,跟程序预期一致。


我要赚赏金
