【瑞萨RA_FSP】DAC —— 输出正弦波

news2024/11/25 16:28:12

文章目录

  • 一、DAC简介
  • 二、DAC的结构框图
    • 1. 参考电压
    • 2. 触发源
    • 3. DAC数据寄存器
    • 4. 转换的过程
    • 5. 同步转换
  • 三、生成正弦波数据表
  • 四、DAC程序设计
    • 1. 硬件设计
    • 2. 软件设计
      • ①文件结构
      • ②FSP配置
      • ③DAC初始化函数
      • ④设置DAC输出电压函数
      • ⑤DAC输出正弦波
      • ⑥ hal_entry入口函数


一、DAC简介

DAC即数模转换模块,顾名思义,它的作用就是把输入的数字编码,转换成对应的模拟电压输出,它的功能与ADC相反。 在常见的数字信号系统中,大部分传感器信号被化成数字信号,而ADC把电压模拟信号转换成易于计算机存储、处理的数字编码,然后将这些数字编码交给计算机进行处理处理, 由DAC生成的模拟电压常常用来驱动某些执行器件比如LED灯可以控制它的亮度,使人们易于感知。

RA6M5 具有片上DAC外设,总共有两路DAC输出通道,每路的分辨率可配置为12位, 这两个通道之间互不影响,每个通道都可以使用ELC功能可外部触发或者进行与ADC单元1的同步转换。

RA6M5的DAC特性:

  • 分辨率:12-bits

  • 输出通道:2 通道

  • 可设置模块停止状态降低功耗

  • DAC0 和 DAC1 可以通过一个事件信号输入来开启转换

  • 可通过以下方法减少 DAC 和 ADC 模块之间的干扰:
    ①同步D/A转换控制,使D/A转换数据的更新时间由ADC12(uint1)输入信号同步
    ②通过合理的控制DAC12的启动信号来减少干扰对D/A转换精度的影响

二、DAC的结构框图

RA6M5的DAC模块框图可见
在这里插入图片描述

框图中的“12-bit D/A”是核心部件,整个DAC外设都是围绕着DA1通道和DA0通道展开的, 左上作为参考电源以及模拟转换输出,右边有着相应的控制寄存器、总线接口、和同步转换。

1. 参考电压

AVCC0引脚作为ADC12和DAC12的电源输入引脚,AVSS0引脚作为ADC12和DAC12的接地输入引脚。 VREFH引脚作为DAC12的模拟参考高电压电源引脚。VREFL引脚作为DAC12的模拟参考低电压引脚。

分别把它们接入到电源的正负两级,可以得到DAC的输出电压范围为:0~3.3V。 如果想让输出的电压范围变宽,可以在外部加一个电压调节电路,把0~3.3V的DAC输出抬升到特定的范围即可。

在电路设计的时候不增加磁珠和电容接入到DAC12电源电路,会使得输出的电压不稳甚至输出的不是想要的电压, 这个时候可以在电路上增加磁珠和电容来减少干扰,从而优化DAC比较电压源从而使其输出稳定。

2. 触发源

可以设置软件来触发DAC、或者通过使用ELC进行触发、甚至还可以使用外部中断进行触发。最终目的是为了使得DACR.DAOEn(n=0,1)位被置1, 可以编写相应的寄存器控制代码以至于可以使用不同的方式进行触发。
在这里插入图片描述

当设置DACR中的DAOEn位(n = 0,1)为1时,启用DAC12并输出转换结果。当设置DACR中的DAOEn位(n = 0,1)为0时,关闭DAC输出转换。

下面是使用软件触发方式来使能DAC的代码:

/**
* @brief  软件使能并输出电压
* @param  输入DAC模块
* @retval 无
*/
void trigger_dac(dac_ctrl_t * p_api_ctrl)
{
   dac_instance_ctrl_t * p_ctrl = (dac_instance_ctrl_t *) p_api_ctrl;
   p_ctrl->p_reg->DACR_b.DAOE0 = 1U;   //使能DAC通道一使其输出相应电压
   //p_ctrl->p_reg->DACR_b.DAOE1 = 1U;   //使能DAC通道二使其输出相应电压
}

3. DAC数据寄存器

DADRn(D/A数据转换寄存器):

