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

【MCU实战经验】STM32F407的串口编程经验

[复制链接]
wdzfd 发布时间:2014-4-8 22:02
HAL驱动的串口编程陷阱
  a" a+ U- D9 G! _, ]# |
' e, ?" K+ ?: Y3 Q7 N$ CSTM32远程升级(基于串口本地升级与WiFi通信远程升级)
9 V0 S/ a0 m! A, O5 e
# H2 ]: }/ P0 j6 U0 u2 T9 d0 _- j
8 G+ _% b8 Y" I" I
& p& Z/ M- \; F: z
串口是嵌入式开发中最常前的外设设备,既可以用作不同单片机之间的通信,也可以用作在STM32 MCUPC机之间的通信,STM32F407的串口功能非常强大,可以接红外,可以接流控,也可以接SIM卡接口,但我这里只介绍我们最常用的UART通信的一点调试经验,以STM32F407为例,对其它STM32芯片也适用,希望对大家有所帮助,如有错误不当之处欢迎大家联系指正。
  m$ p1 F! l7 C1 J! I& w" \
: B$ n' u5 N3 b) p$ v% I一、串口的三种工作方式8 K9 G8 \. O6 ?+ ]- m, l3 m1 Z
操作串口一般有两种方式:查询和中断;STM32还支持第三种DMA方式。( p! _7 z1 g( _0 M8 ]
1)查询:串口程序不断地循环查询标志,看看当前有没有数据要它传送或接收。如果有的话进行相应的写操作和读操作进行传送或接收数据。
- }& Y* b# g' S- T. h2中断:平时串口只要打开中断即可。如果发现有一个中断来,则意味着有数据需要接收(接收中断)或数据已经发送完成(发送中断)。5 N0 L$ w4 R% H  H8 f+ k
3DMA方式,设置好DMA工作方式,由DMA来自动接收或发送数据。
/ e$ f) J2 ^& f) v3 R一般来说,查询方式的效率是比较低的,并且由于STM32UART硬件上没有FIFO,如果程序功能比较多,查询不及时的话很容易出现数据丢失的现象, 故实际项目中这种方式用的并不多。
+ }8 @" x7 }3 w- w7 n4 q* Q2 {中断方式的话我们可以分别设置接收中断和发送中断,当串口有数据需要接收时才进入中断程序进行读读操,这种方式占用CPU资源比较少,实际项目中比较常用,但需要注意中断程序不要太复杂使执行时间太长,如果执行时间超过一个字符的时间的话也会出现数据丢失的现象,这个波特率比较高的串口编程中比较容易出现,可以考虑用循环BUF方法,在中断程序中只负责实时地接收实数数和发送时的填数(写发送寄存器),其它操作放在中断外处理。
% S) m& [2 `. F" n1 a. h1 ]; p9 tSTM32还提供了第三种DMA方式用来支持高速地串口传输。这种方式只要设置好接收和发送缓冲位置,可以由DMA来自动接收和发送数据,这可以最小化占用CPU时间。
$ Y: q; O1 k: R% X
1 ~. i- L9 n# F, d5 o+ ~二、串口的使用步骤: Y( H' @3 T" [
1)中断方式8 W" X7 q5 r( I! ~/ k; B$ |
基本步骤是初试化时钟,脚位、波特率设置、安装中断服务程序、开中断等,参考代码如下:
# R& a8 Z4 }$ e# g1 |0 x) V4 o5 I2 b) ?9 d( m
  1. void uart_init(void)
    7 Q, d& {9 z( ~3 H  g! Y, R
  2. {; i3 o, D5 E/ T' F
  3.    USART_InitTypeDef USART_InitStructure;
    8 j4 n) z7 ~3 L' Q
  4.   NVIC_InitTypeDef NVIC_InitStructure;
    / R& ]* \) R+ d0 u+ s! z7 [1 P5 h
  5.   GPIO_InitTypeDef  GPIO_InitStructure;1 R/ v. H& C; k* K
  6.    : Z& \: p% Y# W; Z/ b7 y$ _
  7.   /* Enable GPIO clock  */
    , [- B- l6 i( X7 a- |) j( q0 ~) Q
  8.    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);2 l& t8 B5 T% ], b7 U4 O3 G" N2 \
  9.   
    3 f' @5 W$ N* o# o) ]2 K; B* }2 ?
  10.    /* Enable USART clock */4 P$ b7 n/ C. @9 s) E) z& K, p0 i5 A
  11.    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
    : |' V1 ]% T) ^6 b2 ^
  12.   / L8 ]* h! k2 i. O# p
  13.    /* Connect USART pins to AF7 */
    1 b3 w- @0 Z+ g; J% V
  14.    GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_USART3);
    ! E& N" B7 p, {9 v/ j
  15.   GPIO_PinAFConfig(GPIOC, GPIO_PinSource11,  GPIO_AF_USART3);: d' ^8 j; t1 I6 @! X$ c* T+ V
  16.    , u: J. w6 F3 B8 ?# U3 z
  17.   /* Configure USART Tx and Rx as  alternate function push-pull */
    # ~9 p# S# j$ |6 h
  18.    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;5 i9 f& Q2 K/ r- b: M+ g4 U6 T
  19.   GPIO_InitStructure.GPIO_Speed =  GPIO_Speed_100MHz;
    " }( w* n& g6 J* ?. B
  20.    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    ' y- E5 J" r2 c- R
  21.   GPIO_InitStructure.GPIO_PuPd =  GPIO_PuPd_UP;
    5 E4 s* C: ^; A$ ^) A  r: h  r
  22.    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;9 ^- U+ P: z( Q, d! H' C
  23.   GPIO_Init(GPIOC,  &GPIO_InitStructure);
    7 i1 r' ?  w  x5 L" P
  24.    
    , N! j4 G0 i! d
  25.   GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_11;
    * ]6 C9 k. `) n; q5 a$ a  J
  26.   GPIO_Init(GPIOC,  &GPIO_InitStructure);* ]: u* h) f( Z" W2 E* z
  27.   /*  USARTx configuration  ----------------------------------------------------*/
    " m! X% f5 B- X& P
  28.   /* USARTx configured as follow:
    , Y8 V+ q& u/ y1 |4 f5 X7 V
  29.         - BaudRate = 3750000 baud
    9 W9 D. P. s/ K8 y
  30.   - Maximum BaudRate that can be achieved when  using the Oversampling by 8" E& I* d; J. b  p
  31.      is: (USART APB Clock / 8) 9 h: E; F8 S4 |; c, B4 [7 @' t
  32. Example:
    4 I3 k/ |; e; i( Q
  33.    - (USART3 APB1  Clock / 8) = (30 MHz / 8) = 3750000 baud' \  `3 ]5 h2 h$ Q
  34.    - (USART1 APB2 Clock / 8) = (60 MHz / 8) = 7500000  baud! h6 W/ t* D& M$ w! ?0 k5 `2 K
  35.   - Maximum BaudRate that can  be achieved when using the Oversampling by 16
    : W( j) M2 L5 ?8 k
  36.     is: (USART APB Clock / 16) 0 U. u# \2 \9 x9 J+ V
  37. Example: (USART3 APB1 Clock / 16) = (30 MHz / 16)  = 1875000 baud
    ( A  ?9 S1 E' n( b, l+ e8 ]
  38. Example: (USART1  APB2 Clock / 16) = (60 MHz / 16) = 3750000 baud
    ; q7 p3 s3 `. c; k8 w+ h$ |
  39.         - Word Length = 8 Bits5 V5 c6 a2 J- F, y: w2 D1 S1 f/ J$ U- z5 B
  40.         - one Stop Bit
    ) q: B% k* O: y! Q& G0 C+ N; K
  41.         - No parity
    ' z1 I& R& o, C+ N6 F7 S
  42.         - Hardware flow control disabled (RTS and  CTS signals)1 H/ H+ v7 U3 F  ^
  43.         - Receive and  transmit enabled
    ! Z- `1 a$ f4 }4 L1 C
  44.    */
    ! i$ X4 u/ x& Q5 K
  45.    USART_InitStructure.USART_BaudRate = 115200;
    ; L) \/ O" W+ U
  46.   USART_InitStructure.USART_WordLength =  USART_WordLength_8b;
      x7 c% V0 I1 h: g& g9 m
  47.    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    . F- {/ ?4 c( v
  48.   USART_InitStructure.USART_Parity =  USART_Parity_No;6 G% }' i$ _1 u- z. P; V, j
  49.    USART_InitStructure.USART_HardwareFlowControl =  USART_HardwareFlowControl_None;; K- m  S" h5 Z, I1 n" F- J
  50.    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    * B- A2 |9 e7 A" _( E
  51.   USART_Init(USART3,  &USART_InitStructure);6 I4 y* J) ^9 r3 f  L4 V
  52.    
    - T7 E% p* k$ z: B5 y& v9 G9 Q7 e
  53.   /* NVIC configuration  */7 K& q: `4 e1 ?: a* [' L+ N/ W
  54.   /* Configure the Priority  Group to 2 bits */
    ( C" k5 m4 P  M: s! d# _
  55.    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);% V+ ?/ {" \, }9 e7 Q: D& W
  56.   . m/ G/ w4 d1 \
  57.    /* Enable the USARTx Interrupt */
    8 z2 O" o9 D" Z" Q% y
  58.   NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;* h. r3 v) i$ C; z4 t
  59.    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;* |! E1 Z5 W9 F7 w/ R
  60.   NVIC_InitStructure.NVIC_IRQChannelSubPriority =  0;
    ! j+ F: ~5 u3 `1 G
  61.    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;1 Y; q  X7 T2 @  [1 ]3 p2 z1 m
  62.    NVIC_Init(&NVIC_InitStructure);
    ' d8 n9 \3 r* P1 C- c) D
  63.   
    ) V; H+ C6 K9 p6 w6 W
  64.   /* Enable USART  */7 @$ ^0 w% |- i0 L
  65.   USART_Cmd(USART3,  ENABLE);
    - u% {9 R2 @. @) m* I2 D
  66.   USART_ITConfig(USART3,  USART_IT_RXNE, ENABLE);8 }& F# W6 S5 D' ?
  67. }
    - M! b8 E- a( Z
复制代码

9 B  r; G8 d3 q9 n+ a+ Z; `中断服务程序如下:, F+ h+ f" H2 B0 N; w& [
  1. void USART3_IRQHandler(void)2 d; u/ O: G( s3 ~8 P$ [3 j
  2. {
    / T. O4 s. H* d' m+ c% w
  3. unsigned char ch;  
    6 A' {( w: [/ n9 M- z# J5 v3 o
  4. if(USART_GetITStatus(USART3,  USART_IT_RXNE) != RESET); a4 `& m; B, u8 v! y
  5.    {
    0 c( f3 W9 b. h, X# O+ e8 V
  6.     /* Read one byte from the  receive data register */) V2 l4 T" t! \
  7.     ch =  (USART_ReceiveData(USART3));* N2 k9 |. v' n8 g/ f
  8. 4 {/ H5 X6 V* {3 [5 H
  9.      printf("in[%c].\r\n",ch);
    & X* N$ g0 R! d- F
  10.   }   
    " d" |5 E; q% J
  11. }
复制代码
" [7 D( }) k" ]+ `4 U

# Q- L' c# v7 g- d* M直接把接收到的字符打印出来。
9 z. o; n" u( _) _# T
; p: X, v1 P4 p7 M" N2DMA方式- x5 j' z# `) v* q6 u
基本步骤同中断方式,额外需要DMA的初始化配置,参考代码如下:& |! z# C- t& W' a. o  t' s
  1. void  uart_init(void)
    9 B6 g1 k6 O3 d9 A! \+ a! @& N
  2. {) T8 z# }2 a0 i: ]/ Z
  3.   USART_InitTypeDef  USART_InitStructure;
    & ~% Q0 p! P: b0 V7 H
  4.    NVIC_InitTypeDef NVIC_InitStructure;& R$ _( _  I, t( D9 p0 i$ r
  5.   GPIO_InitTypeDef GPIO_InitStructure;
    8 ^6 o; D1 c0 C/ Y8 ~$ n( o2 F
  6.   DMA_InitTypeDef DMA_InitStruct;
    / b  j7 c! _% l9 {/ I5 V: W
  7.   
    . e' c( x4 ^- T. N) ]( S
  8.    /* Enable GPIO clock */
    1 z: f! U9 k7 l: D5 B
  9.    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);7 X( e7 w8 {' C( k. b* C8 l
  10.   
    ( E) g+ H9 A" S$ H, f6 e
  11.    /* Enable USART clock */. u7 J8 o: M! L& B, v6 [
  12.    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);" ^/ i& H: f, @+ C! d
  13.   
    ) u+ L9 t$ D1 C/ y: Z3 C
  14.    /* Connect USART pins to AF7 */
    " q+ j& W2 |% b0 O
  15.    GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_USART3);
    $ H& D0 |4 r- _
  16.   GPIO_PinAFConfig(GPIOC, GPIO_PinSource11,  GPIO_AF_USART3);
    % }7 W* \" z. |' h
  17.    
    4 T5 \. c. R( m8 }/ v$ [  ]
  18.   /* Configure USART Tx and Rx as  alternate function push-pull */; p/ Y8 ~6 I1 S5 X
  19.    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;: o9 s' j9 p- e, ?# x
  20.   GPIO_InitStructure.GPIO_Speed =  GPIO_Speed_100MHz;' j. G1 f6 D7 X# V+ g3 c
  21.    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;& B& [& v2 E4 x: F: I" l
  22.   GPIO_InitStructure.GPIO_PuPd =  GPIO_PuPd_UP;
    3 p8 W6 ^: H+ w3 w/ i/ D
  23.    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    6 m/ V( i' s6 w3 x# e+ c0 [
  24.   GPIO_Init(GPIOC,  &GPIO_InitStructure);/ Q: [, A  e7 {8 L3 J
  25.    7 H: j; E5 U+ W2 b
  26.   GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_11;7 r) p. B% e8 [( j( D0 X
  27.   GPIO_Init(GPIOC,  &GPIO_InitStructure);
    * S% c4 F1 ^7 x3 ^6 e; y( M9 y
  28.   /*  USARTx configuration  ----------------------------------------------------*/
    , L, _$ q1 B8 k3 E6 n
  29.   /* USARTx configured as follow:" }) {& n# h5 r* f* U* J3 R7 v, c
  30.         - BaudRate = 3750000 baud
    * K# m3 K" i1 k" A' t9 m# K# O0 a
  31.   - Maximum BaudRate that can be achieved when  using the Oversampling by 8! h1 A$ H$ k1 o0 h2 q
  32.      is: (USART APB Clock / 8) ! |) L4 c5 m) a. c
  33. Example: / H$ z( E* I9 L; b  q6 d
  34.    - (USART3 APB1  Clock / 8) = (30 MHz / 8) = 3750000 baud  s4 n! W  M) b; B7 I! c# b1 @
  35.    - (USART1 APB2 Clock / 8) = (60 MHz / 8) = 7500000  baud
    7 N4 B( W" `- D% H2 R
  36.   - Maximum BaudRate that can  be achieved when using the Oversampling by 16
    / `- J- O0 L2 l9 U9 v( g
  37.     is: (USART APB Clock / 16) / M5 S4 N+ I) T8 W
  38. Example: (USART3 APB1 Clock / 16) = (30 MHz / 16)  = 1875000 baud- K5 G; {4 ?, U+ O$ t6 m5 O
  39. Example: (USART1  APB2 Clock / 16) = (60 MHz / 16) = 3750000 baud& D5 _+ k7 G6 z+ q; U
  40.         - Word Length = 8 Bits
    " a( A% D+ o5 S! g* i8 o  J
  41.         - one Stop Bit
    $ ^8 @7 c3 W$ }) A; f- H6 M! H
  42.         - No parity5 W, M% E# h% t  L
  43.         - Hardware flow control disabled (RTS and  CTS signals)
    & ]7 z$ E4 T  ~8 h
  44.         - Receive and  transmit enabled8 g( Q/ t; ~4 p+ C
  45.    */
    . D5 B7 @, i& P! Z! M/ C
  46.    USART_InitStructure.USART_BaudRate = 115200;
    * g* O% G7 M$ w! O; j
  47.   USART_InitStructure.USART_WordLength =  USART_WordLength_8b;* k# P; L; O( u8 R8 s: R1 C
  48.    USART_InitStructure.USART_StopBits = USART_StopBits_1;1 D: K/ U  ~( [8 q1 c0 y
  49.   USART_InitStructure.USART_Parity =  USART_Parity_No;2 y7 [3 A& p- P0 c  ?+ _
  50.    USART_InitStructure.USART_HardwareFlowControl =  USART_HardwareFlowControl_None;, X; o7 q' a  I
  51.    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;0 g+ O+ E* b3 R" C
  52.   USART_Init(USART3,  &USART_InitStructure);' ~  W1 c7 R7 F9 v, p; H8 Q( d

  53. ' I/ n/ O& K9 i1 y  H( s
  54. /*  DMA_Configuration */" l8 x4 N6 b1 H' o3 h
  55.    DMA_DeInit(DMA1_Stream1); 5 V' i6 P( C9 f
  56.    1 U1 c* F3 p% ~' U
  57.   DMA_InitStruct.DMA_Channel =  DMA_Channel_4;   
    2 r  C1 B% q* {# R- L+ y
  58.    DMA_InitStruct.DMA_PeripheralBaseAddr =  (u32)&USART3->DR; //source  buf
    $ Q. e* }( h3 Z7 h
  59.    DMA_InitStruct.DMA_Memory0BaseAddr = (u8)pdata; //target buf
    , z! Y  w& F3 O2 _1 X9 K) U( |$ I
  60. % D# ]) \# Q4 S7 s; O) U* A
  61.   DMA_InitStruct.DMA_DIR =  DMA_DIR_PeripheralToMemory;! U: }) D  ~3 B. f- P
  62.    DMA_InitStruct.DMA_BufferSize = lenght;  //BuffSize;. E1 ], J6 ]: u) b7 r
  63.   DMA_InitStruct.DMA_PeripheralInc =  DMA_PeripheralInc_Disable; 4 ]; z6 p4 M+ o: z  L7 l; c' {1 ^' ?
  64.    DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
    ; y- V% [0 T+ ?+ J+ n( g/ T$ g1 N
  65.   DMA_InitStruct.DMA_PeripheralDataSize =   DMA_PeripheralDataSize_Word;3 v$ l% @" G9 h. h8 l
  66.    DMA_InitStruct.DMA_MemoryDataSize =  DMA_MemoryDataSize_Byte;
    : U3 A2 W, N: c" d. \; v6 N
  67.   DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;  //DMA_Mode_Normal; ; P2 @* X: ~& @; w' e
  68.    DMA_InitStruct.DMA_Priority = DMA_Priority_High;
    * x( l5 j) C1 t9 T, d, z; y5 d
  69.   DMA_InitStruct.DMA_FIFOMode =  DMA_FIFOMode_Disable;
    : J. ]& J3 ~3 g" h5 p+ }( Z
  70.    DMA_InitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;. Y' A! A: V/ s# m- e
  71.   DMA_InitStruct.DMA_MemoryBurst =  DMA_MemoryBurst_Single;
    " R, ^- P; l, Y
  72.    DMA_InitStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
      P' }0 W9 }# r% L
  73.   DMA_Init(DMA1_Stream1,  &DMA_InitStruct);
    ( s; R  b# w0 Z
  74. 8 S/ p( f1 Y4 C! ^2 |- B
  75.   /* NVIC configuration  */
    - F) C; o; @  \# T$ Z' O! c
  76.   /* Configure the Priority  Group to 2 bits */6 K7 d2 L7 }' @6 t# x
  77.    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    + @) ~# {3 B4 N  F  ]
  78.   + N! t: F9 v( `+ [- `; e
  79.    /* Enable the USARTx Interrupt */( j. c# I; k% Z( c5 g
  80.   NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream1_IRQn;  
    , k) z, q% l) Q+ u% L* Q- W. N
  81.    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    ; C& K+ X# x$ Q
  82.   NVIC_InitStructure.NVIC_IRQChannelSubPriority =  0;1 C" G0 b: E' ]1 h
  83.    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    : R+ `) O+ ?, l% G3 Q/ H
  84.   NVIC_Init(&NVIC_InitStructure);  2 C& Y! ~6 V# ~4 @

  85. 0 j. {& y2 q* r' I& ?! w
  86.   /* Open DMA  interrupt*/: K/ }8 i/ f' _7 i6 I6 v8 |
  87.    DMA_ITConfig(DMA1_Stream1, DMA_IT_TC, ENABLE);# j8 o9 L: u8 m- s, ?) s
  88.   DMA_Cmd(DMA1_Stream1, ENABLE);! x% ]3 V9 ], q# w" l
  89.   USART_Cmd(USART3, ENABLE);
    0 w( ^* d& \, ~
  90.    USART_DMACmd(USART3,USART_DMAReq_Rx,ENABLE);+ m+ h$ C* d7 S# {7 \! c; _
  91. }
复制代码
. s2 Y3 o" m; p
% k* |! R; e  Y0 @! L4 F
DMA中断服务程序如下:3 l5 t* w( D0 }/ u
  1. void DMA1_Stream1_IRQHandler(void) //UART3_RX
    + C" m0 i; X8 L3 h5 T5 D5 U4 K. }
  2. {
    3 S, i& q% i; T( j8 A5 q9 F
  3.      static short i;# \, z& W7 m$ P1 q* P- P

  4. ( T$ P, E6 y2 _7 J- i' \1 j* n; h- ]3 V
  5.     //When a  Transfer Complete6 p$ q( n/ k7 v# Y5 g0 W, x1 J
  6. if(SET ==  DMA_GetITStatus(DMA1_Stream1, DMA_IT_TCIF1))
    & C! S& D. X; ~' E6 b; G1 s
  7. {2 z# \" [9 @6 k$ f
  8. DMA_ClearITPendingBit(DMA1_Stream1, DMA_IT_TCIF1);
    2 K  B( G- _9 }( p7 J3 F5 G6 u# U
  9. i++;0 d9 Q3 N7 P- o7 k% i
  10. }
    # U9 v2 w$ P2 E9 n
  11. }
复制代码

$ H4 g! x) ?, G7 F4 c% ^( u/ S6 V
上面程序只配了DMA接收,发送类似。( ~$ p( l, h. z( b0 A* K

4 F3 r; _" {: G/ w: ^9 d
2 [& I3 q0 j2 y2 [6 k三、实现DMX512协议: X4 z$ U" I: d9 Y; {
DMX512 协议是美国剧场技术协会( United States Institute for Theater Technology,  USITT) 制定的数字多路复用协议, 其制定的初衷是为了使舞台、剧场等地所使用的众多的调光器和控制器能相互兼容。虽然它不是一个行业或国家标准, 但是由于它的简单性和实用性, 自从出台以来, 得到了世界各地生产商和使用者普遍承认,这个协议在LED控制方面应用很广泛,利用STM32 USART可以高速传输的特性,我们很容易用STM32来实现DMX512协议。
( L; J( |+ ?$ i  H+ `1)数据的格式及传输6 {- Z( B, _# I* z/ I( A. }
DMX512  协议规定数据以数据包的形式通过异步通讯的方式进行传输。每个数据包由若干数据帧组成, 每帧数据包括1 位低电平起始位、8 位数据位和2 位高电平停止位。DMX 协议要求数据传输的波特率为250kb/s, 亦即每位的传输时间为4us, 每帧数据的传输时间为44us, 它支持多达512 帧数据传输, 每帧数据与相应的控制支路相对应。数据包的传送要符合一定的格式和时序要求。为了使接收器能够分辨出第一帧数据, 每一个数据包以一个不短于88us 的低电平信号为起始信号, 即所谓的“Break”信号, 接收器接收到“Break”信号就准备接受随后而来的数据帧; 紧接着“Break”信号之后是不短于8us 的高电平信号M. a. b ( Mark after  Break) ; 之后就是数据帧。在DMX512 协议中, M. a. b 之后的第一帧数据被称& A7 \: T# u6 ~5 Z  W' j
为“Star-t code, 在协议中规定其为零, 但在实际应用中可以由生产厂家自己确定其具体的值,  以传递特殊消息。“Star-t  code”标明其后面的数据是8  位控制信号数据帧。数据帧之间可以有时间间隔, 也可以没有;  同样, 数据包之间可以有时间间隔, 也可以没有。DMX512 协议规定“Break”信号、M. a. b 信号的最短时间, 并规定“Break”信号、M. a. b 信号、9 D; P0 B8 A% z; V. i: Z
数据帧之间及数据包之间的时间间隔的最大值不得超过1s, 否则做出错处理, 但是DMX512 协议并未对出错处理做任何规定。为了严格实现DMX512  数据的时序要求,“Break”和M.  a. b信号我们可以用定时器来实现。
. q" y4 a$ [! e/ u( a7 v  N" K2 j  S具体的UART配置如下:- s8 a" i7 @0 T/ C" i1 K
  
  1. USART_InitStructure.USART_BaudRate =  250000;
    + p( |& v( w( b0 ~) s" t3 a
  2.    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    / Z+ x4 X0 X" }6 a1 u6 p/ g3 g3 E4 t
  3.   USART_InitStructure.USART_StopBits =  USART_StopBits_2;
    4 p  r8 I# t; E9 R4 K% f" @. G0 W1 \
  4.    USART_InitStructure.USART_Parity = USART_Parity_No;
    0 f7 O; u2 A/ T% X4 {1 H8 j
  5.   USART_InitStructure.USART_HardwareFlowControl =  USART_HardwareFlowControl_None;
    9 A$ w) H3 `$ S) Z! i* O% u' T; ~
  6.    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    ! t# r8 ^9 h7 p5 ~  h% w+ g3 c. \
  7.   USART_Init(USART1,  &USART_InitStructure);
复制代码
# |  b7 z, y1 a# v" r. m

& ^/ u  v7 U8 I% X6 G2 p0 b0 I, H4 j5 v
发送DMX512信号过程如下,先把UARTTX脚配置为普通的GPIO并输出低电平,然后启动定时器计时88us,  时器到后把TX脚置为高电平并计时8us, 时器到了后在配为UART模式用DMA方式把数据发出。4 g' E: T( t" y( I) O% A& q
DMX512信号的接收是个难点,一般直接配为UART接收就行,不需要在UART模式和GPIO模式间切换,但需要在接收过程中检查接收到“Break”信号时的状态是有帧错误出现,并且接收数据全为零,这样的话可以确认已经收到“Break”信号,随后数据正常DMA接收就行了。
7 ~0 a; [) z9 ?( B( I4 @; ^- K3 L8 T% F; H% G0 K/ t
1 收藏 4 评论3 发布时间:2014-4-8 22:02

举报

3个回答
lyzd 回答时间:2018-6-29 09:43:46
很全哦。。。
radio2radio 回答时间:2018-6-29 10:40:13
串口编程,我的经验是:
' H% k& E! @' L* P3 X5 {7 [* @1. 使用已经调试好的例程,特别是参考官方例程包。
2 T+ B+ i# b8 J7 ^" q2. 使用KEIL的RTE配置串口,很好用。
5 d5 P7 W1 J2 E6 m, n3. 使用CubeMX配置串口,也很好用。
SZHYK 回答时间:2019-7-27 16:10:25
谢谢分享!!
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版