野火启明6M5开发板的 ADC 电位器电路图如图所示。
可知,开发板板载的电位器连接到 P000 引脚, P000 引脚可以连接到MCU内部的 ADC 外设,从而对电位器输入的模拟信号进行采集。
ADC
├─ ......
└─ src
├─ led
│ ├─ bsp_led.c
│ └─ bsp_led.h
├─ debug_uart
│ ├─ bsp_debug_uart.c
│ └─ bsp_debug_uart.h
├─ adc
│ ├─ bsp_adc.c
│ └─ bsp_adc.h
└─ hal_entry.c
打开该工程的 FSP 配置界面进行配置。
首先依次点击 “Stacks” -> “Pins” -> “Peripherals” -> “ADC0” 来配置通道 AN000 对应的引脚为 P000。 如下图所示。
然后依次点击 “Stacks” -> “New Stack” -> “Analog” -> “ADC (r_adc)” 来配置ADC模块。 如下图所示。
ADC 的属性配置:
配置完成之后可以按下快捷键“Ctrl + S”保存, 最后点右上角的 “Generate Project Content” 按钮,让软件自动生成配置代码即可。
void ADC_Init(void)
{
fsp_err_t err;
err = R_ADC_Open(&g_adc0_ctrl, &g_adc0_cfg);
err = R_ADC_ScanCfg(&g_adc0_ctrl, &g_adc0_channel_cfg);
assert(FSP_SUCCESS == err);
}
R_ADC_Open()为整个外设设置操作模式、触发源、中断优先级和配置。如果启用了中断,该函数将注册一个回调函数指针,以便在扫描完成时通知用户。
R_ADC_ScanCfg()配置ADC扫描参数。通道特定设置是在这个函数中设置的。
//ADC转换完成标志位
volatile bool scan_complete_flag = false;
void adc_callback(adc_callback_args_t * p_args)
{
FSP_PARAMETER_NOT_USED(p_args);
scan_complete_flag = true;
}
在FSP配置页面注册回调函数以及优先级,就可以使用来自ADC的中断回调函数了。
Tips: 通过ADC的中断回调函数来判断ADC是否转换完成。 需要定义了一个布尔类型的数据scan_complete_flag来当做ADC读取完成的标志位。 当没有转换完成的时候scan_complete_flag的值一直为false,单ADC触发中断的时候将scan_complete_flag的值变为true。
如果未启用中断,则可使用R_ADC_StatusGet() API 用于轮询 ADC 以确定扫描何时完成。读取 API 函数用于访问转换后的 ADC 结果。这适用于支持校准的MCU的普通扫描和校准扫描。
ADC读取思路,在这里调用R_ADC_ScanStart触发相应的adc通道转换,当ADC转换完成之后会将scan_complete_flag标志位变为true。 当判断到标志位变为true后使用R_ADC_Read()或R_ADC_Read32()读取转换完成的数值。
/* 进行ADC采集,读取ADC数据并转换结果 */
double Read_ADC_Voltage_Value(void)
{
uint16_t adc_data;
double a0;
(void)R_ADC_ScanStart(&g_adc0_ctrl);
while (!scan_complete_flag) //等待转换完成标志
{
;
}
scan_complete_flag = false; //重新清除标志位
/* 读取通道0数据 */
R_ADC_Read(&g_adc0_ctrl, ADC_CHANNEL_0, &adc_data);
/* ADC原始数据转换为电压值(ADC参考电压为3.3V) */
a0 = (double)(adc_data*3.3/4095);
return a0;
}
R_ADC_ScanStart()启动软件扫描或启用扫描的硬件触发器,具体取决于触发器在R_ADC_Open调用中的配置方式。如果该单元被配置为ELC或外部硬件触发,那么该功能允许触发信号到达ADC单元。该函数不能控制触发器本身的生成。如果该单元被配置为软件触发,则该功能启动软件触发扫描。
R_ADC_Read()从单通道或传感器寄存器读取转换结果,返回的数据为uint16_t型。
R_ADC_Read32()从单通道或传感器寄存器读取转换结果,返回的数据为uint32_t型。
void hal_entry(void)
{
LED_Init(); // LED 初始化
Debug_UART4_Init(); // SCI4 UART 调试串口初始化
/* ADC 初始化 */
ADC_Init();
printf("这是一个读取电位器ADC电压转换值的例程\r\n");
printf("打开串口助手查看ADC转换结果,旋钮电位器,可以看到ADC值在一定范围之内发生变化\r\n");
printf("开始读取ADC转换值:\r\n");
while(1)
{
printf("a0 = %f\r\n", Read_ADC_Voltage_Value());
R_BSP_SoftwareDelay(500, BSP_DELAY_UNITS_MILLISECONDS); //大概0.5秒钟读取一次
LED1_TOGGLE;
}
#if BSP_TZ_SECURE_BUILD
/* Enter non-secure code */
R_BSP_NonSecureEnter();
#endif
}