DADRn寄存器是一个16位的读/写寄存器,它存储用于D/A转换的数据。 虽然DADRn数据寄存器有16位数据,但是只用到了前面的12位,而后四位没有用到。还可以通过DADPR.DPSEL位进行设置12位的数据设置为左对齐或右对齐的数据格式。
在这里插入图片描述
当设置的触发源被启动时,DADRn中的值就会被转换并输出到模拟输出引脚上。 之后每当改变DADRn中的数值时,就可以改变输出的模拟电压。

电压转换公式:

如果直接通过输入一个12位的数字值,之后进行对DAC的触发源进行操作时,那么对软件的可操作性就比较差, 这个时候可以通过对软件代码优化使得更容易操作和控制电压,以下就是12位的数字值与电压之间的转换公式:
在这里插入图片描述
通过上面的公式我们知道(设定的数值/4096)x(基准电压)等于需要设定的电压, X对应着需要设定的电压,Y为最终需要设定的数值,那么会有这么一个等式成立: Y/2^12 * 3.3 = X => X / 3.3 * 2^12 = Y。 通过这个公式就可以知道设置的D/A转换电压是多少,将上面的公式写成如下的函数。 其中set_voltage为需要设置的电压,dac_date为需要输入到D/A数据转换寄存器的数据。

/**
* @brief  设置当前的电压3.3V
* @param  需要控制的电压
* @retval 无
*/
void dac_Set(double voltage)
{
   uint16_t dac_date;
   dac_date = (uint16_t)4095*((voltage)/3.3f);
   R_DAC_Write(DAC.p_ctrl, dac_date);
}

4. 转换的过程

在转换的过程中想要停止DAC转换的话,只需要将DACR.DAOEn(n=0,1)位给置0。

  1. 第一步在DADPR寄存器中设置我们想要转换的数据格式

  2. 触发使能寄存器,使得DAC使能寄存器DACR.DAOEn(n=0,1),以开始数模转换转换的结果将在一段时间t过后从输出引脚DA0上输出。如果使能寄存器一直为1的话,DAC将一直转换输出,直到将DAC使能寄存器DACR.DAOEn(n=0,1)位设置0。

  3. 若在转换的过程中,想要改变DAC模拟输出的数值的时候,需要将一个值写入到数据寄存器DADRn(n=0,1)中,转换的结果将在一段时间t过后从输出引脚DAn(n=0,1)上输出。

5. 同步转换

通过同步转换可以使得ADC的单元一和DAC进行同步转换, 通过两个寄存器来控制这一过程,这两个寄存器分别为:通过两个寄存器来控制这一过程这两个寄存器分别为:同步单元选择寄存器(DAADUSR寄存器)和 同步使能转换寄存器(DAADSCR寄存器)。

DAADSCR寄存器:
如果使用ELC事件链接控制器来控制的话,就不能够使能DAADSCR寄存器。 将DAADST位设置为0,允许DADRn寄存器值随时转换为模拟数据。 将DAADST位设置为1,允许D/A转换与同步D/A转换同步,使来自ADC12的输入信号同步(单元1)。 使用此位直到DADC12(单元1)完成A/D转换才开始D/A转换,即使DADRn寄存器被改变。

DAADUSR寄存器:
DAADUSR寄存器选择ADC12单元一进行D/A和A/D同步转换。 将AMADSEL1位设置为1,选择ADC单元1作为DAC的同步单元。 将AMADSEL1位设置为0,不选择ADC单元同步单元。

三、生成正弦波数据表

要输出正弦波,实质是要控制DAC以v=sin(t)的正弦函数关系输出电压,其中v为电压输出,t为时间。

而由于模拟信号连续而数字信号是离散的,所以使用DAC产生正弦波时,只能按一定时间间隔输出正弦曲线上的点,在该时间段内输出相同 的电压值,若缩短时间间隔,提高单个周期内的输出点数,可以得到逼近连续正弦波的图形,见下图,若在外部电路加上适当的电容滤波,可得到更完美的图形。
在这里插入图片描述
由于正弦曲线是周期函数,所以只需要得到单个周期内的数据后按周期重复即可,而单个周期内取样输出的点数又是有限的,所以为了得到呈v=sin(t)函数关系电压值的数据通常不会实时计算获取,而是预先计算好函数单个周期内的电压数据表,并且转化成以DAC寄存器表示的值。

