OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6628|回复: 5

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

[复制链接]

2

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
51
金钱
51
注册时间
2017-2-15
在线时间
8 小时
发表于 2017-2-15 19:20:32 | 显示全部楼层 |阅读模式
1金钱
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];
}
}

最佳答案

查看完整内容[请看2#楼]

F767如果使用DMA的话一定要注意cache的问题。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

88

主题

7377

帖子

5

精华

资深版主

Rank: 8Rank: 8

积分
14980
金钱
14980
注册时间
2013-11-13
在线时间
1823 小时
发表于 2017-2-15 19:20:33 | 显示全部楼层
F767如果使用DMA的话一定要注意cache的问题。
开往春天的手扶拖拉机
回复

使用道具 举报

3

主题

177

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1604
金钱
1604
注册时间
2016-1-28
在线时间
265 小时
发表于 2017-2-15 19:51:41 | 显示全部楼层
帮顶
回复

使用道具 举报

2

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
51
金钱
51
注册时间
2017-2-15
在线时间
8 小时
 楼主| 发表于 2017-2-15 22:29:06 | 显示全部楼层
zuozhongkai 发表于 2017-2-15 20:40
F767如果使用DMA的话一定要注意cache的问题。

关闭cache就正确,多谢楼上的tx。还要在仔细研究。
回复

使用道具 举报

2

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
51
金钱
51
注册时间
2017-2-15
在线时间
8 小时
 楼主| 发表于 2017-2-22 15:03:18 | 显示全部楼层
在数据读取时,先关闭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);
}
回复

使用道具 举报

2

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
51
金钱
51
注册时间
2017-2-15
在线时间
8 小时
 楼主| 发表于 2017-2-22 15:06:14 | 显示全部楼层
当有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位,强制将所有写操作配置为透写属性。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-19 11:50

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表