STM767 ADC+DMA 采样结果读取后,采样结果不更新

2019-07-20 16:41发布

ADC+DMA中断方式,只要在回调函数中读取了数据结果缓冲,ADC_Value_arr_buff[i]=ADC_Value_arr[i],后续ADC采样结果就不更新,如果不读取数据,采用仿真方式,ADC一直在更新数据,代码如下:
void ADC_Init_One(void)
{
    ADC_ChannelConfTypeDef ADC1_ChanConf;
   ADC_MultiModeTypeDef multimode;

   GPIO_InitTypeDef GPIO_Initure;
    __HAL_RCC_ADC1_CLK_ENABLE();            //ʹÄÜADC1ʱÖÓ
    __HAL_RCC_GPIOA_CLK_ENABLE();         //¿ªÆôGPIOAʱÖÓ
   __HAL_RCC_GPIOB_CLK_ENABLE();         //¿ªÆôGPIOAʱÖÓ


   ADC1_Handler.Instance=ADC1;
    ADC1_Handler.Init.ClockPrescaler=ADC_CLOCK_SYNC_PCLK_DIV4;  //4·ÖƵ£¬ADCCLK=PCLK2/4=108/4=27MHZ
    ADC1_Handler.Init.Resolution=ADC_RESOLUTION_12B;            //12λģʽ
    ADC1_Handler.Init.DataAlign=ADC_DATAALIGN_RIGHT;            //ÓÒ¶ÔÆë
    ADC1_Handler.Init.ScanConvMode=ENABLE;//DISABLE;                     //·ÇɨÃèģʽ
    ADC1_Handler.Init.EOCSelection=DISABLE;//ENABLE;//DISABLE;                     //¹Ø±ÕEOCÖжÏ
    ADC1_Handler.Init.ContinuousConvMode=ENABLE;//ENABLE;//ENABLE;               //¹Ø±ÕÁ¬Ðøת»»
    ADC1_Handler.Init.NbrOfConversion=7;                        //1¸öת»»ÔÚ¹æÔòÐòÁÐÖÐ Ò²¾ÍÊÇֻת»»¹æÔòÐòÁÐ1
    ADC1_Handler.Init.DiscontinuousConvMode=DISABLE;//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;//DISABLE;            //¹Ø±ÕDMAÇëÇó
    HAL_ADC_Init(&ADC1_Handler);                                //³õʼ»¯     

GPIO_Initure.Pin=GPIO_PIN_0|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_8|GPIO_PIN_9;    //PA5+PA6+PA7+PA8
    GPIO_Initure.Mode=GPIO_MODE_ANALOG;                              //Ä£Äâ
    GPIO_Initure.Pull=GPIO_NOPULL;                                   //²»´øÉÏÏÂÀ
    HAL_GPIO_Init(GPIOA,&GPIO_Initure);

   
  
  ADC1_ChanConf.Channel=ADC_CHANNEL_0;                        //ͨµÀ
    ADC1_ChanConf.Rank=1;                                       //1¸öÐòÁÐ
    ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_480CYCLES;        //²ÉÑùʱ¼ä
    ADC1_ChanConf.Offset=0;                 
    HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf);        //ͨµÀÅäÖ
  
  
  ADC1_ChanConf.Channel=ADC_CHANNEL_3;                        //ͨµÀ
    ADC1_ChanConf.Rank=2;                                       //1¸öÐòÁÐ
    ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_480CYCLES;        //²ÉÑùʱ¼ä
    ADC1_ChanConf.Offset=0;                 
    HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf);        //ͨµÀÅäÖ
  
    ADC1_ChanConf.Channel=ADC_CHANNEL_4;                        //ͨµÀ
    ADC1_ChanConf.Rank=3;                                       //1¸öÐòÁÐ
    ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_480CYCLES;        //²ÉÑùʱ¼ä
    ADC1_ChanConf.Offset=0;                 
    HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf);        //ͨµÀÅäÖÃ

   ADC1_ChanConf.Channel=ADC_CHANNEL_5;                        //ͨµÀ
    ADC1_ChanConf.Rank=4;                                       //1¸öÐòÁÐ
    ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_480CYCLES;        //²ÉÑùʱ¼ä
    ADC1_ChanConf.Offset=0;                 
    HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf);        //ͨµÀÅäÖÃ


   ADC1_ChanConf.Channel=ADC_CHANNEL_6;                                   //ͨµÀ
    ADC1_ChanConf.Rank=5;                                       //1¸öÐòÁÐ
    ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_480CYCLES;        //²ÉÑùʱ¼ä
    ADC1_ChanConf.Offset=0;                 
    HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf);        //ͨµÀÅäÖÃ
  
  
  ADC1_ChanConf.Channel=ADC_CHANNEL_8;                                   //ͨµÀ
    ADC1_ChanConf.Rank=6;                                       //1¸öÐòÁÐ
    ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_480CYCLES;        //²ÉÑùʱ¼ä
    ADC1_ChanConf.Offset=0;                 
    HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf);        //ͨµÀÅäÖÃ

  ADC1_ChanConf.Channel=ADC_CHANNEL_9;                                   //ͨµÀ
    ADC1_ChanConf.Rank=7;                                       //1¸öÐòÁÐ
    ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_480CYCLES;        //²ÉÑùʱ¼ä
    ADC1_ChanConf.Offset=0;                 
    HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf);        //ͨµÀÅäÖÃ
  HAL_ADC_Start_DMA(&ADC1_Handler, ADC_Value_arr,14);  
}

