Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
DAC
NXP 微控制器
NXP-MCXN947
FRDM-MCXN947的DAC驱动添加
发布于 2024-03-24 22:48:32 浏览:209
订阅该版
[tocm] # 1.前言说明 查看MCXN947的RM,发现这颗芯片是支持DAC的,但是目前体验的frdm-mcxn947并没有实现这块的驱动。而之前计划玩ADC时,其实更想直接用DAC输出电平,ADC采集电平。因此在完成ADC验证后,便尝试实现DAC的驱动。 # 2.实现可行性研究 ## a.RM中DAC管脚信息 ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20240324/fdd55ec62ab7d5a2693ce944cd70f5f8.png) ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20240324/52dee79b2627ba7119808b6a371421ca.png) ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20240324/abb00720dfe52ce44164582ece18483d.png) ## b.规格书中对应的引脚信息 ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20240324/539e8434d8b76713f1b4dbe6b4e04727.png.webp) 经过以上信息,可以判定可以给这个板子添加DAC驱动。 # 3.代码修改 ## a.Kconfig中增加DAC相关配置 ```python menuconfig BSP_USING_DAC config BSP_USING_DAC bool "Enable DAC Channel" select RT_USING_DAC default y if BSP_USING_DAC config BSP_USING_DAC0 bool "Enable DAC0 Channel" default n config BSP_USING_DAC1 bool "Enable DAC1 Channel" default n config BSP_USING_DAC2 bool "Enable DAC2 Channel" default n endif ``` ## b.添加drv_dac.c文件 ```cpp /* * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2024-03-24 Oxlm first version */ #include
#include
#include "fsl_dac.h" #include "fsl_dac14.h" #ifdef RT_USING_DAC // #define DRV_DEBUG #define DBG_TAG "drv.dac" #ifdef DRV_DEBUG #define DBG_LVL DBG_LOG #else #define DBG_LVL DBG_INFO #endif /* DRV_DEBUG */ #include
struct mcx_dac { struct rt_dac_device mcxn_dac_device; LPDAC_Type *dac_base; clock_attach_id_t clock_attach_id; clock_div_name_t clock_div_name; uint8_t clock_div; uint8_t referenceVoltageSource; /* kDAC_ReferenceVoltageSourceAlt1, VREFH reference pin */ uint8_t SOC_CNTRL_BIT; char *name; }; static struct mcx_dac mcx_dac_obj[] = { #ifdef BSP_USING_DAC0 { .dac_base = DAC0, .clock_attach_id = kFRO_HF_to_DAC0, .clock_div_name = kCLOCK_DivDac0Clk, .clock_div = 1u, .referenceVoltageSource = kDAC_ReferenceVoltageSourceAlt1, .SOC_CNTRL_BIT = 4, .name = "dac0", }, #endif #ifdef BSP_USING_DAC1 { .dac_base = DAC1, .clock_attach_id = kFRO_HF_to_DAC1, .clock_div_name = kCLOCK_DivDac1Clk, .clock_div = 1u, .referenceVoltageSource = kDAC_ReferenceVoltageSourceAlt1, .SOC_CNTRL_BIT = 5, .name = "dac1", }, #endif #ifdef BSP_USING_DAC2 { .dac_base = DAC2, .clock_attach_id = kFRO_HF_to_DAC2, .clock_div_name = kCLOCK_DivDac2Clk, .clock_div = 1u, .referenceVoltageSource = kDAC_ReferenceVoltageSourceAlt1, .SOC_CNTRL_BIT = 6, .name = "dac2", }, #endif }; rt_err_t mcxn_dac_disabled(struct rt_dac_device *device, rt_uint32_t channel) { RT_ASSERT(device != RT_NULL); struct mcx_dac *dac = (struct mcx_dac *)device->parent.user_data; if (dac->dac_base == DAC2) { DAC14_Deinit(dac->dac_base); } else { DAC_Deinit(dac->dac_base); } return RT_EOK; } rt_err_t mcxn_dac_enabled(struct rt_dac_device *device, rt_uint32_t channel) { RT_ASSERT(device != RT_NULL); struct mcx_dac *dac = (struct mcx_dac *)device->parent.user_data; dac_config_t dacConfigStruct; dac14_config_t dac14ConfigStruct; if (dac->dac_base == DAC2) { DAC14_GetDefaultConfig(&dac14ConfigStruct); dac14ConfigStruct.enableOpampBuffer = true; dac14ConfigStruct.enableDAC = true; DAC14_Init(dac->dac_base, &dac14ConfigStruct); } else { DAC_GetDefaultConfig(&dacConfigStruct); dacConfigStruct.referenceVoltageSource = dac->referenceVoltageSource; DAC_Init(dac->dac_base, &dacConfigStruct); DAC_Enable(dac->dac_base, RT_TRUE); } return RT_EOK; } rt_err_t mcxn_dac_write(struct rt_dac_device *device, rt_uint32_t channel, rt_uint32_t *value) { RT_ASSERT(device != RT_NULL); struct mcx_dac *dac = (struct mcx_dac *)device->parent.user_data; if (dac->dac_base == DAC2) { if (*value > 0x3FFFU) { *value = 0x3FFFU; } DAC14_SetData(dac->dac_base, *value); } else { if (*value > 0xFFFU) { *value = 0xFFFU; } DAC_SetData(dac->dac_base, *value); } return RT_EOK; } struct rt_dac_ops mcxn_dac_ops = { .disabled = mcxn_dac_disabled, .enabled = mcxn_dac_enabled, .convert = mcxn_dac_write, }; static int mcxn_dac_init(void) { int i; int dac_num = sizeof(mcx_dac_obj) / sizeof(struct mcx_dac); for (i = 0; i < dac_num; i++) { CLOCK_SetClkDiv(mcx_dac_obj[i].clock_div_name, mcx_dac_obj[i].clock_div); CLOCK_AttachClk(mcx_dac_obj[i].clock_attach_id); SPC0->ACTIVE_CFG1 |= 0x01; // Enable VREF SPC0->ACTIVE_CFG1 |= (0x01 << mcx_dac_obj[i].SOC_CNTRL_BIT); if (RT_EOK != rt_hw_dac_register(&mcx_dac_obj[i].mcxn_dac_device, mcx_dac_obj[i].name, &mcxn_dac_ops, (void *)(mcx_dac_obj + i))) { LOG_E("%s register failed", mcx_dac_obj[i].name); return -RT_ERROR; } } return RT_EOK; } INIT_DEVICE_EXPORT(mcxn_dac_init); #endif ``` ## c.将文件添加至编译工具链 在bsp\nxp\mcx\mcxn\Libraries\drivers\SConscript中添加以下信息 ```python if GetDepend('BSP_USING_DAC'): src += ['drv_dac.c'] ``` ## d.pin_mux.c中相关管脚的修改 注释掉dac0和dac1相关gpio配置,新增dac0和dac1配置 ```cpp /* DAC */ PORT4->PCR[2] = PORT_PCR_MUX(0) | PORT_PCR_PS(0) | PORT_PCR_PE(0) | PORT_PCR_IBE(0); /* DAC0 */ PORT4->PCR[3] = PORT_PCR_MUX(0) | PORT_PCR_PS(0) | PORT_PCR_PE(0) | PORT_PCR_IBE(0); /* DAC1 */ /* MCX_RST UART */ //PORT4->PCR[2] = PORT_PCR_MUX(2) | PORT_PCR_PS(0) | PORT_PCR_PE(1) | PORT_PCR_IBE(1); /* FC2_UART */ //PORT4->PCR[3] = PORT_PCR_MUX(2) | PORT_PCR_PS(0) | PORT_PCR_PE(1) | PORT_PCR_IBE(1); /* FC2_UART */ ``` # 4.项目配置 1. 在env中打开ADC0_A0,打开DAC2后保存 2. 运行`scons --target=mdk5`重新生成工程 3. 硬件中将DAC2跳接至adc0_a0 # 5.结果验证 ```shell \ | / - RT - Thread Operating System / | \ 5.1.0 build Mar 24 2024 22:01:29 2006 - 2024 Copyright by RT-Thread team using armclang, version: 6210000 MCXN947 HelloWorld msh >adc probe adc0 probe adc0 success msh >adc enable adc0 adc0 channel 0 enables success msh >adc read 0 adc0 channel 0 read value is 0x000025F0 msh >adc read 0 adc0 channel 0 read value is 0x0000276B msh >adc read 0 adc0 channel 0 read value is 0x00002519 msh >adc read 0 adc0 channel 0 read value is 0x000026D0 msh > msh > msh >dac probe dac2 probe dac2 success msh >dac enable dac2 dac2 channel 0 enables success msh >dac write 0 20 dac2 channel 0 write value is 20 msh >adc read 0 adc0 channel 0 read value is 0x000000CE msh >adc read 0 adc0 channel 0 read value is 0x000000AF msh >adc read 0 adc0 channel 0 read value is 0x000000A4 msh >dac write 0 10000 dac2 channel 0 write value is 10000 msh >adc read 0 adc0 channel 0 read value is 0x00009BDA msh > ``` DAC0和DAC1的验证省略,其最终结果和DAC2结果类似。
1
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
oxlm
这家伙很懒,什么也没写!
文章
4
回答
102
被采纳
8
关注TA
发私信
相关文章
1
试贴-消灭0主题
2
LPC M4的一些资料
3
LPC4088的临时分支
4
lpc1788 ad 不稳定
5
1788 LCD控制器缓冲区字节问题
6
一起来学习LPC4088吧
7
上传LPC4088的realtouch主工程
8
RealBoard 4088预定帖 [第一批板子不多,预定提前结束]
9
晒RealBoard LPC4088开箱照啦,速带小板凳前来围观
10
4088主程序需要的SD卡资源
推荐文章
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
13
个答案
2
次被采纳
张世争
9
个答案
2
次被采纳
rv666
5
个答案
2
次被采纳
用户名由3_15位
11
个答案
1
次被采纳
本月文章贡献
程序员阿伟
9
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
大龄码农
1
篇文章
5
次点赞
RTT_逍遥
1
篇文章
2
次点赞
ThinkCode
1
篇文章
1
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部