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

【经验分享】STM32的USART DMA传输

[复制链接]
STMCU小助手 发布时间:2022-1-14 23:02
问题描述:
     我有一个需求,AD采得一定数目的数据之后,由串口DMA发出,由于AD使用双缓冲,所以每次开始DMA的时候都需要重新设置开始的内存地址以及传输的数目(这些都是理所当然的),但是在开始调试的时候,遇到了一些问题,问题如下:当第一次DMA传输完毕,关闭DMA以设置内存地址等,再开启DMA,发现不启动了。
      开始是参考了《STM32中文参考手册REV10》,里面的发送步骤如下:
  1. 1. 在DMA控制寄存器上将USART_DR寄存器地址配置成DMA传输的目的地址。在每个TXE事件后,数据将被传送到这个地址。5 c  x( \- o& z4 X2 Y
  2. 2. 在DMA控制寄存器上将存储器地址配置成DMA传输的源地址。在每个TXE事件后,将从此存储器区读出数据并传送到USART_DR寄存器。
    . r  P: N9 f) u& X, _; D  l8 n
  3. 3. 在DMA控制寄存器中配置要传输的总的字节数。
    7 @5 S9 `; A* n/ K9 o- Y& l$ t1 J
  4. 4. 在DMA寄存器上配置通道优先级。) t4 C% P* R7 h. r% h/ F
  5. 5. 根据应用程序的要求,配置在传输完成一半还是全部完成时产生DMA中断。0 r6 g% a  S4 E1 O/ {: s3 D
  6. 6. 在DMA寄存器上激活该通道。
复制代码

# Z0 Z! B7 {  V  y& h$ e2 @
检查代码,发现没问题,但是问题还是解决不了,就找了英文的参考手册(REV14),发现上面的步骤有了些修改:
  1. 1. Write the USART_DR register address in the DMA control register to configure it as the- }7 w. W3 I7 |" E; S
  2. destination of the transfer. The data will be moved to this address from memory after
    / N* V. G% c2 N1 U
  3. each TXE event.% b  I& r' X3 B' C2 \% S/ l
  4. 2. Write the memory address in the DMA control register to configure it as the source of
      k2 \+ Y5 s2 c% W+ I" M
  5. the transfer. The data will be loaded into the USART_DR register from this memory
      f- a2 R7 @/ O$ w  U5 q8 F
  6. area after each TXE event.
      s. t5 n! u' \# }
  7. 3. Configure the total number of bytes to be transferred to the DMA control register.6 E+ O; t2 S7 p
  8. 4. Configure the channel priority in the DMA register
    2 G6 c  V% c3 W0 F! e
  9. 5. Configure DMA interrupt generation after half/ full transfer as required by the
    " T' Z: c3 g, A( I+ m; }4 T2 Y
  10. application.
    5 ^# h6 [2 V* M6 i3 V
  11. 6. Clear the TC bit in the SR register by writing 0 to it.1 e* F$ C" r8 M
  12. 7. Activate the channel in the DMA register.
    : t& L$ `6 Y/ O$ ], b% K
  13. When the number of data transfers programmed
复制代码

! N6 \) l( Y# Z2 w- A) _+ Q, z
多了一步,即第6步,清除SR寄存器的TC标志位。照做,ok了。

$ X7 n( ]) n- T- `重启DMA传输成功的条件:
后来,又做了其他一些测试,发现即使不清除TC标志位,只要把对应DMA通道的TCIF标志(传输完成标志,DMA_ISR寄存器里面)清除,同样也可以正常重启传输。所以,要重启传输,保证在重新ENABLE DMA之前,满足以下两个条件之一即可:
  • DMA_ISR 对应的TCIF标志清除
  • USART_SR 的TC标志位清除
    " O7 W6 Z9 ]) I
一个诡异的问题:
发现即使上面提到的两个条件都不满足,但是下面的代码依然可以正常传输:
4 @# l4 T, {+ J$ i+ D
  1. //ENBALE 之前USART1的TC,DMA1 对应USART TX的DMA通道TC标志都已经置位,没有清除
    " k" [: s! f) l+ e5 I4 `' n
  2.                 DMA_Cmd(USART1_Tx_DMA_Channel, ENABLE);3 @5 R# S/ B1 U  g! c6 z4 |* H; q0 {
  3.                 while((USART1->SR & USART_FLAG_TC) == 0x00);
复制代码

( z+ {( i# s$ s% T9 _. F' F' F2 p
这样也可以。但是只要换成:
  1.                 DMA_Cmd(USART1_Tx_DMA_Channel, ENABLE);
    2 E# O/ E9 H' ?4 k1 f
  2.                 : D3 A6 r4 a( y0 P
  3.                 /* Wait until USARTy TX DMA1 Channel Transfer Complete */
    $ F9 ?* g: L/ n1 s$ x6 W% c) x
  4.                 while (DMA_GetFlagStatus(USART1_Tx_DMA_FLAG ) == RESET) {/ H9 w2 |5 F4 N* D- `
  5.                 }
复制代码

" v. Q5 s6 E: O0 U) p( c
就不行了。比较奇怪。
( B& Z, v8 x; ~# K& w
结论:
不管那些诡异的问题了,以后重启DMA之前,清除串口的TC或者DMA的TC。不过根据使用的感觉,清除DMA的TC简单些。
4 K: M( @/ O8 r; I5 v2 y* l% W# @0 z
收藏 评论0 发布时间:2022-1-14 23:02

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版