void DMA_Config(void)
{
     __HAL_RCC_DMA2_CLK_ENABLE(); //DMA2ʱÖÓʹÄÜ  
     __HAL_RCC_DMA1_CLK_ENABLE(); //DMA1ʱÖÓʹÄÜ
     ADC1DMA_Handler.Instance=DMA2_Stream0;                          //Êý¾ÝÁ÷Ñ¡Ôñ
   ADC1DMA_Handler.Init.Channel=DMA_CHANNEL_0;                      //ͨµÀÑ¡Ôñ
     ADC1DMA_Handler.Init.Direction=DMA_PERIPH_TO_MEMORY;             //ÍâÉèµ½´æ´¢Æ÷
     ADC1DMA_Handler.Init.PeriphInc=DMA_PINC_DISABLE;                 //ÍâÉè·ÇÔöÁ¿Ä£Ê½
     ADC1DMA_Handler.Init.MemInc=DMA_MINC_ENABLE;                     //´æ´¢Æ÷ÔöÁ¿Ä£Ê½
     ADC1DMA_Handler.Init.PeriphDataAlignment=DMA_PDATAALIGN_WORD;    //ÍâÉèÊý¾Ý³¤¶È:8λ
     ADC1DMA_Handler.Init.MemDataAlignment=DMA_MDATAALIGN_WORD;       //´æ´¢Æ÷Êý¾Ý³¤¶È:8λ
     ADC1DMA_Handler.Init.Mode=DMA_CIRCULAR;//DMA_NORMAL;                            //ÍâÉèÁ÷¿Øģʽ
     ADC1DMA_Handler.Init.Priority=DMA_PRIORITY_MEDIUM;               //ÖеÈÓÅÏȼ¶
     ADC1DMA_Handler.Init.FIFOMode=DMA_FIFOMODE_DISABLE;              
     ADC1DMA_Handler.Init.FIFOThreshold=DMA_FIFO_THRESHOLD_FULL;      
     ADC1DMA_Handler.Init.MemBurst=DMA_MBURST_SINGLE;                 //´æ´¢Æ÷Í»·¢µ¥´Î´«Êä
     ADC1DMA_Handler.Init.PeriphBurst=DMA_PBURST_SINGLE;              //ÍâÉèÍ»·¢µ¥´Î´«Êä   
     HAL_DMA_DeInit(&ADC1DMA_Handler);   
     HAL_DMA_Init(&ADC1DMA_Handler);
   __HAL_LINKDMA(&ADC1_Handler,DMA_Handle,ADC1DMA_Handler);        //½«DMAÓëADC1ÁªÏµÆðÀ´   
  // __HAL_DMA_ENABLE_IT(&ADC1DMA_Handler,DMA_IT_TC)   
   HAL_NVIC_SetPriority(DMA2_Stream0_IRQn,0,0);
   HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
}

void  HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
  u8 i;
// HAL_ADC_Stop_DMA(&ADC1_Handler);

for(i=0;i<14;i++)
  {
      ADC_Value_arr_buff[i]=ADC_Value_arr[i];
}
}

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
5条回答
taizonglai
1楼-- · 2019-07-20 21:03
 精彩回答 2  元偷偷看……
15623052920
2楼-- · 2019-07-21 02:49
帮顶
moga
3楼-- · 2019-07-21 04:26
zuozhongkai 发表于 2017-2-15 20:40
F767如果使用DMA的话一定要注意cache的问题。

关闭cache就正确,多谢楼上的tx。还要在仔细研究。
moga
4楼-- · 2019-07-21 05:53
在数据读取时,先关闭dCache,读完后打开,数据读取就正常。
void  HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
  u8 i;
        SCB_DisableDCache();
        for(i=0;i<14;i++)
  {       
      ADC_Value_arr_buff[i]=ADC_Value_arr[i];
        }
        SCB_EnableDCache();
        //DMA_Config();
        //ADC_Init_One();
        //HAL_ADC_Start_DMA(&ADC1_Handler, ADC_Value_arr,14);
}
moga
5楼-- · 2019-07-21 10:12
当有CPU和其它主设备【如DMA】共同访问某可缓存的二级存储器比方SRAM1,同时该存储器又具有回写属性,此时就可能发生数据一致性问题。因为该存储器的回写属性,导致通过CPU欲写入存储器的数据只是缓冲在CACHE里,而没有及时写入存储器。如果此时DMA访问该二级存储器的话,读到的数据可能跟预期不一致。
    为了避免数据不一致的问题,我们需要做D-CACHE维护操作。一般有如下四种方法:
1、当对一个可缓存的二级存储器做了写数据操作之后,通过软件对D-CACHE进行清除操作,即运行SCB_CleanDCache()。这样将CACHE里的缓存内容写回到二级存储器,比如把那些DIRTY CACHE行的数据写进SRAM1。
2、通过MPU调整可缓存存储器的存储属性,将其CACHE使用方式改为透写模式。这样保证每次写入CACHE里的内容也同时写入二级存储器,比如写进SRAM1。
3、通过MPU调整可缓存存储器的存储属性,将其共享属性改为可共享的【SHAREABLE】。此后该二级存储器将变为不可缓存。
4、通过配置CACR寄存器中的D-CACHE位,强制将所有写操作配置为透写属性。

一周热门 更多>