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

【原创】STM32F103的USART2配置代码, DMA方式发送!

[复制链接]
wjandsq 发布时间:2015-6-25 14:07
STM32电机培训online,大佬带你玩电机  _# @* d/ Y5 @7 t8 _' O6 e2 `

+ ^0 a6 G, [( ]/ f+ g" ?+ k% h% N- n) x4 Z
#include "stm32f10x.h"
# E# e; L5 ^' R+ _; y/ w1 p#include "stm32f10x_usart.h"+ c5 g9 `. [  f8 U/ F5 @
#include "stm32f10x_dma.h"
  B+ d. [0 x! H5 }# ]/ p& L1 z/ Q& T0 v8 L+ o
uint8_t HEX_CODE[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
7 e2 g) B# [0 Ruint8_t USART2_DMA_TX_Buf[1024];
  e  V, Z8 f) r4 \9 q' M, R. |uint8_t Flag_USART2_DMA_TX_Finished = 1;( P* D' W  u8 L7 v0 c8 x+ u
uint8_t Flag_USART2_Send = 0;
: T0 V' p4 {$ k( a. e
1 S0 r6 C  Q3 t5 z; r+ c. e1 b/**
2 C$ u* k& o, K% q. K8 F  * Function Name  : USART2_Config0 J% X* v& D% C. D' W
  * Description    : None  R7 Q, g+ X$ P6 B, h5 \% Z; e' q
  * Input          : None
+ V% m. k1 w8 f. U# N9 _/ Z  * Output         : None( D2 @& O- z3 N* G
  * Return         : None
  z# d  H+ @  T) h' @: A, M+ Q: g  */; `. H! a3 u6 A& `9 k
void USART2_Config(void) {
) O7 q$ P  b- Q. }  GPIO_InitTypeDef GPIO_InitStructure;8 t/ B- o2 `6 D& G3 G- U! J
  USART_InitTypeDef USART_InitStructure;
$ `$ U' U. n. @. o# o0 a  DMA_InitTypeDef DMA_InitStructure;
# S, a; a/ n( r; \  NVIC_InitTypeDef NVIC_InitStructure;
' O6 t6 ^( C+ q
$ l: l; A/ t# u& q1 b# a  /* config USART2 clock */
+ X# S$ t0 x4 j# i7 _  e' }6 n7 ]  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
! x) P* w7 z4 d+ _; G# i  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);  s1 E( [' H6 M3 R2 x3 @
3 X& d5 h+ P: C! V
  /* *********************USART2 GPIO config **********************/& S( U! |! J' c/ G3 U- q+ U
  /* Configure USART1 Tx (PA.02) as alternate function push-pull */
  R+ C! l( M8 f3 B+ @2 d& d  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
" q, z( @' n' K% Y4 Y2 P5 n  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
4 s& ]" n# ]) H0 [  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;* G' U/ O1 d; z$ f: R
  GPIO_Init(GPIOA, &GPIO_InitStructure);    & k* L% K/ a; f* T; V$ |  e
  /* Configure USART2 Rx (PA.03) as input floating */
# s" C& i: ~, @" @9 S  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;4 _: e; u  w  z+ n, G3 S: ^
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;! Z% S6 b% m" O0 q
  GPIO_Init(GPIOA, &GPIO_InitStructure);
6 G( y" W2 @$ ^' r% y6 W: O$ e8 B- X, a
  /* USART2 mode config 115200 8-N-1*/
  P  j7 ^' G/ b7 g, p6 |  USART_InitStructure.USART_BaudRate = 115200;" L9 @. y. K) |" d7 ~& F5 p
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;" b2 {& n4 [8 o8 f
  USART_InitStructure.USART_StopBits = USART_StopBits_1;0 J# y8 |0 U9 ^4 P1 n
  USART_InitStructure.USART_Parity = USART_Parity_No ;
* c4 a: K! N2 z( ~/ [$ x  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;8 \& b( f6 `) ?+ H
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;0 e5 B) ~- F1 f! h+ c/ y- k$ O
  USART_Init(USART2, &USART_InitStructure);
* Q3 G5 f$ h6 T  USART_Cmd(USART2, ENABLE);; Z* n4 W# A8 o$ V  W- C" E- `

$ n2 f: K9 Q, W7 C: a) x
6 m6 j5 g- A  `+ @5 z  USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);
0 D- f- _3 H; ^/ s, g' A  /* Enable USART2 DMA TX request */) e* e+ u/ `/ d) X; ?
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);; `; O  n# r' }# W1 Y' C" h: s4 n
* b7 U6 j( E3 e/ y- I8 B4 m
  DMA_DeInit(DMA1_Channel7);' `; c, x- g) K4 T% z' L5 c
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&USART2->DR);
8 R' h3 Z+ n* C  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART2_DMA_TX_Buf;
) O5 W& C4 m# s  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;) q$ Y; A& A3 k) z! u7 v, _) @
  DMA_InitStructure.DMA_BufferSize = 0;/ q5 R: {0 Z. b/ o# `& S$ @
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;5 f% f4 g% k1 W" n
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;( n) W7 O/ D+ j( H; k  ]
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
2 K* }3 L6 T0 T$ c9 e2 s% i4 x  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
$ M" C/ N# R' V6 q2 ^1 v  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;8 ~! U/ R' a2 x5 C
  DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
