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

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

[复制链接]
wdzfd 发布时间:2014-4-8 22:02
HAL驱动的串口编程陷阱" q1 _7 F4 {+ p

7 H3 _8 \- A# {. w+ a' Q$ q+ jSTM32远程升级(基于串口本地升级与WiFi通信远程升级)& t( [2 {+ F1 j6 D' S
) U1 F3 b5 x- M/ R+ A! w
5 U1 F5 C  m6 g9 N
4 u$ D6 m2 I; ?* v, _+ G
串口是嵌入式开发中最常前的外设设备,既可以用作不同单片机之间的通信,也可以用作在STM32 MCUPC机之间的通信,STM32F407的串口功能非常强大,可以接红外,可以接流控,也可以接SIM卡接口,但我这里只介绍我们最常用的UART通信的一点调试经验,以STM32F407为例,对其它STM32芯片也适用,希望对大家有所帮助,如有错误不当之处欢迎大家联系指正。
5 ^% x" S( D# F6 ~. d! n# d2 n2 c1 V/ d7 O
一、串口的三种工作方式
4 S$ p! r" q( P操作串口一般有两种方式:查询和中断;STM32还支持第三种DMA方式。
6 r: a& @/ H, e1)查询:串口程序不断地循环查询标志,看看当前有没有数据要它传送或接收。如果有的话进行相应的写操作和读操作进行传送或接收数据。
$ i# d- F5 R. a! l4 u- O2中断:平时串口只要打开中断即可。如果发现有一个中断来,则意味着有数据需要接收(接收中断)或数据已经发送完成(发送中断)。& t" V4 u: W; |5 N* w9 W
3DMA方式,设置好DMA工作方式,由DMA来自动接收或发送数据。
/ h% Y' m+ P  s1 ]( y9 m7 O0 `( N; e一般来说,查询方式的效率是比较低的,并且由于STM32UART硬件上没有FIFO,如果程序功能比较多,查询不及时的话很容易出现数据丢失的现象, 故实际项目中这种方式用的并不多。
# a7 ?; z% ?0 g! J) B+ p中断方式的话我们可以分别设置接收中断和发送中断,当串口有数据需要接收时才进入中断程序进行读读操,这种方式占用CPU资源比较少,实际项目中比较常用,但需要注意中断程序不要太复杂使执行时间太长,如果执行时间超过一个字符的时间的话也会出现数据丢失的现象,这个波特率比较高的串口编程中比较容易出现,可以考虑用循环BUF方法,在中断程序中只负责实时地接收实数数和发送时的填数(写发送寄存器),其它操作放在中断外处理。7 o$ W) B3 C& r' n8 Q* {
STM32还提供了第三种DMA方式用来支持高速地串口传输。这种方式只要设置好接收和发送缓冲位置,可以由DMA来自动接收和发送数据,这可以最小化占用CPU时间。4 S3 I" H$ @: q7 r! Z
& u3 a4 m' W' U; f
二、串口的使用步骤
' Q6 {7 m2 d5 g" q  [( I1)中断方式
$ V( D. [6 G. N; q基本步骤是初试化时钟,脚位、波特率设置、安装中断服务程序、开中断等,参考代码如下:
# A0 X) ?4 t7 F& ]
, Q) \  B* l% b2 a- [- f% i
  1. void uart_init(void); v& l  y, |. q. V& Z9 H, ]
  2. {2 J# X4 o! f5 Q" H5 z) g" k
  3.    USART_InitTypeDef USART_InitStructure;
    ) g1 ~6 }0 ~8 Y) B) H: t' e2 p
  4.   NVIC_InitTypeDef NVIC_InitStructure;# V; h1 K  R+ h" H
  5.   GPIO_InitTypeDef  GPIO_InitStructure;0 Z# h$ K- Q# l* t
  6.    7 v* `) G( k$ a
  7.   /* Enable GPIO clock  */+ w% q. w5 @* G' R; R. k
  8.    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
    : T: J1 Z/ A+ A% k
  9.   
    / V& L( y' a1 A( K% F6 F/ \, G
  10.    /* Enable USART clock */5 E. f/ S8 @9 j0 ]6 M7 n, X- g% S
  11.    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
    ) I& h5 U; n. ]( a, P" a  u
  12.   
    . R. O; @: q7 L! Z; ]- {
  13.    /* Connect USART pins to AF7 */+ ?2 ~' g, M7 a, u8 g* ]
  14.    GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_USART3);5 w3 R* F1 L: d* A2 e7 W/ {5 w
  15.   GPIO_PinAFConfig(GPIOC, GPIO_PinSource11,  GPIO_AF_USART3);
    : f  J7 B# G4 h
  16.    - x0 {( w" |2 t) Z* ^% X- u0 E/ W
  17.   /* Configure USART Tx and Rx as  alternate function push-pull */
    * y/ ^* H7 z/ o2 z- W) y
  18.    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    ) f# f% W- p& B1 [5 `; g  ?
  19.   GPIO_InitStructure.GPIO_Speed =  GPIO_Speed_100MHz;
    6 q. X4 U# {& t8 C$ Z( U
  20.    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    , r( u1 J9 q2 K* v, D
  21.   GPIO_InitStructure.GPIO_PuPd =  GPIO_PuPd_UP;
    " r! g: O+ p4 i/ E$ |
  22.    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    ' k& {6 w* v: \' ]/ O* V1 m  A
  23.   GPIO_Init(GPIOC,  &GPIO_InitStructure);- [! X( A# x- z+ R+ g: b
  24.    
    ) n# y* v6 O# o+ f+ t: T
  25.   GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_11;
    ) o  J; r5 \+ f/ Q
  26.   GPIO_Init(GPIOC,  &GPIO_InitStructure);0 J9 z+ I1 e+ A- Y
  27.   /*  USARTx configuration  ----------------------------------------------------*/& U8 S3 }6 {, @9 J' j! I1 a! ~
  28.   /* USARTx configured as follow:% d8 l# f4 d. J* {, A: n/ W
  29.         - BaudRate = 3750000 baud
    ( d! m! h- ?4 @
  30.   - Maximum BaudRate that can be achieved when  using the Oversampling by 8
    9 U, m* \. Y0 R& Y( I
  31.      is: (USART APB Clock / 8)
    9 r3 @8 s+ j6 m- ?
  32. Example:
    9 B/ c! }6 F5 Y, c, F7 k
  33.    - (USART3 APB1  Clock / 8) = (30 MHz / 8) = 3750000 baud/ z6 K, ^. I' q. L. Q( E
  34.    - (USART1 APB2 Clock / 8) = (60 MHz / 8) = 7500000  baud' x* Q6 [) h3 Y7 R6 s4 Q+ |3 E
  35.   - Maximum BaudRate that can  be achieved when using the Oversampling by 16
    0 u% C9 D  V/ ]/ ~7 Y
  36.     is: (USART APB Clock / 16)
    4 m% ]! z; E% J. a# a
  37. Example: (USART3 APB1 Clock / 16) = (30 MHz / 16)  = 1875000 baud0 e/ i. E- S0 p2 y; r% S9 [
  38. Example: (USART1  APB2 Clock / 16) = (60 MHz / 16) = 3750000 baud7 F  }0 d/ @& `0 d9 U
  39.         - Word Length = 8 Bits9 `4 g" @- g* j- ]+ B
  40.         - one Stop Bit0 T+ ?9 y9 e# L0 N7 [/ J
  41.         - No parity
    # u, t7 \% b; y9 ]5 e
  42.         - Hardware flow control disabled (RTS and  CTS signals)% w3 S0 D7 o6 ]! P" ?; w! P5 G5 W
  43.         - Receive and  transmit enabled
    " u9 m" G2 L  E  o  P( V7 j
  44.    */
    2 e# p5 [! H& K
  45.    USART_InitStructure.USART_BaudRate = 115200;* Y; n' m* f2 s# n
  46.   USART_InitStructure.USART_WordLength =  USART_WordLength_8b;, x- e$ p7 G$ \. [- k
  47.    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    ) l% E$ B0 n: m. u, m
  48.   USART_InitStructure.USART_Parity =  USART_Parity_No;0 ?# P% V# ]4 T" @, q
  49.    USART_InitStructure.USART_HardwareFlowControl =  USART_HardwareFlowControl_None;9 W+ j8 W6 }7 G# ?7 z+ f
  50.    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;' |! D' f4 a! p5 R
  51.   USART_Init(USART3,  &USART_InitStructure);
    1 }/ _1 B' O7 d: t: l' k
  52.    + i( X- ^* K8 y& D# Q: W
  53.   /* NVIC configuration  */$ Z$ Q* e% I& z6 K
  54.   /* Configure the Priority  Group to 2 bits */9 \+ N3 e' Y4 Z4 Y" t3 q! Q2 q$ g+ a
  55.    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);. v0 }8 r" \! K
  56.   ; ?! ?) f1 h/ Y; v. `4 ~, j$ ~$ C/ j
  57.    /* Enable the USARTx Interrupt */
    ! U( k  }& m, P
  58.   NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
    % ~" K% q8 _: R
  59.    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;% b, h  A; u5 Q' ?: U% _
  60.   NVIC_InitStructure.NVIC_IRQChannelSubPriority =  0;8 r! L/ ?6 @9 U( U/ G
  61.    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;* X$ f( c% Z5 b& T. e
  62.    NVIC_Init(&NVIC_InitStructure);3 Y0 m. i4 X# ]* E: I" _
  63.   
    5 l! e# F% g3 o9 d! A9 D  K6 f- U
  64.   /* Enable USART  */3 m/ a7 t$ b( R6 _1 g# ?7 w
  65.   USART_Cmd(USART3,  ENABLE);
    ) O+ C$ q: [  s- p8 e
  66.   USART_ITConfig(USART3,  USART_IT_RXNE, ENABLE);5 G1 w; @- X% K/ t
  67. }+ N8 k& P8 |/ A" c2 }
复制代码
* w7 w4 O' x2 ?0 B. A# V& w
中断服务程序如下:5 g0 F- e. ^( F8 G% Q
  1. void USART3_IRQHandler(void), v6 ^2 b/ Z7 }
  2. {  @9 j# p. Z4 G: r' B
  3. unsigned char ch;  
    1 }; r2 O. ~* w! N$ o0 T$ c* E; H
  4. if(USART_GetITStatus(USART3,  USART_IT_RXNE) != RESET)
    ' y+ x6 `. k8 s& V" S6 Y9 L
  5.    {7 y9 ]4 ?  ]- H% P8 P
  6.     /* Read one byte from the  receive data register */
    ) I) c) b  V. k, k& r; R0 r
  7.     ch =  (USART_ReceiveData(USART3));
    3 z# o5 ^) i2 m' V! s

  8. 3 a+ s  {; ?  e# Z& \7 A; H: O
  9.      printf("in[%c].\r\n",ch);. f7 O: o1 D5 F/ t/ }' |: N: ~
  10.   }   
    . s' Z9 r) r& R( q  _1 o
  11. }
