【NXP-MCXA153】PWM驱动移植

news2024/11/15 11:55:09

介绍

‌PWM(‌Pulse Width Modulation)‌,‌脉冲宽度调制,‌是一种数字量控制模拟量的技术,‌常用于电机驱动、显示屏背光控制、逆变控制等;NXP-MCXA153开发板上有多路CTimer定时器,可以用来生成PWM波形

移植流程

① 在board里边添加相应的外设:配置时钟分频、引脚功能等

② 添加相应的config开关、Kconfig开关,用以指示相应的外设开启与关闭(本质是通过宏定义或者条件编译的方式)

③ 根据SDK_2_14_2_FRDM-MCXA153提供的simple_pwm示例工程编写pwm总线驱动,需要实现几个关键的函数

  • mcx_pwm_init
  • mcx_drv_pwm_control
  • mcx_drv_pwm_enable
  • mcx_drv_pwm_disable

④ 添加相应的库文件依赖:fsl_ctimer.c

驱动文件

pin_mux.c

BOARD_InitPins函数里加入以下代码:配置CTIMER1外设为复位状态、设置P1_4引脚功能

#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

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

drv_pwm.c

pwm驱动层适配如下

/*
 * Copyright (c) 2006-2024, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2024-8-3       hywing       Initial version.
 */

#include <rtthread.h>
#include <rtdevice.h>
#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 */

SConscript

Libraries/MCXA153/SConscript文件里边加上以下代码

src += ['MCXA153/drivers/fsl_ctimer.c']

测试用例

打开使能pwm0驱动,保存配置推出menuconfig
在这里插入图片描述

导出MDK5工程

scons --target=mdk5

生成频率1KHz,占空比为5%的方波,最后编译并烧录到开发板上去

#include <rtthread.h>
#include <rtdevice.h>

#include <rtthread.h>
#include "board.h"
#include <rtdevice.h>

#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%
在这里插入图片描述

总结

其实这个是用NXP定时器配置的PWM,并不是原生的PWM,但也能满足要求

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2054496.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

6. 数据结构—串的匹配算法

1.BF算法(暴力算法) //模式匹配(暴力算法) int Index(SString S,SString T){int i1,j1;while(i<S.length&&j<T.length){if(S[i]T[i]){i;j;}else{ii-j2; //最开始匹配的位置的后一个j1; //从头匹配 }}if(j>T.length)return i-T.length;return return 0…

【Vue3】配置路由规则props

【Vue3】配置路由规则props 背景简介开发环境开发步骤及源码总结 背景 随着年龄的增长&#xff0c;很多曾经烂熟于心的技术原理已被岁月摩擦得愈发模糊起来&#xff0c;技术出身的人总是很难放下一些执念&#xff0c;遂将这些知识整理成文&#xff0c;以纪念曾经努力学习奋斗的…

Ubuntu启用root用户

1.1 命令行的组成 在启用 root 用户之前&#xff0c;先来了解一下&#xff0c;ubuntu 命令的组成。 打开 ubuntu 的终端&#xff0c;可以看到命令行是由 topeetubuntu:~$ 这几个字母组成&#xff0c;如下图所示&#xff1a; 对应的说明框图如下&#xff1a; 1.2 由普通用户切…

基于机器视觉的智能图像处理与分析系统(MATLAB图片处理,GUI界面)

灰度&#xff0c;二值&#xff0c;去噪&#xff0c;均衡&#xff0c;锐化&#xff0c;截取&#xff0c;边缘检测&#xff0c;都可做。 ☆图像灰度化&#xff0c;二值化 ☆图像相加&#xff0c;相减等 ☆图像旋转&#xff0c;图像裁剪 ☆图像灰度变换&#xff0c;gamma变换&…

Github 2024-08-19 开源项目周报Top15

根据Github Trendings的统计,本周(2024-08-19统计)共有15个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目7JavaScript项目3TypeScript项目3Dart项目2HTML项目1PowerShell项目1Clojure项目1C++项目1Rust项目1Bootstrap 5: Web上开发响应式、…

微服务:微服务保护

&#x1f4a5; 该系列属于【SpringBoot基础】专栏&#xff0c;如您需查看其他SpringBoot相关文章&#xff0c;请您点击左边的连接 目录 一、引言 1. 什么是雪崩问题 2. 雪崩问题产生的原因 3. 解决思路 二、微服务保护 1. 服务保护方案 &#xff08;1&#xff09;请求限…

03 serv00搭建WordPress

第一步 下载 serv00 官方教程 按官方教程下载 WordPress 压缩包&#xff0c;解压&#xff0c;将 WordPress 项目文件夹重命名为 public_html&#xff08;先删除原来的 public_html&#xff09; ‍ 第二步 安装 完成以上步骤后访问你的网站&#xff0c;开始安装 WordPress …

ESXi中设置网卡为混杂模式

为了测试系统网络问题&#xff0c;将ESXi中设置网卡设为混杂模式&#xff0c;如图 设置方法为进入编辑状态&#xff0c;然后将混杂模式选中&#xff1a; CBSD关于网络的一段描述 About bhyve networking By default, virtual machines use the tap interface, which CBSD aut…

