来源:转载自21ic论坛极海半导体专区
最近在编写DMA_ADC例程的过程中出现了一个中断配置的问题,在ADC采集过程中,结合手册进行ADC连续转换模式配置采集,手册上给出需要进行中断配置的信息,但是真实情况不需要进行中断配置也可以进行ADC连续转换采集,因此,我没过滤掉ADC采集中开启中断配置的信息,开启了ADC中断采集,因此这次以APM32F411官方例程中的DMA_ADC例程,复刻了此次出现的问题。
2、基于APM32F411 DMA_ADC例程问题复刻
/*!
* [url=home.php?mod=space&uid=247401]@brief[/url] ADC Init
*
* @param None
*
* @retval None
*/
void ADC_Init(void)
{
GPIO_Config_T gpioConfig;
ADC_Config_T adcConfig;
/* RCM Enable*/
RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOA);
/* GPIO Configuration */
GPIO_ConfigStructInit(&gpioConfig);
gpioConfig.pin = GPIO_PIN_0;
gpioConfig.mode = GPIO_MODE_AN;
gpioConfig.pupd = GPIO_PUPD_NOPULL;
GPIO_Config(GPIOA, &gpioConfig);
RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_ADC1);
/* ADC Configuration */
ADC_Reset();
ADC_ConfigStructInit(&adcConfig);
/* Set resolution*/
adcConfig.resolution = ADC_RESOLUTION_12BIT;
/* Set dataAlign*/
adcConfig.dataAlign = ADC_DATA_ALIGN_RIGHT;
/* Set scanDir*/
adcConfig.scanConvMode = DISABLE;
/* Set convMode continous*/
adcConfig.continuousConvMode = ENABLE;
/* Set extTrigEdge*/
adcConfig.extTrigEdge = ADC_EXT_TRIG_EDGE_NONE;
/* Set nbrOfConversion*/
ADC_Config(ADC1, &adcConfig);
ADC_ConfigRegularChannel(ADC1, ADC_CHANNEL_0, 1, ADC_SAMPLETIME_112CYCLES);
NVIC_EnableIRQRequest(ADC_IRQn,0x00,0x00);
ADC_EnableInterrupt(ADC1,ADC_INT_EOC);
ADC_EnableDMA(ADC1);
ADC_EnableDMARequest(ADC1);
/* Enable ADC*/
ADC_Enable(ADC1);
ADC_SoftwareStartConv(ADC1);
}
根据上述复刻代码,在ADC_Init()代码配置中,使用NVIC申请中断号,使能中断,但是在中断服务函数中,我并没有进行内容处理。
3、问题定位及疑惑
当出现问题时,因为首先Debug进行单步调试,程序卡死时,出现以下的信息定位:
当程序出现问题时,我首先定位的信息便是Internal:Mode->Handler,Stack->MSP->0x20000400,同时Debug Faults中,SCB->DFSR寄存器的值为0x00000001。首先,模式由Thread变成Handler,这个变化可以说明当前程序由普通用户运行的代码变成了异常程序处理的代码。其次,看到SCB寄存器的内容,结合内核手册中的一些信息,如下:
DFSR->HALTED寄存器位置为1,从手册内容表示,CPU被调试器喊停,但被调停是因为什么原因呢?这个需要进一步分析,如下:
DFSR寄存器中HALTED寄存器被置位是因为在NVIC中进行了HALT的请求,然后我回顾了以下程序,在ADC初始化中进行了NVIC的请求,因为程序在ADC进行采集时,会一直跳进中断程序。记录到这里,我已经对问题进行了确认。因为在ADC配置中开启了中断,当中断开启后,请求了HALT,并且CPU响应了这次请求对ADC的中断服务函数进行处理,但我并没有对ADC的中断服务函数进行处理与ADC采集为连续配置模式,因此程序一直处在Handler模式与线程模式下的切换。并且结合.s启动文件可知,如下:
Default_Handler PROC
EXPORT ADC_IRQHandler [WEAK]
当我通过申请使能中断后,MCU会通过传入的中断号,并计算出偏移量,加载到中断向量表中(这个后面计划出一个启动文件分析,到时在细讲)。当MCU相应中断使能时,程序切换至Handler模式时,PC便将这个地址当做入口,跳入中断服务函数并执行。如下图形式(仅举例):
同时,因为我初始的程序并没有对ADC_Handler模式进行定义处理,同时导致MCU在响应中断后进不了中断服务函数,从而一致卡死在汇编语言B.处,类似C语言中的while(1);,从而产生死循环。
注:文章作者在原帖中提供了例程文件,有需要请至原文21ic论坛下载
原文地址:https://bbs.21ic.com/icview-3329454-1-1.html
-
adc
+关注
关注
99文章
6729浏览量
549610 -
中断
+关注
关注
5文章
906浏览量
42905 -
函数
+关注
关注
3文章
4384浏览量
65121 -
dma
+关注
关注
3文章
576浏览量
103463
原文标题:APM32芯得 EP.57 | 基于APM32F411 DMA_ADC Handler模式分析及解决
文章出处:【微信号:geehysemi,微信公众号:Geehy极海半导体】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
极海APM32F411微控制器硬件FPU使用指南

为APM32F411打造可自动化的命令行工作流

正式发布 | 极海APM32F411系列高适配型MCU,均衡功耗、性能与成本

充能新时代 | 基于APM32F411的EV交流充电桩应用方案

TinyMaix框架的内存需求超过了APM32F411的可用内存,导致运行失败,怎么能成功优化?
【极海APM32F030R8 MINI开发板试用体验】+官方dma接收usart程序软件
STM32F030 ADC DMA乱序问题
极海半导体推出APM32F411系列高性能高适配型MCU

APM32F411板的python+pyocd命令行操作

评论