• 已解决 73482 个问题
  • 已帮助 5993 位优秀工程师

ADC和DMA使用,调用下面这函数死机了。

黄莨元 2017-05-01 浏览量:2286
想用ADC采集,采集的结果通过DMA传输,在主函数中调用下面这两个函数,然后就死机了,没有使用DMA中断,能帮看看配置出了啥问题吗,谢谢,单片机是STM32F412

#include "adc.h"
#include "main.h"
	
ADC_HandleTypeDef  ADC1_Handler;       //ADC¾ä±ú
DMA_HandleTypeDef  ADC1TxDMA_Handler; //DMA¾ä±ú

//ch: ADC_channels 
//ͨµÀÖµ 0~16È¡Öµ·¶Î§Îª£ºADC_CHANNEL_0~ADC_CHANNEL_16
void MY_ADC_Init(void)
{ 
    ADC1_Handler.Instance=ADC1;
    ADC1_Handler.Init.ClockPrescaler          = ADC_CLOCK_SYNC_PCLK_DIV4;   //4·ÖƵ   ADCʱÖÓΪ25M
    ADC1_Handler.Init.Resolution              = ADC_RESOLUTION_12B;             //12λģʽ
    ADC1_Handler.Init.DataAlign               = ADC_DATAALIGN_RIGHT;             //ÓÒ¶ÔÆë
    ADC1_Handler.Init.ScanConvMode            = DISABLE;                      //·ÇɨÃèģʽ
    ADC1_Handler.Init.EOCSelection            = DISABLE;                      //¹Ø±ÕEOCÖжÏ
    ADC1_Handler.Init.ContinuousConvMode      = ENABLE;                //¹Ø±ÕÁ¬Ðøת»»
    ADC1_Handler.Init.NbrOfConversion         = 1;                         //1¸öת»»ÔÚ¹æÔòÐòÁÐÖÐ Ò²¾ÍÊÇֻת»»¹æÔòÐòÁÐ1 
    ADC1_Handler.Init.DiscontinuousConvMode   = DISABLE;             //½ûÖ¹²»Á¬Ðø²ÉÑùģʽ
    ADC1_Handler.Init.NbrOfDiscConversion     = 0;                     //²»Á¬Ðø²ÉÑùͨµÀÊýΪ0
    ADC1_Handler.Init.ExternalTrigConv        = ADC_SOFTWARE_START;       //Èí¼þ´¥·¢
    ADC1_Handler.Init.ExternalTrigConvEdge    = ADC_EXTERNALTRIGCONVEDGE_NONE;//ÎÞÍⲿ´¥·¢×ª»»
    ADC1_Handler.Init.DMAContinuousRequests   = ENABLE;             //¹Ø±ÕDMAÇëÇó
	  ADC1_Handler.Init.EOCSelection            = DISABLE;
    HAL_ADC_Init(&ADC1_Handler);                                 //³õʼ»¯ 
}

//ADCµ×²ãÇý¶¯£¬Òý½ÅÅäÖã¬Ê±ÖÓʹÄÜ
//´Ëº¯Êý»á±»HAL_ADC_Init()µ÷ÓÃ
//hadc:ADC¾ä±ú
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
    GPIO_InitTypeDef GPIO_Initure;
	
    __HAL_RCC_ADC1_CLK_ENABLE();            //ʹÄÜADC1ʱÖÓ
    __HAL_RCC_GPIOC_CLK_ENABLE();			      //¿ªÆôGPIOCʱÖÓ
	
    GPIO_Initure.Pin    = GPIO_PIN_0;            //PC0
    GPIO_Initure.Mode   = GPIO_MODE_ANALOG;     //Ä£Äâ
    GPIO_Initure.Pull   = GPIO_NOPULL;          //²»´øÉÏÏÂÀ­
    HAL_GPIO_Init(GPIOC,&GPIO_Initure);
		
}

