你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

DMA触发请求异常之案例分享

[复制链接]
accelerating 发布时间:2020-2-18 11:44
某STM32用户开发产品,用到ADC模块,通过定时器更新事件触发AD转换,转换结果由DMA搬运到指定的内存区域。DMA工作在正常模式(即非循环模式),每当传输完毕一批数据后在传输完成中断里设置传输结束标志,应用代码对该标志进行监视。
  ]: q0 V# r/ d( r
当检查到该有效标志时,说明采集到了预定的转换数据。将数据处理后,软件产生TIMER更新事件,以保证计数器从0开始计数【注:这里选用的向上计数模式】。然后清除更新事件标志、ADC转换完成标志位EOC ,关闭DMA后对DMA进行再配置,然后重新使能DMA进行第二次传输。

# W* p& v2 b9 ~6 n/ S9 [
调试中发现,对于第二次DMA传输,每次一使能DMA 就立即搬运一个数据。按理说应该延时一个定时器更新周期后才会搬运首次数据才对。因为软件置位UG位后,用来触发ADC的TIMer是从0开始计数的,需要计数到溢出才会触发AD转换。他想不明白的是  TIM已经复位从0开始计数了,该清的标志位都清除了,还有什么原因导致DMA不等TIMER触发就立即先行搬运一个数据呢。

" ]! l" `# Q8 a
该问题源于本论坛,但用户没有贴出任何代码。这里模拟他的应用场景做个测试验证,并试图找出相关原因。

6 ~8 N, A1 p4 N. t! U8 a6 o
我这里也设计了两轮DMA传输,照样使用TIMER更新事件触发ADC转换。第一轮DMA传输传输3个AD转换结果到某内存地址,第二轮传输5个转换结果到另一内存位置。
- k: D; S9 W2 S
先使用Stm32CubeMx基于STM32F411Discovery板进行基本的初始化配置。配置都很简单。

0 A$ s# |6 c. A. t! q( t) ?
ADC配置,这里只选择1个常规通道用于测试,选择TIM2的触发输出启动AD转换,并开启ADC的DMA传输功能,DMA工作在Normal模式。【硬件上ADC输入通道我直接连VDD了】

7 j2 R% a& p( \/ L: h2 K
11.jpg

  D+ g: r" d0 R8 Z  r- `/ j
TIMER配置,这里选择TIM2,其更新事件做为触发输出用来启动ADC。

; e4 g8 t% `8 X# i) j( d$ B
22.jpg

1 K; H  q, b9 C: w3 t2 N" e, Z
配置完毕后生成初始化代码,然后添加用户代码。
这里准备了几个内存变量.

, \/ a& F, c9 z% Z- D% |1 X
33.jpg

! h, D( [1 g0 Z. i
我在第一次DMA传输完成后立即关闭定时器,在开启第二轮DMA传输前,不让定时器有机会再次触发ADC产生EOC事件。看看有无他说到的情形发生。
" J: K2 B% f& b/ {( `9 x3 h+ m: T
我把用户代码分成两部分,分别用红框、绿框区分。
$ J- B' i5 U8 F) [: P" u0 l4 A
第一部分由基本的初始化函数、开启ADC外设及其DMA功能、对第一次DMA传输做配置并使能DMA、等待3次ADC转换结束。
( x: f; n) x- m- H3 J- |
44.jpg

# k- |/ f! U$ h1 m
第二部分代码的功能主要关闭定时器、关闭DMA,第二次对DMA进行配置,再开启DMA功能并启动定时器。【我把断点打在箭头所指的地方,即待启动计数器的那句代码处】
4 L2 v; u& K6 q* l' E) H' n% y
55.jpg
. V5 s: j/ C  |" G" U1 S  }1 `* |7 J
基于上述代码测试,没有发现一使能第二次DMA传输就先传一个数据的现象。这时定时器也没被启动,DMA处于就绪待命状态。【结果如下图】
$ i5 G7 p9 i: v
66.jpg
# `4 w2 y0 w4 p" p5 O; Q6 T/ T
那客户反馈的情况到底是怎么回事呢?
因为没见到用户具体的代码,他说过在DMA做完第一次传输后,还对定时器做了复位。那我们不妨在第一次DMA传输结束后,增加对定时器的复位操作,看看结果会怎么样。

4 g6 V' s5 q; z5 |. d+ X
我将第二部分代码稍作修改如下【见下图中A处代码】:

& d; E7 t" W7 [3 V7 K) `! A
77.jpg