复制代码
9 s, R& X' S( l6 c" j3 X) A
5 U& Z% ?% l7 s. E9 ^5 }2 q0 x
直接把接收到的字符打印出来。
! E1 E; Y& V+ o2 V# U- ~+ R- Y- ?- V
2DMA方式9 G- Z- }  O. `
基本步骤同中断方式,额外需要DMA的初始化配置,参考代码如下:& F* Q* \9 S$ o  E$ W" i9 v2 r5 R' j
  1. void  uart_init(void)
    3 ?& z  F: X! e- H; S" o
  2. {
    & L/ w( O1 c/ x+ L6 v
  3.   USART_InitTypeDef  USART_InitStructure;  C9 x' p( W, R8 ^% y
  4.    NVIC_InitTypeDef NVIC_InitStructure;1 h0 Q% G+ j4 g+ l& A- i
  5.   GPIO_InitTypeDef GPIO_InitStructure;9 H# H; m/ z, s; W5 i% _" ?+ x2 B
  6.   DMA_InitTypeDef DMA_InitStruct;& n' ^2 D5 ^9 m; q1 s6 a. e! o& l
  7.   
    - B, s! V- z! m4 G! D* I
  8.    /* Enable GPIO clock */
    2 `/ S1 U: }+ J; i. x/ o
  9.    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
      B& I. ^" V/ r; i3 \8 [
  10.   
    , n& \, |2 }! p: L7 ^8 k, ~* J
  11.    /* Enable USART clock */+ e1 k! K. N% O* A4 Z
  12.    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
      S0 L9 `1 B9 A# q8 C8 o
  13.   1 o& i  ^: W2 S( f9 |$ m
  14.    /* Connect USART pins to AF7 */
      V' p. w% s$ D/ C4 Y
  15.    GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_USART3);
    , |) u* u! y$ |1 h! ]$ C% m0 ?
  16.   GPIO_PinAFConfig(GPIOC, GPIO_PinSource11,  GPIO_AF_USART3);
    5 R* f5 T6 b/ y; H
  17.    
    & `/ w; ~" w' i: k) u: ?
  18.   /* Configure USART Tx and Rx as  alternate function push-pull */$ N4 v+ L2 ]% R& j' S
  19.    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    6 I  E. r+ A! F/ U; {
  20.   GPIO_InitStructure.GPIO_Speed =  GPIO_Speed_100MHz;8 X+ f9 |! V: P3 D% ?7 |- r% D
  21.    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    ) g$ z! X0 t7 J1 Q( h
  22.   GPIO_InitStructure.GPIO_PuPd =  GPIO_PuPd_UP;5 p4 a- A4 x9 l( B1 y& `
  23.    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;' e( V7 N% k( f( a9 c
  24.   GPIO_Init(GPIOC,  &GPIO_InitStructure);1 C* D& l' ]5 b7 J" `$ V1 }5 m# a' X
  25.    
    , J. Z; U- X( m! _) E
  26.   GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_11;
      m6 z' C8 H% g: I: p. Y# `
  27.   GPIO_Init(GPIOC,  &GPIO_InitStructure);
    , c/ b2 P$ X* F1 C: T
  28.   /*  USARTx configuration  ----------------------------------------------------*/
    6 r5 v: n" H1 ]7 f0 K# Z* G0 z
  29.   /* USARTx configured as follow:; \4 q) L, T5 d- s) x
  30.         - BaudRate = 3750000 baud
    1 p8 T! P( U" G, T
  31.   - Maximum BaudRate that can be achieved when  using the Oversampling by 8# o+ z1 L# F, I; v9 w$ H4 r5 X+ X
  32.      is: (USART APB Clock / 8)
    5 h2 `" A. y8 K( T4 [
  33. Example:
    - Z& d; `! u, I, y
  34.    - (USART3 APB1  Clock / 8) = (30 MHz / 8) = 3750000 baud
    0 J" d9 y/ p; f; H8 y
  35.    - (USART1 APB2 Clock / 8) = (60 MHz / 8) = 7500000  baud
    1 N: q7 D4 j+ B1 n" }$ f
  36.   - Maximum BaudRate that can  be achieved when using the Oversampling by 167 e- D) C8 N- P. I% T
  37.     is: (USART APB Clock / 16)
    # T; W; f7 F; ^' \! b! n
  38. Example: (USART3 APB1 Clock / 16) = (30 MHz / 16)  = 1875000 baud
    : H$ s) F# L# G. P) n8 U
  39. Example: (USART1  APB2 Clock / 16) = (60 MHz / 16) = 3750000 baud
    6 h7 A" S! q. T4 c% l
  40.         - Word Length = 8 Bits
    % v8 G$ v* E- W1 ~6 z' b
  41.         - one Stop Bit
    7 d4 s3 e/ d% d7 p' l
  42.         - No parity
    ' i% p. W& [6 C9 S: _9 M
  43.         - Hardware flow control disabled (RTS and  CTS signals)$ B- Q5 Z9 b3 C2 X
  44.         - Receive and  transmit enabled2 D& i0 _: a8 s$ h* ^+ g
  45.    */
    . u( ]7 @8 `' t/ ^1 `
  46.    USART_InitStructure.USART_BaudRate = 115200;
    3 D$ ]& U0 b3 [  i+ r' a) y
  47.   USART_InitStructure.USART_WordLength =  USART_WordLength_8b;. R$ V8 s1 W; O, O' G% m, G, _
  48.    USART_InitStructure.USART_StopBits = USART_StopBits_1;/ t. \% L+ r' N: X6 q
  49.   USART_InitStructure.USART_Parity =  USART_Parity_No;
    3 v  t) J2 E* Z2 z
  50.    USART_InitStructure.USART_HardwareFlowControl =  USART_HardwareFlowControl_None;
    ) i) @' W5 G* `9 `" t% s" p
  51.    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
      C) {- t' D) z2 N5 Y
  52.   USART_Init(USART3,  &USART_InitStructure);
    : k7 z+ v, Z: U) B9 B

  53. " m# l; {% n% t5 q! w
  54. /*  DMA_Configuration */% h. g' g1 [0 U% h1 w
  55.    DMA_DeInit(DMA1_Stream1); 5 S0 j+ i3 h' _
  56.    4 Q8 G7 Q# y, O
  57.   DMA_InitStruct.DMA_Channel =  DMA_Channel_4;   * x8 }- [6 [0 @' [1 F7 K( S0 @
  58.    DMA_InitStruct.DMA_PeripheralBaseAddr =  (u32)&USART3->DR; //source  buf
    $ F. B- j. R2 M
  59.    DMA_InitStruct.DMA_Memory0BaseAddr = (u8)pdata; //target buf; K1 _) s5 P! z  j( {
  60. 8 C0 P5 M: Y4 _! C4 q1 v8 \5 O. E  n2 b
  61.   DMA_InitStruct.DMA_DIR =  DMA_DIR_PeripheralToMemory;2 H2 \' f6 x' h4 n: |
  62.    DMA_InitStruct.DMA_BufferSize = lenght;  //BuffSize;& M# N" P% Q% C, _
  63.   DMA_InitStruct.DMA_PeripheralInc =  DMA_PeripheralInc_Disable;
    - m# K5 J. o$ w4 e! S  |
  64.    DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
    / t0 r: M; K. w0 D6 z& C
  65.   DMA_InitStruct.DMA_PeripheralDataSize =   DMA_PeripheralDataSize_Word;
    # r" y  P2 p5 w5 n
  66.    DMA_InitStruct.DMA_MemoryDataSize =  DMA_MemoryDataSize_Byte;
    2 D, h; l" G! C0 V0 A  l* X% F7 G
  67.   DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;  //DMA_Mode_Normal; / L& l6 `! b! G5 S
  68.    DMA_InitStruct.DMA_Priority = DMA_Priority_High;
    ! k- ]3 {* _$ M2 @8 ~/ E/ V
  69.   DMA_InitStruct.DMA_FIFOMode =  DMA_FIFOMode_Disable;
    # M, w5 L+ _# Y5 R' t9 V2 [
  70.    DMA_InitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;8 [* p) }0 a4 P+ B( k
  71.   DMA_InitStruct.DMA_MemoryBurst =  DMA_MemoryBurst_Single;7 K7 [7 X- _" L: O# D
  72.    DMA_InitStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;/ \6 W1 R& P, C* ?! u. p. O/ q
  73.   DMA_Init(DMA1_Stream1,  &DMA_InitStruct);' E' f" j4 o/ O' Y0 e0 c3 a

  74. % @) Q0 {4 B* E  j3 [
  75.   /* NVIC configuration  */" I6 G* m. ~  L* K
  76.   /* Configure the Priority  Group to 2 bits */
    9 I' k' }/ N* v3 J4 M: O: Q
  77.    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    & a% l) w, O, n% E, S5 |
  78.   + W# u; c- x5 J( S
  79.    /* Enable the USARTx Interrupt */. L. c+ k! V* j2 V/ e4 A9 x
  80.   NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream1_IRQn;  3 b/ v! v. i% O2 S
  81.    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    ! B6 g% {) M; C
  82.   NVIC_InitStructure.NVIC_IRQChannelSubPriority =  0;
    % M' s3 X3 ]9 x# \/ N8 `
  83.    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    ; R& i' c" c) \( e/ L4 ]
  84.   NVIC_Init(&NVIC_InitStructure);  
    2 W0 k! b$ I+ D0 a# D

  85. / T; l6 p9 j$ T
  86.   /* Open DMA  interrupt*/
    " n) O; ^. S) P" d9 Y& D
  87.    DMA_ITConfig(DMA1_Stream1, DMA_IT_TC, ENABLE);
    4 u; {! C0 m" d' R( Z  a
  88.   DMA_Cmd(DMA1_Stream1, ENABLE);1 E5 }% v+ D9 a8 D: `# S# @
  89.   USART_Cmd(USART3, ENABLE);- G1 J8 v% k4 E9 W+ |4 Y
  90.    USART_DMACmd(USART3,USART_DMAReq_Rx,ENABLE);2 y+ Z8 d/ U! v$ ]$ O9 O
  91. }
复制代码
: D$ k8 o: B' a8 Y- r; I
* A  L( E3 [  g9 w3 g
DMA中断服务程序如下:
4 J; W9 B1 K# z6 q( Y( w/ j  R$ [1 l
  1. void DMA1_Stream1_IRQHandler(void) //UART3_RX9 e6 t6 C7 o7 w' ~; Z1 r
  2. {( n+ Z5 i1 F" o, ]1 g. j2 X
  3.      static short i;+ h: M+ S; b+ E
  4. 0 p* q0 y$ p& O8 I
  5.     //When a  Transfer Complete
    6 b9 i6 M( }0 e0 \+ H5 ^: C# i  F
  6. if(SET ==  DMA_GetITStatus(DMA1_Stream1, DMA_IT_TCIF1))) Q* }, z5 P+ V- [4 ~! Y
  7. {
    ; f4 ~+ z. x" {0 S3 |: i
  8. DMA_ClearITPendingBit(DMA1_Stream1, DMA_IT_TCIF1);
    + [5 r: K" r3 ?
  9. i++;: r2 x. l2 U* w& `% R8 a$ ?
  10. }3 U' i9 p3 M. k3 t# o
  11. }