WiFi的IP和电脑IP一样吗

在当今数字化时代&#xff0c;互联网已成为我们生活、学习和工作不可或缺的一部分。而网络连接的核心要素之一&#xff0c;就是IP地址。无论是通过WiFi接入网络的设备&#xff0c;还是直接连接至路由器的电脑&#xff0c;它们都拥有各自的IP地址。然而&#xff0c;这两个IP地址…

SQL 布尔盲注 (injection 第六关)

简介 SQL注入&#xff08;SQL Injection&#xff09;是一种常见的网络攻击方式&#xff0c;通过向SQL查询中插入恶意的SQL代码&#xff0c;攻击者可以操控数据库&#xff0c;SQL注入是一种代码注入攻击&#xff0c;其中攻击者将恶意的SQL代码插入到应用程序的输入字段中&am…

大华 DSS 数字监控系统 group_saveGroup SQL 注入漏洞复现

0x01 产品简介 大华 DSS 数字监控系统是大华开发的一款安防视频监控系统,拥有实时监视、云台操作、录像回放、报警处理、设备管理等功能。 0x02 漏洞概述 大华 DSS 数字监控系统 group_saveGroup 接口存在SQL 注入漏洞,未经身份验证的远程攻击者除了可以利用 SQL 注入漏洞…

计算机毕业设计pyspark+django+scrapy租房推荐系统 租房大屏可视化 租房爬虫 hadoop 58同城租房爬虫 房源推荐系统

用到的技术: 1. python 2. django后端框架 3. django-simpleui&#xff0c;Django后台 4. vue前端 5. element-plus&#xff0c;vue的前端组件库 6. echarts前端可视化库 7. scrapy爬虫框架 基于大数据的租房信息推荐系统包括以下功能&#xff1a…

一、什么是 mvvm? MVC、MVP、MVVM三种模式的区别与详解

简介 MVC、MVP、MVVM都是常见的软件架构模式。 MVC&#xff08;Model-View-Controller&#xff09;架构模式中&#xff0c;将应用程序分为三个主要部分&#xff1a;模型&#xff08;Model&#xff09;、视图&#xff08;View&#xff09;和控制器&#xff08;Controller&…

VBA技术资料MF185:图片导入Word添加不同格式说明文字

我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的工作效率&#xff0c;而且可以提高数据的准确度。“VBA语言専攻”提供的教程一共九套&#xff0c;分为初级、中级、高级三大部分&#xff0c;教程是对VBA的系统讲解&#…

Nuclei文件上传小Tips

前言 Nuclei对于文件上传类型Poc编写小Tips 平台 ProjectDiscovery Cloud Platform: https://cloud.projectdiscovery.io/ JsonPath: https://jsonpath.com/ Json解析&#xff1a; 在线json解析平台即可 案例 某康resourceOperations upload接口存在前台上传 具体接口&…

海康VisionMaster使用学习笔记9-畸变标定和畸变校正的使用

畸变标定和畸变校正 1. 功能和分类 2. 畸变标定 添加图像源 加载带有畸变的标定板图像 标定时标定板图像需尽量占满视野. 添加畸变标定 用于生成畸变标定文件 1. 运行参数畸变类型: 此时标定板图像同时包含径向和透视,因此选择径向透视畸变.标定板类型:棋盘格标定板校正中…

三、LogicFlow 基础配置介绍及实现一个基础 Demo

目录 前置LogicFlow 介绍LogicFlow基础配置引入方式核心包基础概念实例&#xff08;配置项&#xff09;节点边&#xff08;节点与节点之间的连线&#xff09;背景网格主题事件 插件包 实现基础Demo最后 前置 这一篇主要是对 LogicFlow 的一些功能及配置相关的介绍&#xff08;…

C++竞赛初阶L1-13-第五单元-循环嵌套(29~30课)535: T456454 数字统计

题目内容 请统计某个给定范围 [L,R] 的所有整数中&#xff0c;数字 2 出现的次数。 比如给定范围 [2,22]&#xff0c;数字 2 在数 2 中出现了 1 次&#xff0c;在数 12 中出现 1 次&#xff0c;在数 20 中出现 1 次&#xff0c;在数 21 中出现 1 次&#xff0c;在数 22 中出现…

人工智能赋能的认知营销:定制开发AI智能名片商城小程序的未来展望

摘要&#xff1a;随着人工智能技术的飞速发展&#xff0c;其在商业领域的应用日益广泛且深入&#xff0c;特别是在认知营销这一前沿领域。本文旨在探讨人工智能如何通过定制开发AI智能名片商城小程序&#xff0c;为认知营销注入新的活力与可能性。通过深入分析人工智能在数据处…

Security OAuth2简单修改授权码方式

问题 用户先通过密码模式获取令牌&#xff08;前端携带用户名和密码&#xff0c;在网关添加客户端id和客户端密码参数&#xff0c;认证服务通过密码模式发放令牌&#xff09;&#xff0c;此后使用该令牌访问服务。 现在&#xff0c;需要该用户授权给第三方客户端访问这个用户…