【Follow me第二季第3期】扩展任务---EK_RA6M5函数信号发生器
[复制链接]
本帖最后由 quansirx 于 2024-11-28 21:17 编辑
一、任务介绍
该项目使用EK_RA6M5评估板完成一简易函数信号发生器的制作,涉及EK_RA6M5主控芯片的片内资源有定时器GPT,数模转换器DAC;片外QSPI Flash用于存储历史DAC波形数据
DAC最大模拟输出电压为3.3V,最小输出电压为0V,如果使用外部电压偏置电路可以实现更大电压或负压输出。
二、原理说明
函数信号发生器最基本的功能是生成一定幅度、频率(周期)、波形类型的信号,那么如何通过MCU主控来控制波形的类型、幅度以及频率?这个思路是比较简单的,只需使用到定时器与DAC这两个外设就能够实现以上功能。对于一个12位的DAC,能转换的离散电压范围为2^12=4096档,这4096个电压档位将DAC的输出电压范围3.3V均分为4096份。
2.1、幅度调节
因此波形的幅度大小通过控制DAC的输出档位来实现,将DAC_Array波形查找表内数据归一化,设幅度调节因子为A,A∈[0,1]。因此DAC最终输出的电压等于
DAC_Arrat*4095*A
2.2、频率调节
使用定时器实现,设定时器溢出频率为F,设DAC在一个信号周期的采样点数为N,于是DAC输出信号频率
f=F/N;
2.3、波形类型
将不同信号的波形数据存储到片内Flash,通过设置标记变量的方式来输出不同类型的波形
2.4 软件流程图
三、程序设计
3.1 定时器外设设置
在FSP工具内新增定时器外设,用于定时触发DAC进行转换
3.2 DAC外设设置
FSP内新增DAC外设
3.3
波形设置代码
//add***
#include "bsp_adc.h"
#include "math.h"
#define M_PI 3.14159265358979323846
#define ND 128
float frac=0.8;
volatile float dac_array[ND];
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[ND2];
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[i]=(float)1.0*i/(ND-1);
}
break;
case 2://正弦波
double w=0.0;
for(uint16_t i=0;i<ND;i++){
dac_array[i]=(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[i]=1.0;
}
else{
dac_array[i]=0;
}
}
break;
case 4://历史波形删除方波
n3=0;
n2=0;
// for(uint32_t i=0;i<ND2;i++){
// history_dac_array[i]=0;
// }
break;
}
}
DAC定时输出设置、信号幅度测试
//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[n1++]);
R_DAC_Write(&g_dac0_ctrl,dac_value);
//add2**
history_dac_array[n2++]=dac_array[n1-1];
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[n3++]);
R_DAC_Write(&g_dac0_ctrl,dac_value);
if(n3==n2)
n3=0;
}
}
四、实验结果
我这里通过在调试状态更改标记变量的方式,更改DAC输出波形类型,信号幅度、频率,默认DAC历史波形存储深度为12800,超过存储深度后历史波形数据将被新的波形数据覆盖
另外提供了清除历史存储波形的选项。使用e2 studio内置real-time chart来观察DAC信号波形
4.1 GIF演示
4.2 视频演示
|