这次的实验比较简单,主要目的就是验证一下ADC的中断功能,思路是使用软件触发ADC的连续单通道采样,将采样值通过串口发送到上位机观察数是否正确。
其实官方并不推荐使用中断的方式,这种方式会占用大量的CPU资源,笔者安排这篇文章的主要目的是在使用ADC中断的时候发现了个容易忽略的问题,如下图:
笔者配置了ADC通道12的连续转换并使能了通道中断,关键的点就在中断这里,通过查看SDK中的代码发现,配置后的代码并没有在SDK的初始化代码中使能NVIC中的中断开关,一定要注意在使用中断的时候配置中断优先级以及使能NVIC中的中断开关。
配置代码如下:
void AdcInit(void)
{
//初始化ADC0模块
ADC_DRV_ConfigConverter(INST_ADC_CONFIG_1, &adc_config_1_ConvConfig0);
//ADC0校准
ADC_DRV_AutoCalibration(INST_ADC_CONFIG_1);
//设置抢占中断优先级
INT_SYS_SetPriority(ADC0_IRQn, 12); //设置中断优先级
INT_SYS_EnableIRQ(ADC0_IRQn); //使能ADC0中断,如果使用中断必须使能
}
主程序代码如下:
uint16_t adcSel12Value = 0;
//ADC0中断服务程序
void ADC0_IRQHandler(void)
{
ADC_DRV_GetChanResult(INST_ADC_CONFIG_1, 0U, &adcSel12Value);
}
int main(void)
{
McuInit(); // 芯片基础初始化:时钟、GPIO、中断使能
SysTickBegin(); // SysTick定时器计时初始化
Lpuart1Init(); //LPUART的初始化
AdcInit(); //初始化ADC
//软件启动ADC0
ADC_DRV_ConfigChan(INST_ADC_CONFIG_1, 0U, &adc_config_1_ChnConfig0);
while (1)
{
printf("The Sel12 Volt is %d\r\n", adcSel12Value);
DelayMsFromSysTick(300);
}
}