1 t5 z$ [4 v, m) b* G& V0 r  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
* ^( D# B7 ]+ A7 a  DMA_Init(DMA1_Channel7, &DMA_InitStructure);. y% o# F" {" w; t; \
  DMA_ITConfig(DMA1_Channel7, DMA_IT_TC, ENABLE);+ G7 I1 p; s$ Q
" Y% l5 l* u6 z8 T; g# j1 D
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
, t2 a) _8 ^+ }
( o- X: Y+ V0 Y' Y2 Z" m. m" t4 ?  /* Enable USART2 DMA TX Finish Interrupt */
, h& [! [: U6 G# f0 f$ r& N. y% G  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel7_IRQn;
/ a* E& F" g4 V" Y' w( d+ I. P. Y* p  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;- J- ^! c. T$ F
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
% H9 V5 x% N1 K- }( O1 h/ r  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;+ K" S# Q; q1 \# k" m% p
  NVIC_Init(&NVIC_InitStructure);
0 y& A9 [( U* ~- b3 {! X+ b6 v6 K$ ~& Z" s
  /* Enable USART2 Interrupt */
( \1 r% s, u% n- g# k# @9 c) n( j  NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;: `6 e2 w3 V: K+ z3 h$ }0 ^4 n
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
4 ]  i! _/ v7 \- `" G$ W  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;7 M# n3 R4 f0 x* R' s* g% G1 G
  NVIC_Init(&NVIC_InitStructure);  B% o" I; M: ?% h2 O
}+ x* y3 S* l# p5 |( S8 B
/**6 j7 w9 w) L, z) A
  * Function Name  : USART2_Data_Load' P6 F" q3 n3 }- D. B
  * Description    : None& m( t+ H3 {3 ]4 {7 t
  * Input          : None
+ D' i, _4 }$ Y. b  * Output         : None
" n) r5 a( t- `. n0 T  * Return         : None
! s3 Q% V/ _/ i2 k/ o, s2 |  */
/ K9 C1 q- V5 F* t, l( ?- k. Ovoid USART2_Data_Load(uint16_t temp1, uint16_t temp2, uint8_t temp3){, I/ h4 ~* q: T) E3 k5 S
  USART2_DMA_TX_Buf[0] = HEX_CODE[temp1 >> 4];- _" c) ?- M5 R1 @# s; S& h1 y
  USART2_DMA_TX_Buf[1] = HEX_CODE[temp1 & 0x0F];( g6 u/ F/ u3 U+ _' |9 M9 G7 L
  USART2_DMA_TX_Buf[2] = HEX_CODE[temp2 >> 4];) R0 _  s3 T& g; {
  USART2_DMA_TX_Buf[3] = HEX_CODE[temp2 & 0x0F];
" N6 M* ^2 t( X2 T0 m2 k0 k' \; @  USART2_DMA_TX_Buf[4] = 0x20;
* \2 u! g2 F' f6 @9 a5 I. ~  USART2_DMA_TX_Buf[5] = HEX_CODE[temp3];
! x$ w$ D9 j1 l( E  USART2_DMA_TX_Buf[6] = 0x0D;
- R7 `" K5 A2 K) q- S& _! _- N  USART2_DMA_TX_Buf[7] = 0x0A;$ n. `! |+ O6 w
  Flag_USART2_Send = 1;
% r- j: w5 u4 \. |4 C3 E}# t! a; A# t& K
/**# t" y8 B( f* U; D
  * Function Name  : USART2_Data_Send% b* M# J$ |  Z, ?0 _+ G
  * Description    : None
8 ^/ `  K9 H. \5 K/ d  * Input          : None! A* Z# |. y  V+ s3 F- `: I
  * Output         : None
6 I5 @# i* y( y; X2 l' z  * Return         : None
- u, b- G" }$ A  */
) T  _% {/ v) C! C2 B1 P8 rvoid USART2_Data_Send(uint16_t len) {3 u  y! C9 r7 a+ v7 W( w
  if(Flag_USART2_Send){4 h1 N) q+ @  c: C' B& n. d: ^
    if(Flag_USART2_DMA_TX_Finished == 1){
/ r. T2 a0 p- C3 f1 N  x      Flag_USART2_DMA_TX_Finished = 0;
5 @  w* U$ ?0 z3 z2 D      DMA1_Channel7->CMAR  = (uint32_t)&USART2_DMA_TX_Buf[0];/ B+ o6 a- J' C: Y2 \. Z8 J/ h
      DMA1_Channel7->CNDTR = 8; // len
4 z, U/ ]" q* `3 ?% J& W      DMA_Cmd(DMA1_Channel7, ENABLE);3 |! ^/ c. ]% {
      Flag_USART2_Send = 0;) t; F- n, Q# P- e
    }
2 U9 @$ o, W0 ^. M8 y) _) E; ~  }4 o  g5 V% c# a
}
- v4 @& l2 |5 U; S9 A4 x/**5 n* A; S1 D5 ?. P  ^
  * Function Name  : USART2_IRQHandler
, d, ]/ K% P+ ~# {. n- |  * Description    : This function handles USART2 global interrupt request.- E- a# }+ R$ z, `1 c; |( x
  * Input          : None
  u2 V0 L- |- N6 _% k0 }1 Y( `  * Output         : None" G+ H0 \$ A% ^2 m
  * Return         : None* B* ?1 h3 N) L5 g8 V3 G. E+ d4 h8 I
  */
8 F9 l( ~+ V( V8 w. q' pvoid USART2_IRQHandler(void) {
1 i7 \$ B5 F7 m$ L' O$ H  if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET) {$ C0 c, T* C4 ^% ~( ~0 ?3 y: X6 n
    (void)USART_ReceiveData(USART2);% l  o1 v9 h" O$ c0 F  C3 b
  }& C4 C6 I7 V/ ~) g9 s) e9 G- J
  if (USART_GetITStatus(USART2, USART_IT_TC) != RESET) {: c+ M6 S# n7 S: a! K+ ]  r
    /* Disable the USART2 Transmit Complete interrupt */7 b/ b$ z1 d8 x1 y! r) M4 ~
    USART_ITConfig(USART2, USART_IT_TC, DISABLE);
: |+ {, p7 `2 u, H, }. g3 J    Flag_USART2_DMA_TX_Finished = 1;
2 G4 Z  E# x' _' U; H6 c8 ^5 F  }     - U) F9 g$ b8 |% }4 x9 e% O7 k
  /* If overrun condition occurs, clear the ORE flag a.nd recover communication */    + X8 T9 q) U% A5 m7 l
  if(USART_GetFlagStatus(USART2,USART_FLAG_ORE) != RESET) {
1 V& [$ c1 e) I! e" G/ L    (void)USART_ReceiveData(USART2);/ {) G7 p3 P. y5 e. ^! _
  }! G% Y. ^# [: Y0 X$ A  m9 M
}
) j0 V# m2 L# W- y7 }+ h/**
# E7 K5 b+ [! K5 ^  * Function Name  : DMA1_Channel7_IRQHandler& k1 U* e3 J1 t* p. h5 `9 M
  * Description    : This function handles DMA1 Channel 7 interrupt request./ ]+ Z) g: g# T6 v. R4 |8 @* a4 ^! q
  * Input          : None
# }* g8 g1 @4 o  * Output         : None3 M) g! W9 v8 U6 g- R0 P' s$ P
  * Return         : None
# f, `, d+ i4 @) h" e8 _  */
1 P4 E' U  b, Q; K4 bvoid DMA1_Channel7_IRQHandler(void)0 E0 V9 ?0 C' \' G; G, R
{+ R) ^2 f% `3 R& w
  if(DMA_GetITStatus(DMA1_IT_TC7)) {
/ F1 u8 c) W& T7 w- B2 l6 \    /* USART2 DMA 传输完成 */; F# `, ]# ]$ ~7 D9 s. o
    DMA_ClearITPendingBit(DMA1_IT_TC7);3 _  W+ D7 B) {0 s  l. w  f! u
    DMA_Cmd(DMA1_Channel7, DISABLE);1 K* x# s/ f5 M9 B
    /* Enable USART2 Transmit complete interrupt */0 z5 d; e# G2 p, K1 e, L( S. }7 \
    USART_ITConfig(USART2, USART_IT_TC, ENABLE);
1 F6 P4 I! Z" w4 q% m8 @5 Y8 ^0 U  }
% s6 z1 O6 k% w/ g6 b9 Q" w9 S}
4 R& L5 A9 x% H. I. ], p/ V/ Z+ J& F7 m
收藏 4 评论7 发布时间:2015-6-25 14:07