% J3 U0 s) ]) g- c; `, \6 R* e
基于调整过的代码进行测试,还真发现了一使能第二次DMA传输时就先传一个数据的现象。可是此时定时器仍未启动,DMA怎么就开始传输数据了呢。【结果如下图所示】
! R& E0 |* j/ K2 l; Y9 T
88.jpg

- ~2 g6 J7 Z6 W- I1 Z3 H0 X& X
当然,单纯从DMA传输功能来讲,它跟定时器是否启动并没有必然联系。对于被使能了的DMA,只要有合适的DMA请求出现,它就行使职能。具体到这里,应该是有EOC事件出现了才会发生DMA传输的。那这个EOC事件从哪里来的呢?
我们不妨先理一理:
  Q( U1 F! ^* g+ u( g1 P! R
第一次DMA传输完成后不可能还有待处理EOC事件存在。在第一次DMA传输过程中,每次DMA读取ADC数据就保证EOC被清零了,DMA传输完成后又立即关闭了定时器,本案例里也没有别的事情影响定时器的迅速关闭。按理说在两次DMA传输之间不会有定时器更新事件触发AD转换,更何况在使能第二次DMA前还专门做了EOC的清除操作。
9 Y7 e+ z0 _; s1 I5 I% e
看起来的确有点奇怪,怎么感觉有个DMA请求,用客户的话说,好像潜伏在哪里一样?
目前的代码跟刚开始的比,多了个定时器的复位操作。难道这个复位操作会导致ADC转换而生成EOC事件?说到这,它还真有这本事。
因为软件方式对定时器进行复位也可以产生更新事件,它正好能启动AD转换【AD转换功能一直都没关闭过】从而产生EOC事件。如果EOC标志没有及时清除的话,就可以在下次DMA传输刚被使能,即使计数器还没被启动的条件下触发一次DMA传输。
分析到这里,感觉找到问题原因了。但是,似乎还是有点不对劲。因为即使定时器复位动作产生更新事件而触发ADC转换,进而产生EOC事件, 但我们在定时器复位动作之后还特意做过对EOC标志的清除。【下图中的第二个红圈内的代码】

" e) |: K/ S, R, V% K
99.jpg

5 W+ M' t$ z2 [: Z
难道说这个清除EOC标志的操作有问题?
先确认代码写法本身,没有问题。再看逻辑和时序上问题。
通过进一步的调试,在下图所示代码处放了3个断点单步运行,的确发现定时器复位事件触发了ADC转换,EOC被置位。在后续代码中也发现EOC被清零了。有意思的是,当开着下图所示3个断点来运行时,那个奇怪的现象就消失了,那潜伏的DMA请求似乎遁形了。
& Y% Z+ v7 E; Y7 k6 O+ F7 _! m6 I
10.jpg
+ n; {7 w& T7 |6 N& x& x
如果取消上面的第1、第2个断点后运行代码,那个现象立即又重现,潜伏的又激活了。
反复验证到这里,基本上明白是怎么回事了。
+ ^* a9 C0 K' \7 x" g
毫无疑问,定时器的复位操作导致AD转换而产生了EOC事件。代码里虽然有对EOC的清除操作,但该操作相对ADC而言,太早了点。即在针对EOC做删除操作时,ADC可能还在忙着转换,离产生EOC事件还早呢。这正好可以解释为什么在复位操作代码后放个断点再删除EOC就有效的情形。
4 @3 E$ c1 R' G+ N8 v+ F, l% K* \$ S
既然这样,我在清除EOC操作代码的前面加一句EOC标志查询等待,以保证后续的清除操作可靠有效。我将代码再次做了调整。见下图中方框内代码。
/ }8 q0 K6 i! f  l
111.jpg
# j" B% n: T% E/ r- J
就修改过的代码进行验证,那个现象彻底消失。后续的第二轮DMA传输也规规矩矩了。

+ |3 }* B- r# ~2 `, `
222.jpg

! [( c/ c5 W  M4 s- Y* \
到此,本应用案例分享结束。最后,稍作小结并做些提醒:
" w' j0 ]+ b1 W1 n
333.jpg

* o* h0 M$ H9 C4 B) I5 m. T, T7 ^
1、针对STM32定时器的软件复位操作可以产生更新事件,其效果等同于定时器溢出导致的更新事件。
2、我们编写代码,尤其这种嵌入式代码时,除了保证代码基本的正常逻辑外,各个硬件本身操作时序、响应时间参数等也须多加关注。
3、结合本案例,在第一次DMA传输完成后为第二次DMA做准备时,建议先关闭计数器,否则可能会给我们的应用带来些隐患,本案例中探讨的问题,就是其中隐患之一。限于篇幅和主题,这里就不啰嗦了,后面若有合适案例再行交流。
, ~  M- d2 F0 J2 e! H4 ]) Q5 v/ b% {) Y' B
1 z+ X9 F- }& R! w3 C
收藏 评论1 发布时间:2020-2-18 11:44

举报

1个回答
byronsong 回答时间:2020-2-20 09:45:08
感谢楼主的分享

所属标签

相似分享

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版