Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
PWM
【NXP-MCXA153】PWM驱动移植
发布于 2024-07-25 22:14:36 浏览:189
订阅该版
[tocm] ## 移植流程 ① 在board里边添加相应的外设:配置时钟分频、引脚功能等 ② 添加相应的config开关、Kconfig开关,用以指示相应的外设开启与关闭(本质是通过宏定义或者条件编译的方式) ③ 根据[SDK_2_14_2_FRDM-MCXA153](https://mcuxpresso.nxp.com/zh/builder?hw=FRDM-MCXA153)提供的simple_pwm示例工程编写pwm总线驱动,需要实现几个关键的函数 - mcx_pwm_init - mcx_drv_pwm_control - mcx_drv_pwm_enable - mcx_drv_pwm_disable ## 驱动文件 ### drv_pwm.c pwm驱动层适配如下 ```c /* * Copyright (c) 2006-2024, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2024-02-26 Yilin Sun Initial version. */ #include
#include
#include "fsl_ctimer.h" #ifdef RT_USING_PWM typedef struct { struct rt_device_pwm pwm_device; CTIMER_Type *ct_instance; uint32_t timerClock; const ctimer_match_t pwmPeriodChannel; ctimer_match_t matchChannel; char *name; } mcx_pwm_obj_t; static mcx_pwm_obj_t mcx_pwm_list[]= { #ifndef BSP_USING_PWM0 { .ct_instance = CTIMER1, .timerClock = 0, .pwmPeriodChannel = kCTIMER_Match_3, .matchChannel = kCTIMER_Match_2, .name = "pwm0", } #endif }; volatile uint32_t g_pwmPeriod = 0U; volatile uint32_t g_pulsePeriod = 0U; static rt_err_t mcx_drv_pwm_get(mcx_pwm_obj_t *pwm, struct rt_pwm_configuration *configuration) { return RT_EOK; } status_t CTIMER_GetPwmPeriodValue(uint32_t pwmFreqHz, uint8_t dutyCyclePercent, uint32_t timerClock_Hz) { g_pwmPeriod = (timerClock_Hz / pwmFreqHz) - 1U; g_pulsePeriod = (g_pwmPeriod + 1U) * (100 - dutyCyclePercent) / 100; return kStatus_Success; } static rt_err_t mcx_drv_pwm_set(mcx_pwm_obj_t *pwm, struct rt_pwm_configuration *configuration) { CTIMER_Type *ct = pwm->ct_instance; uint32_t pwmFreqHz = 1000000000 / configuration->period; uint8_t dutyCyclePercent = configuration->pulse * 100 / configuration->period; CTIMER_GetPwmPeriodValue(pwmFreqHz, dutyCyclePercent, pwm->timerClock); CTIMER_SetupPwmPeriod(ct, kCTIMER_Match_3, kCTIMER_Match_2, g_pwmPeriod, g_pulsePeriod, false); return 0; } static rt_err_t mcx_drv_pwm_enable(mcx_pwm_obj_t *pwm, struct rt_pwm_configuration *configuration) { CTIMER_StartTimer(pwm->ct_instance); return 0; } static rt_err_t mcx_drv_pwm_disable(mcx_pwm_obj_t *pwm, struct rt_pwm_configuration *configuration) { CTIMER_StopTimer(pwm->ct_instance); return 0; } static rt_err_t mcx_drv_pwm_control(struct rt_device_pwm *device, int cmd, void *args) { mcx_pwm_obj_t *pwm = device->parent.user_data; struct rt_pwm_configuration *configuration = (struct rt_pwm_configuration *)args; switch (cmd) { case PWM_CMD_ENABLE: return mcx_drv_pwm_enable(pwm, configuration); case PWM_CMD_DISABLE: return mcx_drv_pwm_disable(pwm, configuration); case PWM_CMD_SET: return mcx_drv_pwm_set(pwm, configuration); case PWM_CMD_GET: return mcx_drv_pwm_get(pwm, configuration); default: return -RT_EINVAL; } return RT_EOK; } static struct rt_pwm_ops mcx_pwm_ops = { .control = mcx_drv_pwm_control, }; int mcx_pwm_init(void) { rt_err_t ret; char name_buf[8]; ctimer_config_t config; CTIMER_GetDefaultConfig(&config); for (uint8_t i = 0; i < ARRAY_SIZE(mcx_pwm_list); i++) { mcx_pwm_list[i].timerClock = CLOCK_GetCTimerClkFreq(1U) / (config.prescale + 1); CTIMER_Init(mcx_pwm_list[i].ct_instance, &config); ret = rt_device_pwm_register(&mcx_pwm_list[i].pwm_device, mcx_pwm_list[i].name, &mcx_pwm_ops, &mcx_pwm_list[i]); if (ret != RT_EOK) { return ret; } } return RT_EOK; } INIT_DEVICE_EXPORT(mcx_pwm_init); #endif /* RT_USING_PWM */ ``` ### pin_mux.c 在`BOARD_InitPins`函数里加入以下代码 ```c #ifdef BSP_USING_PWM0 ctimer_config_t config; CTIMER_Init(CTIMER1, &config); const port_pin_config_t port1_4_pin62_config = {/* Internal pull-up/down resistor is disabled */ kPORT_PullDisable, /* Low internal pull resistor value is selected. */ kPORT_LowPullResistor, /* Fast slew rate is configured */ kPORT_FastSlewRate, /* Passive input filter is disabled */ kPORT_PassiveFilterDisable, /* Open drain output is disabled */ kPORT_OpenDrainDisable, /* Low drive strength is configured */ kPORT_LowDriveStrength, /* Normal drive strength is configured */ kPORT_NormalDriveStrength, /* Pin is configured as CT1_MAT2 */ kPORT_MuxAlt4, /* Digital input enabled */ kPORT_InputBufferEnable, /* Digital input is not inverted */ kPORT_InputNormal, /* Pin Control Register fields [15:0] are not locked */ kPORT_UnlockRegister}; /* PORT1_4 (pin 62) is configured as CT1_MAT2 */ PORT_SetPinConfig(PORT1, 4U, &port1_4_pin62_config); #endif ``` ### .config 加上PWM0相关开关 ``` CONFIG_BSP_USING_PWM=y CONFIG_BSP_USING_PWM0=y ``` ### board/Kconfig 加入PWM0相关配置 ``` menuconfig BSP_USING_PWM config BSP_USING_PWM bool "Enable PWM" select RT_USING_PWM default y if BSP_USING_PWM config BSP_USING_PWM0 bool "Enable PWM0 output" default y endif ``` ## 测试用例 生成频率1KHz,占空比为5%的方波 ```c #include
#include
#include
#include "board.h" #include
#define PWM_LED_DEV "pwm0" #define PWM_CHANNEL 3 int main(void) { struct rt_device_pwm *pwm_dev = RT_NULL; rt_uint32_t period, pulse; period = 1000000; pulse = 50000; pwm_dev = (struct rt_device_pwm *)rt_device_find(PWM_LED_DEV); if (pwm_dev == RT_NULL) { rt_kprintf("pwm device (%s) not found!\n", PWM_LED_DEV); return RT_ERROR; } rt_pwm_enable(pwm_dev, PWM_CHANNEL); rt_pwm_set(pwm_dev, PWM_CHANNEL, period, pulse); while (1) { rt_thread_mdelay(1000); } return 0; } ``` ## 实验效果 使用逻辑分析仪测量P1_4生成的波形,波形刚好频率为1KHz,占空比为5% ![方波.png](https://oss-club.rt-thread.org/uploads/20240725/eac1002825fe2d84ccf5979fb7cdee04.png.webp)
0
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
hywing
嵌入式系统开发工程师,从事物联网、工业自动化、汽车电子开发工作
文章
6
回答
3
被采纳
0
关注TA
发私信
相关文章
1
玩iot camera笔记之3测试试用3路pwm
2
[已解决]PWM输出异常分析
3
给RT-Thread添加PWM驱动框架
4
关于rt-thread-3.1.0 pwm
5
关于rt-thread的PWM框架在stm32f103vf应用的疑问
6
rt-thread stm32 bsp adc pwm 外设适配好了吗
7
stm32f103ze 添加pwm 设备失败
8
【正点原子】潘多拉IoT-STM32L475开发板 用menuconfig 看不到PWM....
9
关于rtthread 4.0.0版本中pwm的初始化定时器寄存器读写问题
10
RT-Thread正点原子战舰V3使用PWM设备驱动没有输出
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
keil_MDK
rt_mq_消息队列_msg_queue
ulog
C++_cpp
at_device
本月问答贡献
踩姑娘的小蘑菇
7
个答案
3
次被采纳
a1012112796
14
个答案
2
次被采纳
张世争
9
个答案
2
次被采纳
rv666
5
个答案
2
次被采纳
用户名由3_15位
13
个答案
1
次被采纳
本月文章贡献
程序员阿伟
9
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
大龄码农
1
篇文章
5
次点赞
RTT_逍遥
1
篇文章
2
次点赞
ThinkCode
1
篇文章
1
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部