來源:轉(zhuǎn)載自21ic論壇極海半導體專區(qū)
最近在編寫DMA_ADC例程的過程中出現(xiàn)了一個中斷配置的問題,在ADC采集過程中,結合手冊進行ADC連續(xù)轉(zhuǎn)換模式配置采集,手冊上給出需要進行中斷配置的信息,但是真實情況不需要進行中斷配置也可以進行ADC連續(xù)轉(zhuǎn)換采集,因此,我沒過濾掉ADC采集中開啟中斷配置的信息,開啟了ADC中斷采集,因此這次以APM32F411官方例程中的DMA_ADC例程,復刻了此次出現(xiàn)的問題。
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);
}
根據(jù)上述復刻代碼,在ADC_Init()代碼配置中,使用NVIC申請中斷號,使能中斷,但是在中斷服務函數(shù)中,我并沒有進行內(nèi)容處理。
3、問題定位及疑惑
當出現(xiàn)問題時,因為首先Debug進行單步調(diào)試,程序卡死時,出現(xiàn)以下的信息定位:

當程序出現(xiàn)問題時,我首先定位的信息便是Internal:Mode->Handler,Stack->MSP->0x20000400,同時Debug Faults中,SCB->DFSR寄存器的值為0x00000001。首先,模式由Thread變成Handler,這個變化可以說明當前程序由普通用戶運行的代碼變成了異常程序處理的代碼。其次,看到SCB寄存器的內(nèi)容,結合內(nèi)核手冊中的一些信息,如下:

DFSR->HALTED寄存器位置為1,從手冊內(nèi)容表示,CPU被調(diào)試器喊停,但被調(diào)停是因為什么原因呢?這個需要進一步分析,如下:

DFSR寄存器中HALTED寄存器被置位是因為在NVIC中進行了HALT的請求,然后我回顧了以下程序,在ADC初始化中進行了NVIC的請求,因為程序在ADC進行采集時,會一直跳進中斷程序。記錄到這里,我已經(jīng)對問題進行了確認。因為在ADC配置中開啟了中斷,當中斷開啟后,請求了HALT,并且CPU響應了這次請求對ADC的中斷服務函數(shù)進行處理,但我并沒有對ADC的中斷服務函數(shù)進行處理與ADC采集為連續(xù)配置模式,因此程序一直處在Handler模式與線程模式下的切換。并且結合.s啟動文件可知,如下:
Default_Handler PROC
EXPORT ADC_IRQHandler [WEAK]
當我通過申請使能中斷后,MCU會通過傳入的中斷號,并計算出偏移量,加載到中斷向量表中(這個后面計劃出一個啟動文件分析,到時在細講)。當MCU相應中斷使能時,程序切換至Handler模式時,PC便將這個地址當做入口,跳入中斷服務函數(shù)并執(zhí)行。如下圖形式(僅舉例):

同時,因為我初始的程序并沒有對ADC_Handler模式進行定義處理,同時導致MCU在響應中斷后進不了中斷服務函數(shù),從而一致卡死在匯編語言B.處,類似C語言中的while(1);,從而產(chǎn)生死循環(huán)。
注:文章作者在原帖中提供了例程文件,有需要請至原文21ic論壇下載
原文地址:https://bbs.21ic.com/icview-3329454-1-1.html
-
adc
+關注
關注
100文章
7458瀏覽量
554020 -
中斷
+關注
關注
5文章
913瀏覽量
43598 -
函數(shù)
+關注
關注
3文章
4409瀏覽量
66979 -
dma
+關注
關注
3文章
578瀏覽量
105421
原文標題:APM32芯得 EP.57 | 基于APM32F411 DMA_ADC Handler模式分析及解決
文章出處:【微信號:geehysemi,微信公眾號:Geehy極海半導體】歡迎添加關注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
極海APM32F411微控制器硬件FPU使用指南
為APM32F411打造可自動化的命令行工作流
基于極海APM32F103的USB鍵盤與虛擬串口例程
正式發(fā)布 | 極海APM32F411系列高適配型MCU,均衡功耗、性能與成本
充能新時代 | 基于APM32F411的EV交流充電樁應用方案
TinyMaix框架的內(nèi)存需求超過了APM32F411的可用內(nèi)存,導致運行失敗,怎么能成功優(yōu)化?
【極海APM32F030R8 MINI開發(fā)板試用體驗】+官方dma接收usart程序軟件
STM32F030 ADC DMA亂序問題
APM32F103XC_TMR_關閉DMA進入睡眠模式出現(xiàn)故障
APM32F030C8T6_ADC_ADC連續(xù)轉(zhuǎn)換后DMA只傳輸一次
APM32F030C8T6_ADC_ADC Vref參考電壓數(shù)值讀取出錯
極海半導體推出APM32F411系列高性能高適配型MCU
APM32F411板的python+pyocd命令行操作

基于APM32F411 DMA_ADC Handler模式分析及解決
評論