【Follow me第二季第3期】扩展任务---EK_RA6M5函数信号发生器
本帖最后由 quansirx 于 2024-11-28 21:17 编辑<p>一、任务介绍</p>
<p>该项目使用EK_RA6M5评估板完成一简易函数信号发生器的制作,涉及EK_RA6M5主控芯片的片内资源有定时器GPT,数模转换器DAC;片外QSPI Flash用于存储历史DAC波形数据</p>
<p>DAC最大模拟输出电压为3.3V,最小输出电压为0V,如果使用外部电压偏置电路可以实现更大电压或负压输出。</p>
<p>二、原理说明</p>
<p>函数信号发生器最基本的功能是生成一定幅度、频率(周期)、波形类型的信号,那么如何通过MCU主控来控制波形的类型、幅度以及频率?这个思路是比较简单的,只需使用到定时器与DAC这两个外设就能够实现以上功能。对于一个12位的DAC,能转换的离散电压范围为2^12=4096档,这4096个电压档位将DAC的输出电压范围3.3V均分为4096份。</p>
<p>2.1、幅度调节</p>
<p>因此波形的幅度大小通过控制DAC的输出档位来实现,将DAC_Array波形查找表内数据归一化,设幅度调节因子为A,A∈。因此DAC最终输出的电压等于</p>
<p>DAC_Arrat*4095*A</p>
<p>2.2、频率调节</p>
<p>使用定时器实现,设定时器溢出频率为F,设DAC在一个信号周期的采样点数为N,于是DAC输出信号频率</p>
<p>f=F/N;</p>
<p>2.3、波形类型</p>
<p>将不同信号的波形数据存储到片内Flash,通过设置标记变量的方式来输出不同类型的波形</p>
<p> </p>
<p>2.4 软件流程图</p>
<p style="text-align: center;"> </p>
<p>三、程序设计</p>
<p>3.1 定时器外设设置</p>
<p>在FSP工具内新增定时器外设,用于定时触发DAC进行转换</p>
<p style="text-align: center;"> </p>
<p>3.2 DAC外设设置</p>
<p>FSP内新增DAC外设</p>
<p style="text-align: center;"> 3.3</p>
<p>波形设置代码</p>
<pre>
<code>//add***
#include "bsp_adc.h"
#include "math.h"
#define M_PI 3.14159265358979323846
#define ND 128
float frac=0.8;
volatile float dac_array;
volatile uint16_t dac_value;
volatile uint8_t wave_type=0;
static uint32_t n1=0;
static uint32_t n2=0;
static uint32_t n3=0;
//add***
//add2***
#define ND2 12800
volatile float history_dac_array;
volatile uint8_t show_history_wave=0;
//add2***
void init_dac_array(uint8_t cmd);
void init_dac_array(uint8_t cmd){
switch(cmd){
case 1://锯齿波
for(uint16_t i=0;i<ND;i++){
dac_array=(float)1.0*i/(ND-1);
}
break;
case 2://正弦波
double w=0.0;
for(uint16_t i=0;i<ND;i++){
dac_array=(float)(sin(w)+1)/2;
w+=(2*M_PI/(ND-1));
}
break;
case 3://方波
for(uint16_t i=0;i<ND;i++){
if(i<ND/2){
dac_array=1.0;
}
else{
dac_array=0;
}
}
break;
case 4://历史波形删除方波
n3=0;
n2=0;
// for(uint32_t i=0;i<ND2;i++){
// history_dac_array=0;
// }
break;
}
}</code></pre>
<p>DAC定时输出设置、信号幅度测试</p>
<pre>
<code>//add***
void g_timer0_callback(timer_callback_args_t * p_args)
{
FSP_PARAMETER_NOT_USED(p_args);
if(show_history_wave==0){
dac_value=(uint16_t)(frac*4095*dac_array);
R_DAC_Write(&g_dac0_ctrl,dac_value);
//add2**
history_dac_array=dac_array;
QSPI_Flash_BufferWrite(history_dac_array, FLASH_WriteAddress, ND2);//存储历史DAC波形
//add2**
if(n1==ND)
n1=0;
if(n2==ND2)
n2=0;
}
else{
QSPI_Flash_BufferRead(history_dac_array2, FLASH_WriteAddress, ND2);//读取历史DAC波形
dac_value=(uint16_t)(frac*4095*history_dac_array2);
R_DAC_Write(&g_dac0_ctrl,dac_value);
if(n3==n2)
n3=0;
}
}</code></pre>
<p>四、实验结果</p>
<p>我这里通过在调试状态更改标记变量的方式,更改DAC输出波形类型,信号幅度、频率,默认DAC历史波形存储深度为12800,超过存储深度后历史波形数据将被新的波形数据覆盖</p>
<p>另外提供了清除历史存储波形的选项。使用e2 studio内置real-time chart来观察DAC信号波形</p>
<p>4.1 GIF演示</p>
<p style="text-align: center;"> </p>
<p>4.2 视频演示</p>
<p style="text-align: center;"><iframe allowfullscreen="true" frameborder="0" height="450" src="https://training.eeworld.com.cn/shareOpenCourseAPI?isauto=true&lessonid=41683" style="background:#eee;margin-bottom:10px;" width="700"></iframe><br />
</p>
<p>做的这个函数发生器的频率能做到大概在多少范围</p>
qwqwqw2088 发表于 2024-11-29 11:17
做的这个函数发生器的频率能做到大概在多少范围
<p>没有使用DMA,目前是8KHz左右</p>
quansirx 发表于 2024-11-29 13:18
没有使用DMA,目前是8KHz左右
<p>8KHz频率这么高吗?输出个方波看看频率</p>
quansirx 发表于 2024-11-29 13:18
没有使用DMA,目前是8KHz左右
<p>请问有没有这个任务完整的工程代码?或者细一点的分享,这个任务的功能试了几次搞不定,谢谢</p>
wangerxian 发表于 2024-11-30 16:22
8KHz频率这么高吗?输出个方波看看频率
<p>可以的 但是DAC转换点数需要适当减少</p>
beyond_笑谈 发表于 2024-11-30 17:37
请问有没有这个任务完整的工程代码?或者细一点的分享,这个任务的功能试了几次搞不定,谢谢
<p>可以,源程序后面会上传 后续更新下文件链接</p>
beyond_笑谈 发表于 2024-11-30 17:37
请问有没有这个任务完整的工程代码?或者细一点的分享,这个任务的功能试了几次搞不定,谢谢
<p> 文件资源正在审核</p>
quansirx 发表于 2024-11-30 21:29
可以,源程序后面会上传 后续更新下文件链接
<p>工程链接:https://download.eeworld.com.cn/detail/quansirx/635164</p>
页:
[1]