void MY_DMA_Config(void)
{
	
		__HAL_RCC_DMA2_CLK_ENABLE();                                  //DMA2ʱÖÓʹÄÜ	
		__HAL_LINKDMA(&ADC1_Handler,DMA_Handle,ADC1TxDMA_Handler);    //½«DMAÓëADC1ÁªÏµÆðÀ´(·¢ËÍDMA)
	
    ADC1TxDMA_Handler.Instance                 = DMA2_Stream0;                 //Êý¾ÝÁ÷Ñ¡Ôñ
    ADC1TxDMA_Handler.Init.Channel             = DMA_CHANNEL_0;                //ͨµÀÑ¡Ôñ
    ADC1TxDMA_Handler.Init.Direction           = DMA_PERIPH_TO_MEMORY;         //ÍâÉèµ½´¢´æÆ÷
    ADC1TxDMA_Handler.Init.PeriphInc           = DMA_PINC_DISABLE;             //ÍâÉè·ÇÔöÁ¿Ä£Ê½
    ADC1TxDMA_Handler.Init.MemInc              = DMA_MINC_DISABLE;             //´æ´¢Æ÷ÔöÁ¿Ä£Ê½
    ADC1TxDMA_Handler.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;      //ÍâÉèÊý¾Ý³¤¶È:16λ
    ADC1TxDMA_Handler.Init.MemDataAlignment    = DMA_PDATAALIGN_HALFWORD;      //´æ´¢Æ÷Êý¾Ý³¤¶È:16λ
    ADC1TxDMA_Handler.Init.Mode                = DMA_CIRCULAR;                 //Ñ­»·Ä£Ê½
    ADC1TxDMA_Handler.Init.Priority            = DMA_PRIORITY_MEDIUM;          //¸ßÓÅÏȼ¶
    ADC1TxDMA_Handler.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;              
    ADC1TxDMA_Handler.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_HALFFULL;      
    ADC1TxDMA_Handler.Init.MemBurst            = DMA_MBURST_SINGLE;              //´æ´¢Æ÷Í»·¢µ¥´Î´«Êä
    ADC1TxDMA_Handler.Init.PeriphBurst         = DMA_PBURST_SINGLE;              //ÍâÉèÍ»·¢µ¥´Î´«
		
//		HAL_DMA_DeInit(&ADC1TxDMA_Handler);
    HAL_DMA_Init(&ADC1TxDMA_Handler);

}



0 0 收起

我来回答

上传资料:
选择文件 文件大小不超过15M(格式支持:doc、ppt、xls、pdf、zip、rar、txt)
最佳答案
  • 这是我F429采集ADC的代码,楼主可以照着来改,ADC-DMA卡死只跟是否连续转换有关系,跟NVIC的设置是没有任何关系的,NVIC是设置优先级的,优先级低了顶多不能调用而已,并不会卡死,楼主可以把ADC语句跟NVIC的有关设置的语句全部删掉或者像MOP姐那样设置为0,1​,即可解决问题。

    • 发布于 2017-05-06
    • 举报
    • 评论 0
    • 0
    • 0

其他答案 数量:3
  • 你这里使能了中断,有可能是进了中断了吧。可以发一下中断函数看看。

    你可以仿真一下,看看死机后是停在了哪里。

    • 发布于2017-05-01
    • 举报
    • 评论 1
    • 0
    • 0
黄莨元 回复了 汉云 :我把中断设置那两个函数不要了,也是不可以啊,也会死机 回复

  • 你是不是使用了cubemx?

    cubemx里面要将中断打开,就是那个NVIC的设置那里

    • 发布于2017-05-01
    • 举报
    • 评论 3
    • 0
    • 0
黄莨元 回复了 chen0000009 :可以不打开中断的吧,我把NVIC设置那里不要了,也是死机呢 回复
chen0000009 回复了 chen0000009 :不是,你必须要使能NVIC那里的那个中断,不然用不了 回复
黄莨元 回复了 chen0000009 :不一定要使能中断吧,DMA中断只是检查传输完成的状态,我调用HAL_DMA_Init(&ADC1TxDMA_Handler);这个语句就会死机了 回复

  • 關鍵在於這一行

    HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 1, 1);
    預設是

    HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0);
    所以沒有主要次序的,您只能設定

    HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 1);
    以上供您參考

    • 发布于2017-05-02
    • 举报
    • 评论 2
    • 0
    • 0
黄莨元 回复了 MOP :谢谢回答,我把程序改了不开中断了,但是也不行啊,DMA中断只是检查传输完成的状态 回复
MOP 回复了 黄莨元 :要開中斷的喔,我是只用CubeMX產生的Code,就已經有中斷囉,反推理回去沒開應該無法正常工作,您可以實驗看看^__^ 回复

相关问题

问题达人换一批

ADC和DMA使用,调用下面这函数死机了。