举报

7个回答
沐紫 回答时间:2015-6-25 14:25:56
谢谢,要是有代码注释或者文字说明更好啦
wyxy163@126.com 回答时间:2015-6-25 17:05:13
提示: 作者被禁止或删除 内容自动屏蔽
wjandsq 回答时间:2015-6-25 20:37:02
本帖最后由 wjandsq 于 2015-6-25 20:45 编辑 3 _$ b( j, m" L6 V- u: P

1 }' x4 S  i8 I. }$ O# }+ w所谓STM32F103串口数据的DMA发送,其本质流程如下:9 [9 h, x: i% `! D6 X
1. 要发送的数据放在USART2_DMA_TX_Buf缓冲。& L. {% ~. Q2 J0 }, P
2. STM32串口DMA发送和DSP相比的优势。
4 K  @6 S+ R7 `" W. {   启动DMA传输后,USART2_DMA_TX_Buf缓冲中的数据通过DMA1_Channel7通道,/ U. Y1 C  H& x* L8 g+ w& @! P
   自动传输到USART2->DR寄存器,这个工作不需要CPU干预,可以极大的节省CPU的资源。9 R" [3 |: H4 B' y6 p; `
   和DSP的FIFO相比,这优势很大,因为DSP的FIFO只有16字节,这意味着DSP的串口通过/ S# [8 M. g! L/ N
   FIFO发送数据时,如果FIFO缓冲为空,可以迅速填入16个字节,然后去处理其它的事务。
