软件部分
将先前的项目模板复制一份,重命名为02_DAC-ADC-Voltage
1. 配置DAC
先进入Pins页面
序号 | 操作 |
---|---|
1 | 点击界面下方标签栏中的Pins 标签,进入引脚配置界面。 |
2 | 在Pin Selection 区域,展开Analog 选项,选择Analog:DAC 下的DAC0 。 |
3 | 在Pin Configuration 区域,将Operation Mode 设置为Enabled 。 |
4 | 在Pin Configuration 区域,勾选DAC0 对应的P014 引脚。 |
再来到Stacks页面
序号 | 操作 |
---|---|
1 | 点击界面下方标签栏中的Stacks 标签,进入堆栈配置页面。 |
2 | 在HAL/Common Stacks 区域,点击New Stack 按钮。 |
3 | 在弹出菜单中,选择Analog 选项。 |
4 | 在Analog 子菜单中,选择DAC (r_dac) 。 |
最后配置DAC的属性
序号 | 操作 |
---|---|
1 | 在HAL/Common Stacks 区域,点击选中g_dac0 DAC (r_dac) 。 |
2 | 在下方Settings 设置区域,Module g_dac0 DAC (r_dac) 部分,确认Name 为g_dac0 ,Channel 为0 。 |
3 | 在Settings 设置区域的Pins 部分,确认DAC0 对应P014 。 |
2. 配置ADC
进入Pins页面
序号 | 操作 |
---|---|
1 | 点击界面下方标签栏中的Pins 标签,进入引脚配置界面。 |
2 | 在Pin Selection 区域,展开Analog:ADC 选项,选择ADC0 。 |
3 | 在Pin Configuration 区域,将Operation Mode 设置为Custom 。 |
4 | 在Pin Configuration 区域,勾选AN000 对应的P000 引脚。 |
进入Stacks页面
序号 | 操作 |
---|---|
1 | 点击界面下方标签栏中的Stacks 标签,进入堆栈配置页面。 |
2 | 在HAL/Common Stacks 区域,点击New Stack 按钮。 |
3 | 在弹出菜单中,选择Analog 选项下的ADC (r_adc) 。 |
序号 | 操作 |
---|---|
1 | 在Settings 设置区域的Module g_adc0 ADC (r_adc) - General 部分,设置Name 为g_adc0 ,Unit 为0 。 |
2 | 在Settings 设置区域的Module g_adc0 ADC (r_adc) - General 部分,设置Mode 为Single Scan 。 |
序号 | 操作 |
---|---|
1 | 在Settings 设置区域的Input - Channel Scan Mask (channel availability varies by MCU) 部分,勾选Channel 0 。 |
序号 | 操作 |
---|---|
1 | 在Settings 设置区域的Interrupts 部分,设置Normal/Group A Trigger 为Software 。 |
2 | 在Settings 设置区域的Interrupts 部分,设置Callback 为adc0_callback ,Scan End Interrupt Priority 为Priority 2 。 |
3 | 在Settings 设置区域的Pins 部分,确认AN000 对应P000 。 |
配置完成后,生成项目代码。
3. 编写代码
3.1 新建adc.h
新建文件adc.h
,加入以下代码
c
#ifndef ADC_H_
#define ADC_H_
void adc0_waitComplete();
#endif
3.2 新建adc.c
这段代码中实现了adc的回调函数adc0_callback
,当ADC扫描完成时会自动调用。在回调函数中将标志位scan_complete_flag
设为true,以便adc0_waitComplete
函数退出死循环。
新建文件adc.c
,加入以下代码
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 修改hal_entry.c
在这里要实现用DAC输出电压,ADC采集电压,每隔200ms递增或递减一次DAC输出的电压值,同时打印到串口。 在hal_entry.c
的文件开头加入:
c
#include "adc.h"
uint16_t adc_data = 0;
在hal_entry函数
中加入:
c
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库的函数编程,一样的。 例如
c
g_dac0.p_api->write(&g_dac0_ctrl, dac_value);
就可以用FSP库代替
c
R_DAC_Write(&g_dac0_ctrl, dac_value);