OpenEdv-开源电子网

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

ADC取样时间短的话DMA中断函数进入不了解决及DMA按需要启动

[复制链接]

3

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
74
金钱
74
注册时间
2016-9-23
在线时间
21 小时
发表于 2016-9-30 15:05:25 | 显示全部楼层 |阅读模式
        新手一枚,所以会出各种各样低级问题,觉得反而更有借鉴意义,分享出来,希望对新学STM32的同学有帮助。

问题描述:
   使用ADC单独连续模式,DMA循环模式运行,调试时发现,若设置ADC取样时间很短将影响DMA传输中断函数的进入,ADC取样时间可选:3、15、28、56、84、112、144、480个时钟周期,实验发现,若选最低的3个或15个时钟周期作为取样时间,则DMA传输中断函数不能进入,若选择28个时钟周期及以后的6种取样时间,均可正常进入DMA传输中断函数。
     
      
结论:
         经仿真显示,ADC状态寄存器ADC_SR的OVE位置1,说明ADC数据丢失溢出,通过调试非循环模式DMA启动经验,将DMA初始化(启动)置于ADC初始化(启动)前,问题解决。所以ADC的溢出发生在ADC启动后DMA配置过程中,若设置取样时间长的话,问题被避开了,但取样时间短的话,会造成溢出。


DMA按照需要启动需注意事项:
        1、DMA传输完成中断函数里面对ADC的CR2寄存器DMA位置0,即关闭ADC的DMA传输;
                 void DMA2_Stream0_IRQHandler(void)                                                                            //ADC3的DMA中断服务函数
                        {
                          u8    k;  
                              if ((DMA_GetITStatus(DMA2_Stream0, DMA_IT_TCIF0) != RESET))                        //传输完成标志且数据转移至缓存区后允许将数据存入缓冲区
                                  {
                                    
                                      ADC_DMACmd(ADC3, DISABLE);                                                               //关闭ADC的DMA传输
                                      Disc_Times++;                                                                                      //记录进入中断的次数
                                      for(k=0;k<16;k++)                                                                                //将数据转移,防止被下一轮写入冲掉                                                              
                                             {            
                                                 PDChnl[2].SampleValue[k]=ADC3_ConvertedValue[k];        
                                             }
                                        DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0);                            //清除传输中断标志位
                                   }
                          }
         2、DMA启动前对通道传输数据的数量重新加载    DMA2_Stream0->NDTR = 0X10;
         3、ADC的DMA启动前对ADC状态寄存器ADC_SR的溢出位OVE置0,ADC3->SR &=~0X1<<5 ;确保程序长期稳定运行,取样时间短时,容易发现问题;取样时间长时,程序运行几分钟后才会出错,容易忽视;
             DMA2_Stream0->NDTR = 0X10;                 //重新装填DMA需要传输的数据个数
             DMA_Cmd(DMA2_Stream0, ENABLE);          //先使能DMA通道
             ADC3->SR &=~0X1<<5 ;                         //将由硬件置1的ADC状态寄存器的溢出标志位清除,不然容易出错
             ADC_DMACmd(ADC3, ENABLE);                 //再使能ADC的DMA传输
            


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

3

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
74
金钱
74
注册时间
2016-9-23
在线时间
21 小时
 楼主| 发表于 2017-2-21 14:16:42 | 显示全部楼层
ADC3->SR &=~(0X1<<5) ;这一行应该加个括号;
实际后来测试过程中将DMA配置放在ADC转换开启之前一般不会出问题,所以以上帖子好像误导不少人,非常抱歉,以后尽量搞明白再发帖。
回复 支持 反对

使用道具 举报

3

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
74
金钱
74
注册时间
2016-9-23
在线时间
21 小时
 楼主| 发表于 2017-2-21 14:20:02 | 显示全部楼层
ADC开启不是指
ADC_Cmd(ADC2, ENABLE);            //使能ADC2       
而是指
ADC_SoftwareStartConv(ADC2);   //ADC软件转换开启              

在频繁开启关闭ADC和DMA时才会出问题,每秒几千次的开闭。         
回复 支持 反对

使用道具 举报

23

主题

344

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2315
金钱
2315
注册时间
2017-7-6
在线时间
281 小时
发表于 2017-8-21 09:29:57 | 显示全部楼层
楼主写的不错,我在F429的时候也是遇到这个问题,我也是把DMA初始化放在ADC初始化后面,出现溢出。改了 我再试试,另外你用了DMA为啥还在中断里面把ADC3_ConvertedValue[k]拷贝到PDChnl[2].SampleValue[k],直接配置存储器地址为PDChnl[2].SampleValue[k],不就好了吗?
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-18 10:36

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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