瑞萨单片机论坛
直播中

VR小杰

未满1年用户 59经验值
擅长:控制/MCU
私信 关注
[经验]

【瑞萨RA2L1入门学习】02、DAC电压输出及ADC电压采集实验

1 前言

本次实验内容是先用DAC做电压输出,再用ADC进行电压采集,最后在串口打印查看。

2 硬件部分

2.1 DAC

DAC 为数字/模拟转换模块,故名思议,它的作用就是把输入的数字编码,转换成对应的模拟电压输出,它的功能与 ADC 相反。在常见的数字信号系统中,大部分传感器信号被化成电压信号,而 ADC 把电压模拟信号转换成易于计算机存储、处理的数字编码,由计算机处理完成后,再由 DAC 输出电压模拟信号,该电压模拟信号常常用来驱动某些执行器件,使人类易于感知。如音频信号的采集及还原就是这样一个过程。
RA2L1开发板搭载的R7FA2L1AB2DFL芯片拥有12位的DAC。

2.2 ADC

ADC 即模拟-数字转换器(Analog-to-digital converter), 是一种用于将连续的模拟信号转换为离散的数字信号的器件。 就比如我们可以将我们生活中的温度、压力、声音这样的模拟信号通过 ADC 转化为可以通过单片机处理的数字信号。
RA2L1开发板搭载的R7FA2L1AB2DFL芯片拥有12位的ADC。

3 软件部分

将先前的P项目模板复制一份,重命名为02_DAC-ADC-Voltage

3.1 配置DAC

先进入Pins页面

序号 操作
1 点击界面下方标签栏中的Pins标签,进入引脚配置界面。
2 Pin Selection区域,展开Analog选项,选择Analog:DAC下的DAC0
3 Pin Configuration区域,将Operation Mode设置为Enabled
4 Pin Configuration区域,勾选DAC0对应的P014引脚。

DAC配置1.jpg

再来到Stacks页面

序号 操作
1 点击界面下方标签栏中的Stacks标签,进入堆栈配置页面。
2 HAL/Common Stacks区域,点击New Stack按钮。
3 在弹出菜单中,选择Analog选项。
4 Analog子菜单中,选择DAC (r_dac)

DAC配置2.jpg

最后配置DAC的属性

序号 操作
1 HAL/Common Stacks区域,点击选中g_dac0 DAC (r_dac)
2 在下方Settings设置区域,Module g_dac0 DAC (r_dac)部分,确认Nameg_dac0Channel0
3 Settings设置区域的Pins部分,确认DAC0对应P014

DAC配置3.jpg

3.2 配置ADC

进入Pins页面

序号 操作
1 点击界面下方标签栏中的Pins标签,进入引脚配置界面。
2 Pin Selection区域,展开Analog:ADC选项,选择ADC0
3 Pin Configuration区域,将Operation Mode设置为Custom
4 Pin Configuration区域,勾选AN000对应的P000引脚。

ADC配置1.jpg

进入Stacks页面

序号 操作
1 点击界面下方标签栏中的Stacks标签,进入堆栈配置页面。
2 HAL/Common Stacks区域,点击New Stack按钮。
3 在弹出菜单中,选择Analog选项下的ADC (r_adc)

ADC配置2.jpg

序号 操作
1 Settings设置区域的Module g_adc0 ADC (r_adc) - General部分,设置Nameg_adc0Unit0
2 Settings设置区域的Module g_adc0 ADC (r_adc) - General部分,设置ModeSingle Scan

ADC配置3.jpg

序号 操作
1 Settings设置区域的Input - Channel Scan Mask (channel availability varies by MCU)部分,勾选Channel 0

ADC配置4.jpg

序号 操作
1 Settings设置区域的Interrupts部分,设置Normal/Group A TriggerSoftware
2 Settings设置区域的Interrupts部分,设置Callbackadc0_callbackScan End Interrupt PriorityPriority 2
3 Settings设置区域的Pins部分,确认AN000对应P000

ADC配置5.jpg

配置完成后,生成项目代码。

3.3 编写代码

3.3.1 新建adc.h

新建文件adc.h,加入以下代码

#ifndef ADC_H_
#define ADC_H_
void adc0_waitComplete();
#endif

3.3.2 新建adc.c

这段代码中实现了adc的回调函数adc0_callback,当ADC扫描完成时会自动调用。在回调函数中将标志位scan_complete_flag设为true,以便adc0_waitComplete函数退出死循环。

新建文件adc.c,加入以下代码

#include "adc.h"
#include "hal_data.h"

volatile static bool scan_complete_flag = true;
void adc0_callback(adc_callback_args_t *p_args)
{
    FSP_PARAMETER_NOT_USED(p_args);
    scan_complete_flag = true;
}

void adc0_waitComplete()
{
    scan_complete_flag = false;
    while (!scan_complete_flag)
    {
        /* Wait for callback to*/
    }
}

3.3.3 修改hal_entry.c

在这里要实现用DAC输出电压,ADC采集电压,每隔200ms递增或递减一次DAC输出的电压值,同时打印到串口。
hal_entry.c的文件开头加入:

#include "adc.h"
uint16_t adc_data = 0;

hal_entry函数中加入:

typedef enum
    {
        up,
        down
    } Direction;
    Direction d = up;
    uint16_t dac_value = 0;
    Debug_UART9_Init(); // SCI9 UART 调试串口初始化
    g_dac0.p_api->open(&g_dac0_ctrl, &g_dac0_cfg);
    g_dac0.p_api->start(&g_dac0_ctrl);

    g_adc0.p_api->open(&g_adc0_ctrl, &g_adc0_cfg);
    g_adc0.p_api->scanCfg(&g_adc0_ctrl, &g_adc0_channel_cfg);
    while (1)
    {
        g_dac0.p_api->write(&g_dac0_ctrl, dac_value);
        g_adc0.p_api->scanStart(&g_adc0_ctrl);
        adc0_waitComplete();
        g_adc0.p_api->read(&g_adc0_ctrl, ADC_CHANNEL_0, &adc_data);
        double volt = (double)(adc_data / 4095.0) * 3.3;
        printf("adc_data: %d, 电压: %.3lf V\n", adc_data, volt);
        if (d == up)
        {
            dac_value += 500;
        }
        else
        {
            dac_value -= 500;
        }
        if (dac_value >= 4000)
        {
            d = down;
        }
        if (dac_value == 0)
        {
            d = up;
        }
        R_BSP_SoftwareDelay(200, BSP_DELAY_UNITS_MILLISECONDS);
    }

注意,这里是用了面向对象的编程方法,参考教程为:《ARM嵌入式系统中面向对象的模块编程方法》基于DShanMCU-RA6M5(瑞萨MCU)
也可以用瑞萨FSP库的函数编程,一样的。
例如

g_dac0.p_api->write(&g_dac0_ctrl, dac_value);

就可以用FSP库代替

R_DAC_Write(&g_dac0_ctrl, dac_value);

4 下载测试

把编译好的程序下载到开发板并复位,将P000引脚与P014引脚短接,打开串口助手,可观察到输出的adc值与算得的电压值。

串口助手.jpg

工程附件

*附件:02_DAC-ADC-Voltage.zip

更多回帖

发帖
×
20
完善资料,
赚取积分