复制代码
4 \% b. I" a: j. f: |1 G2 z

; o* X1 `1 E- A, {上面程序只配了DMA接收,发送类似。
7 I; X: ^+ F  L) F! p$ {/ V; u3 x$ Z7 e1 c8 ^! `
% N, Q0 ~* f* Z' w, ~
三、实现DMX512协议
* _# n3 j% w1 z# A6 c! \DMX512 协议是美国剧场技术协会( United States Institute for Theater Technology,  USITT) 制定的数字多路复用协议, 其制定的初衷是为了使舞台、剧场等地所使用的众多的调光器和控制器能相互兼容。虽然它不是一个行业或国家标准, 但是由于它的简单性和实用性, 自从出台以来, 得到了世界各地生产商和使用者普遍承认,这个协议在LED控制方面应用很广泛,利用STM32 USART可以高速传输的特性,我们很容易用STM32来实现DMX512协议。
% O# }8 s1 Z1 I0 q4 u1)数据的格式及传输
- c2 O. H( D$ C! S  h0 TDMX512  协议规定数据以数据包的形式通过异步通讯的方式进行传输。每个数据包由若干数据帧组成, 每帧数据包括1 位低电平起始位、8 位数据位和2 位高电平停止位。DMX 协议要求数据传输的波特率为250kb/s, 亦即每位的传输时间为4us, 每帧数据的传输时间为44us, 它支持多达512 帧数据传输, 每帧数据与相应的控制支路相对应。数据包的传送要符合一定的格式和时序要求。为了使接收器能够分辨出第一帧数据, 每一个数据包以一个不短于88us 的低电平信号为起始信号, 即所谓的“Break”信号, 接收器接收到“Break”信号就准备接受随后而来的数据帧; 紧接着“Break”信号之后是不短于8us 的高电平信号M. a. b ( Mark after  Break) ; 之后就是数据帧。在DMX512 协议中, M. a. b 之后的第一帧数据被称
% E6 V9 m, K; U6 e: j: m) ?- W为“Star-t code, 在协议中规定其为零, 但在实际应用中可以由生产厂家自己确定其具体的值,  以传递特殊消息。“Star-t  code”标明其后面的数据是8  位控制信号数据帧。数据帧之间可以有时间间隔, 也可以没有;  同样, 数据包之间可以有时间间隔, 也可以没有。DMX512 协议规定“Break”信号、M. a. b 信号的最短时间, 并规定“Break”信号、M. a. b 信号、
" L. O3 x/ g0 A9 X数据帧之间及数据包之间的时间间隔的最大值不得超过1s, 否则做出错处理, 但是DMX512 协议并未对出错处理做任何规定。为了严格实现DMX512  数据的时序要求,“Break”和M.  a. b信号我们可以用定时器来实现。3 `; h( Y4 n3 I' x8 i7 o6 `- J8 v
具体的UART配置如下:# }0 o+ F  b3 W; ~: z, J1 K
  
  1. USART_InitStructure.USART_BaudRate =  250000;
    % W" f! }4 I! L& b
  2.    USART_InitStructure.USART_WordLength = USART_WordLength_8b;/ ~8 X7 o& M) V8 Z
  3.   USART_InitStructure.USART_StopBits =  USART_StopBits_2;
    0 v& }8 r# e5 t/ l
  4.    USART_InitStructure.USART_Parity = USART_Parity_No;' h) t5 u# w  I
  5.   USART_InitStructure.USART_HardwareFlowControl =  USART_HardwareFlowControl_None;
    5 `. z9 t9 E7 ^( ~: L4 x% W
  6.    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    % D! r; ~6 Q' r& k  I( }
  7.   USART_Init(USART1,  &USART_InitStructure);
复制代码
5 C3 ~$ Q0 K4 r. R- }' A) Z% k1 s
' S( {( p& b6 L* ?1 U

( D- }" y. g; D9 T$ C, y' x8 p
发送DMX512信号过程如下,先把UARTTX脚配置为普通的GPIO并输出低电平,然后启动定时器计时88us,  时器到后把TX脚置为高电平并计时8us, 时器到了后在配为UART模式用DMA方式把数据发出。
  O5 Q5 N4 v- R! x8 a/ r0 u7 TDMX512信号的接收是个难点,一般直接配为UART接收就行,不需要在UART模式和GPIO模式间切换,但需要在接收过程中检查接收到“Break”信号时的状态是有帧错误出现,并且接收数据全为零,这样的话可以确认已经收到“Break”信号,随后数据正常DMA接收就行了。
" `7 j. O$ g! G
! z8 T$ L+ W0 [8 V" l# s8 E
1 收藏 4 评论3 发布时间:2014-4-8 22:02

举报

3个回答
lyzd 回答时间:2018-6-29 09:43:46
很全哦。。。
radio2radio 回答时间:2018-6-29 10:40:13
串口编程,我的经验是:
, ]1 n8 }! Z* h* j$ s1. 使用已经调试好的例程,特别是参考官方例程包。% u- d; N9 A5 q+ y5 m# l4 s
2. 使用KEIL的RTE配置串口,很好用。
4 u$ W! c+ p8 u. S% {, X6 j: M% G3. 使用CubeMX配置串口,也很好用。
SZHYK 回答时间:2019-7-27 16:10:25
谢谢分享!!
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版