如sin函数值的范围为[-1: +1],而RA6M5的DAC输出电压范围为[0~3.3]V,按12位DAC分辨率表示的方法,可写入寄存器的最大值为212 = 4096,即范围为[0:4096]。所以,实际输出时,会进行如下处理:

  • 抬升sin函数的输出为正值:v = sin(t)+1 ,此时,v的输出范围为[0:2];

  • 扩展输出至DAC的全电压范围: v = 3.3*(sin(t)+1)/2 ,此时,v的输出范围为[0:3.3],正是DAC的电压输出范围,扩展至全电压范围可以充分利用DAC的分辨率;

  • 把电压值以DAC寄存器的形式表示:Reg_val = 212/3.3 * v = 211*(sin(t)+1),此时,存储到DAC寄存器的值范围为[0:4095];

  • 实践证明,在sin(t)的单个周期内,取32个点进行电压输出已经能较好地还原正弦波形,所以在t∈[0:2π]区间内等间距根据上述Reg_val公式运算得到32个寄存器值,即可得到正弦波表;

  • 控制DAC输出时,每隔一段相同的时间从上述正弦波表中取出一个新数据进行输出,即可输出正弦波。改变间隔时间的单位长度,可以改变正弦波曲线的周期。

四、DAC程序设计

1. 硬件设计

野火启明6M5开发板的引出引脚电路图如图所示
在这里插入图片描述
RA6M5有2个DAC通道,两个通道分别可以连接到 P014 和 P015 引脚上。
在这里插入图片描述

2. 软件设计

①文件结构

├─ ......
└─ src
   ├─ led
   │  ├─ bsp_led.c
   │  └─ bsp_led.h
   ├─ debug_uart
   │  ├─ bsp_debug_uart.c
   │  └─ bsp_debug_uart.h
   ├─ adc
   │  ├─ bsp_dac.c
   │  └─ bsp_dac.h
   └─ hal_entry.c

②FSP配置

打开该工程的 FSP 配置界面进行配置。

首先依次点击 “Stacks” -> “Pins” -> “Peripherals” -> “DAC0” 来配置通道 DA0 对应的引脚为 P014。 如下图所示。
在这里插入图片描述
然后依次点击 “Stacks” -> “New Stack” -> “Analog” -> “DAC (r_dac)” 来配置DAC模块。 如下图所示。
在这里插入图片描述
DAC 的属性配置:
在这里插入图片描述
实际上除了DA0引脚选择以外,在本次实验中这些属性都不怎么需要配置,按照默认值即可。
在这里插入图片描述
配置完成之后可以按下快捷键“Ctrl + S”保存, 最后点右上角的 “Generate Project Content” 按钮,让软件自动生成配置代码即可。

③DAC初始化函数

/**
* @brief  初始化DAC
* @param  无
* @retval 无
*/
void DAC_Init()
{
   R_DAC_Open(&g_dac0_ctrl, &g_dac0_cfg);
   R_DAC_Start(&g_dac0_ctrl);
}
  • R_DAC_Open()配置单个 DAC 通道,启动通道,并提供用于 DAC API 写入和关闭函数的句柄。

  • R_DAC_Start()启动 D/A 转换输出。

④设置DAC输出电压函数

/**
* @brief  设置当前的电压
* @param  需要控制的电压
* @retval 无
*/
void DAC_SetVoltage(float voltage)
{
   uint16_t dac_data;
   dac_data = (uint16_t)(4095*((voltage)/3.3f));
   R_DAC_Write(&g_dac0_ctrl, dac_data);
}

通过电压转换公式将输入的模拟量转换为数值量,输入到R_DAC_Write()函数里, R_DAC_Write()会将数据写入到 D/A 转换器里。

⑤DAC输出正弦波

//正弦波数据数组变量
uint16_t var[] = {
   2048, 2460, 2856, 3218, 3532, 3786, 3969, 4072, 4093, 4031, 3887, 3668,
   3382, 3042, 2661, 2255, 1841, 1435, 1054, 714, 428, 209, 65, 3, 24, 127,
   310, 564, 878, 1240, 1636, 2048
};


/**
* @brief  生成正弦波波形
* @param  输入的值可以调节波形的周期
* @retval 无
*/
void DAC_SinWave_Cycle(uint32_t time_interval)
{
   for(uint32_t i = 0 ; i < (sizeof(var)/sizeof(var[0])); i++)
   {
      R_DAC_Write(&g_dac0_ctrl, var[i]);
      R_BSP_SoftwareDelay(time_interval, BSP_DELAY_UNITS_MILLISECONDS);
   }
}

通过轮循的方式将之前python生成的正弦波数据输入到R_DAC_Write()函数里面, 并且延时一段时间。而延时时间就是输入到函数里面的数值, 通过改变这一数值就可以调节正弦波的周期以及频率。