4 y& W4 I  \8 ]# u7 X. f   而STM32的DMA发送则没有此种限制。更具体的说,如果DSP发送的数据超过16字节,
! f! ^$ j+ G. K, a$ ?8 E   则必须等待前16个字节数据发送完毕,然后再继续发送后续的数据,需要第二次甚至
$ i$ W0 b) `/ e) G9 v6 X   第N次处理。而STM32启动一次DMA就搞定(DMA最大传输65535个数据)。- y6 G/ C. v; s+ r! d: r. [2 J' I
3. 发送结束的一些事务处理% p' _, [5 q0 A; |
   DMA传输完毕,数据全部通过DMA1_Channel7通道依次传入USART2-DR,这里开启了0 S$ H1 L. y! ~; z+ v$ f; e
   DMA传输完毕中断,进这个中断时,USART2-DR寄存器是最后一个要发送的数据,  B+ ^. m% o9 W6 l' g1 Q) n
   此时打开USART2发送完毕中断,进入USART2发送完毕中断后,可以设定标识,5 G+ ^9 v4 V; t6 E7 T6 O
   也可以操作GPIO, 进行RS485的换向动作。
" Y  q4 r" B( V* S4 t& F# y9 g; w" H6 z% F) U3 p& ^/ I
最新的STM32F103的HAL库,几乎所有的通信,都可以启用DMA,HAL库函数抽象层次过高,灵活性不够,
' G2 b" i/ ]' _7 d# B; P但比较适合使用操作系统的场合。可以把HAL库的宏定义拷贝过来使用,以提高标准外设驱动库的效率,
3 a" @! i) A$ g/ r又保证标准外设驱动库的灵活性。: k2 O7 W+ g2 S2 H& W- I' H% \# P
( g+ N" D! K6 t9 m6 d* i( z

1 w1 @: y( U/ x4 _/ N
" G( y4 [  B1 C: P3 X) G
Paderboy 回答时间:2015-6-25 20:38:16
多谢分享。。。支持下。。
HenryChen 回答时间:2015-7-3 16:57:05
多谢分享。。。支持下。。
fanyao-367090 回答时间:2016-11-10 16:43:14
zengyi703-16313 回答时间:2016-11-11 08:13:25
学习一下

所属标签

相似分享

官网相关资源

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