【Follow me第二季第3期】DAC配置生成波形及性能测试
[复制链接]
本帖最后由 breeze_i 于 2024-12-17 21:25 编辑
简介:本次实验使用RA6M5的片内外设DAC模块,产生三角波和正弦波,驱动LED,实现呼吸灯效果。
打开用户手册,找到DAC模块,框图如下:
可以看到,这是一个转换精度12为的ADC,有两路输出,在原理图中看到DA0对应的引脚是P014。本次将DAC输出通过杜邦线连接到LED3上。
二、模块配置
打开e2studio,如图打开FSP配置界面:添加DAC模块。
三、三角波、正弦波实现
第一个DAC_output()是三角波,第二个函数DAC_output_sineware()是生成正弦波。
- fsp_err_t DAC_output(void)
- {
- static int16_t a=1;
- gs_dac_value=(uint16_t)(gs_dac_value+a);
- if(gs_dac_value>=0x0FFF)
-
- {
- a = -1;
- }
- else if (gs_dac_value == 0)
- {
- a = 1;
- }
-
- fsp_err_t status = R_DAC_Write(&g_dac0_ctrl, gs_dac_value);
-
- return status;
- }
-
- fsp_err_t DAC_output_Sinewave(void)
- {
- fsp_err_t ret;
- uint64_t currenttime=gs_dwTick;
-
- uint64_t t_ms=(currenttime-gs_starttime);
- double t_s =(double)t_ms/1000;
- DAC_value=(uint16_t)((sin(t_s)+1)/2*4096);
- ret = R_DAC_Write(&g_dac0_ctrl, DAC_value);
- return ret;
- }
四、实验现象
使用杜邦线将P014和P008短接,将工程中P008引脚去使能,即保持在高阻态。
1.在10ms任务中调用三角波生成函数DAC_outoput();实验现象如视频所示(可能是白天太亮了,手机摄像头录的LED3变化不明显)。
播放器加载失败: 未检测到Flash Player,请到 安装
20241215_090931
2.在10ms任务中调用三角波生成函数DAC_outoput_Sineware();实验现象如视频所示(这次把旁边的绿色led2关掉试试),可以看到红色LED3的明暗变化,实现了呼吸灯效果,然后打开FreeMaster看一下DAC生成的波形是按照正弦规律变化的。
播放器加载失败: 未检测到Flash Player,请到 安装
20241215_092632
下面配置ADC模块。
按照如下步骤在DAC工程中添加ADC模块
属性设置:
我选用的是Channel0,P000引脚,不使用中断。采样精度选最高的12bit
点击Generate Project Content生成代码。
驱动函数封装
在src文件夹下新adc.h,adc.c两个文件。
adc.c添加代码如下
- #include "adc.h"
- volatile bool scan_complete_flag = false;
- uint16_t gs_adc_value=0;
- void ADC_Init()
- {
- fsp_err_t status = R_ADC_Open(&g_adc0_ctrl, &g_adc0_cfg);
- if(status!=FSP_SUCCESS)
- {
- while(1);
- }
- status = R_ADC_ScanCfg(&g_adc0_ctrl, &g_adc0_channel_cfg);
- if(status!=FSP_SUCCESS)
- {
- while(1);
- }
- }
-
-
-
-
-
- void ADC_READ_DATA()
- {
- fsp_err_t status = R_ADC_ScanStart(&g_adc0_ctrl);
- adc_status_t adc_status;
- do{
- status=R_ADC_StatusGet(&g_adc0_ctrl, &adc_status);
- }while(adc_status.state==ADC_STATE_SCAN_IN_PROGRESS);
-
- {
- status = R_ADC_Read(&g_adc0_ctrl,ADC_CHANNEL_0, &gs_adc_value);
-
- }
- }
注意ADC转换需要时间,尽管只要0.4us,但这个时间对mcu来说还是很长的,在开始扫描之后需要等待转换完成之后,才能读取到数据。
然后再在hal_entry()函数中中调用ADC_Init()函数,初始化ADC模块。
在1ms任务中调用ADC 读取函数
使用Freemaster观测dac模块设定输出值和adc模块采集到的电压值,可以看到两条曲线基本重合,说明dac模块的输出还是挺准的。
|