⑥ hal_entry入口函数

/* 用户头文件包含 */
#include "led/bsp_led.h"
#include "debug_uart/bsp_debug_uart.h"
#include "dac/bsp_dac.h"

void hal_entry(void)
{
   /* TODO: add your own code here */

   LED_Init();         // LED 初始化
   Debug_UART4_Init(); // SCI4 UART 调试串口初始化
   DAC_Init();         // DAC 初始化

   printf("这是一个DAC输出正弦波的实验例程\r\n");
   printf("使用示波器测量 P014 引脚(DAC 0)\r\n");

   while(1)
   {
      DAC_SinWave_Cycle(1);
   }


#if BSP_TZ_SECURE_BUILD
   /* Enter non-secure code */
   R_BSP_NonSecureEnter();
#endif
}

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

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

相关文章

多用户商城软件有哪些开发方式?-加速度jsudo

电商时代之下&#xff0c;企业商家纷纷开始了b2b2c商城系统的搭建&#xff0c;以此来抢占电商市场&#xff0c;但由于大多企业商家并没有专业化的开发团队&#xff0c;所以大多会选择将网站建设外包给专业的商城系统开发公司&#xff0c;但就目前而言&#xff0c;b2b2c商城系统…

改进YOLOv8 | 损失函数篇 | YOLOv8 更换损失函数之 SIoU / EIoU / WIoU / Focal_xIoU 最全汇总版

文章目录 更换方式CIoUDIoUEIoUGIoUSIoUWIoUFocal_CIoUFocal_DIoUFocal_EIoUFocal_GIoUFocal_SIoU提示更换方式 第一步:将ultralytics/yolo/utils/metrics.py文件中的bbox_iou替换为如下的代码:class

基于微信小程序的云音乐管理系统+第三稿+文档

博主介绍&#xff1a;✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 项目名称 基于微信小程序的云音乐管理系统第三稿文档 视频演示 基于微信小程序的云音乐管理系统第三稿问题解答任务书开题报告查重报告安装视频讲解视频&#…

【计算机网络】第三章传输层-电子科技大学2023期末考试

第三章 传输层 传输层服务与协议 传输层为两个不同主机上的应用程序之间提供逻辑通信机制 传输层协议运行在端系统 发送方: 将应用程序报文分成数据段传递给网络层,接受方: 将数据段重新组装成报文传递到应用层 网络层为两个主机之间提供逻辑通信 主要提供两种协议TCP和U…

RTC

文章目录 前言驱动应用程序运行 前言 RTC&#xff08;Real Time Clock&#xff0c;实时时钟&#xff09;是个常用的外设&#xff0c;通过 RTC 我们可以知道日期和时间信息&#xff0c;因此在需要记录时间的场合就需要实时时钟。 可以使用专用的实时时钟芯片来完成此功能&#…

PostgreSQL如何创建临时表?

分类 PostgreSQL支持两种临时表&#xff1a; 会话级临时表&#xff1a;数据可以一直保存在整个会话的生命周期中事务级临时表&#xff1a;数据只存在于这个事务的生命周期中 在PostgreSQL中&#xff0c;不管是事务级的临时表还是会话级的临时表&#xff0c;当会话结束时都会…

家庭版Windows10/Windows11不支持远程桌面的解决办法

家庭版Windows10或11是不支持远程桌面的。我们可以在电脑的“设置”-> “远程桌面设置”中查看系统是否支持远程桌面&#xff1a;我们可以通过RDPWrap这个项目让家庭版也支持远程桌面。 百度网盘下载 首先在下面网址下载该项目&#xff0c;下载zip&#xff1a;https://gith…

【wifi使用指导】wifi模块怎么用?无线路由wifi模块SKW92A/SKW77网页配置说明

据悉&#xff0c;在全球范围内&#xff0c;WiFi承载了超过一半的数据流量&#xff0c;并且65%-90%的智能手机流量来自WiFi。无线覆盖的实现依赖于WiFi模块提供的WiFi信号&#xff0c;支持AP/Client&#xff0c;Bridge&#xff0c;Gateway&#xff0c;Router&#xff0c;3G/4G R…

U-Mail企业邮件服务器搭建方案

数字化办公的日渐推行&#xff0c;使企业对邮箱的依赖与日俱增&#xff0c;正式工作报告&#xff0c;部门之间的事物往来、通知等等都需要使用到企业邮箱。随着企业对数字化建设的不断深入&#xff0c;企业对企业邮箱的要求也越来越高&#xff0c;比如对第三方应用集成及协同办…

