[APM32F4]基于APM32F411 DMA_ADC Handler模式分析及解决

1、前言
    最近在编写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便将这个地址当做入口,跳入中断服务函数并执行。如下图形式(仅举例):

DMA_ADC4.png (43.42 KB )

下载附件

2023-9-25 17:08 上传

 
    同时,因为我初始的程序并没有对ADC_Handler模式进行定义处理,同时导致MCU在响应中断后进不了中断服务函数,从而一致卡死在汇编语言B.处,类似C语言中的while(1);,从而产生死循环。


---------------------
作者:lzh12a3nf
链接:https://bbs.21ic.com/icview-3329454-1-1.html
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值