【C++】STL之string类(1)

个人主页&#xff1a;平行线也会相交&#x1f4aa; 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 平行线也会相交 原创 收录于专栏【C之路】&#x1f48c; 本专栏旨在记录C的学习路线&#xff0c;望对大家有所帮助&#x1f647;‍ 希望我们一起努力、成长&…

19项网络与数据安全新国标全文公开免费下载

根据2023年5月23日国家市场监督管理总局、国家标准化管理委员会发布的中华人民共和国国家标准公告&#xff08;2023年第2号&#xff09;&#xff0c;全国信息安全标准化技术委员会归口的19项网络安全国家标准正式发布。近日&#xff0c;标准全文正式公开&#xff0c;博主第一时…

【社区图书馆】疯狂 Java 讲义:但凡种种,不一而足

虽说酒香不怕巷子深&#xff0c;但是千里之外并不一定能闻到&#xff0c;有人看到这可能会感觉这不免有些杠的味道&#xff0c;其实我想表达的是好酒也需要宣传&#xff0c;比如今天我所要讲的这本书《疯狂Java讲义》。 这不是【赠书活动】&#xff0c;这不是赠书活动… …&…

ChatGPT辅助学Qt6.2——1.Qt安装及编写登录界面

本文旨在帮助读者理解如何使用ChatGPT来辅助安装和学习Qt 6.2。我们将从Qt 6.2的基本概念开始&#xff0c;然后深入了解其安装过程&#xff0c;并探讨如何使用ChatGPT作为一个强大的辅助工具。对于那些寻求在学习和使用Qt 6.2中找到有效支持的人来说&#xff0c;这篇文章将提供…

中国电子学会2023年05月份青少年软件编程Python等级考试试卷五级真题(含答案)

2023-05 Python五级真题 分数&#xff1a;100 题数&#xff1a;38 测试时长&#xff1a;60min 一、单选题(共25题&#xff0c;共50分) 1. 有列表L[UK,china,lili,"张三"]&#xff0c;print(L[-2])的结果是&#xff1f;&#xff08; C&#xff09; A. UK B.…

华为防火墙基础知识

1.什么是防火墙 墙&#xff0c;始于防&#xff0c;忠于守。自古至今&#xff0c;墙予人以安全之意。防火墙&#xff0c;顾名思义&#xff0c;阻挡的是火&#xff0c;这一名词起源于建筑领域&#xff0c;其作用是隔离火灾&#xff0c;阻止火势从一个区域蔓延到另一个区域。 而…

Spring常见问题

包含内容 单例bean线程是安全的吗&#xff1f; Spring框架中的bean是单例的吗&#xff1f; 是单例的 这个默认是单例的但是可以在Bean注解类文件使用Scope注解进行配置 singleton&#xff1a;bean在每个Spring IOC容器中只有一个实例prototype&#xff1a;一个bean的定义可以…

C语言指针入门学习、知识点梳理(三)

本篇继续深入介绍C语言指针的基本概念与知识点&#xff0c;以经典指针程序--------”互换两个数字“进行阐述&#xff0c;基础不牢地动山摇&#xff0c;有关指针的基础概念&#xff0c;需要提前学习的&#xff0c;可以通过链接跳转至第一、第二篇。 C语言指针入门学习、概念梳…

Linux常见指令

Linux常见指令 引言Linux常见指令查指令——man文件管理相关指令lspwdcdtouchmkdirrmdir与rmrmdirrm cpmvfind 文件查看类catmorelesshead 与 tailheadtail使用管道显示某段内容 grep 打包压缩相关指令zip/unziptar 总结 引言 Linux与我们熟悉的Window都是操作系统&#xff0c…

C语言之指针详解(6)

目录 本章重点 1. 字符指针 2. 数组指针 3. 指针数组 4. 数组传参和指针传参 5. 函数指针 6. 函数指针数组 7. 指向函数指针数组的指针 8. 回调函数 9. 指针和数组面试题的解析 指向函数指针数组的指针 指向函数指针数组的指针是一个指针指针指向一个数组 &#xff0…

【Shiro】第三章 Shiro入门

目录 1、身份认证 2、Realm 3、编码、散列算法 4、Realm使用散列算法 1、身份认证 【1】基本流程 流程如下: 1、Shiro把用户的数据封装成标识token,token一般封装着用户名&