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

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

[复制链接]
wjandsq 发布时间:2015-6-25 14:07
STM32电机培训online,大佬带你玩电机
' l( Q: Q" m+ P! F" k1 Z& w- X* Q" b: ^7 g( o

5 j7 \8 Z6 ^) m  [: X#include "stm32f10x.h": Z5 p# q, z' v4 k# I
#include "stm32f10x_usart.h") b( M) h; {7 o# _" l- X% f8 P
#include "stm32f10x_dma.h"
* M+ `% [4 `% a. ^; z( V" Z+ h3 h8 Q5 p2 h7 c# r; z
uint8_t HEX_CODE[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
" I( _, U" Z6 Vuint8_t USART2_DMA_TX_Buf[1024];& P4 i, Z! m; n
uint8_t Flag_USART2_DMA_TX_Finished = 1;
. r( c& |- m" q! q6 E2 Y" g$ Auint8_t Flag_USART2_Send = 0;
% N9 \. p4 m. E. n# K  B5 r4 X8 \: r) j. B- ]' w9 K
/**2 d1 [4 K* ]6 ~
  * Function Name  : USART2_Config
7 \$ K/ w% Q) \2 H  * Description    : None
. S& s! K: u6 [6 _  * Input          : None/ r0 o9 U( ~6 f+ d
  * Output         : None& s. g1 o7 k! ~. U/ t9 d. A
  * Return         : None) ~$ T+ f# p6 V8 j
  */
' r$ u- C) D0 S' {7 @' q7 kvoid USART2_Config(void) {
: A/ S, ^) o' e, U0 u' T/ |$ g  GPIO_InitTypeDef GPIO_InitStructure;
+ v0 I- c) f2 ^8 x$ {  USART_InitTypeDef USART_InitStructure;
) x7 D* o! d+ e, T1 l  DMA_InitTypeDef DMA_InitStructure;
) H. h4 e9 }* Y7 s/ F  NVIC_InitTypeDef NVIC_InitStructure;   e/ s1 H3 J$ R9 `. }/ b

+ f, [& s+ G7 o' k  /* config USART2 clock */1 ?! Q. @5 b! [' p- z# r
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);% }) B- b& q7 ~9 @' |
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
) {5 r4 V- l5 B. h7 P8 Z0 P% u7 N1 R
2 C$ d* @5 x: d  /* *********************USART2 GPIO config **********************/
( _" ]& G9 W% Y6 {; }4 }  /* Configure USART1 Tx (PA.02) as alternate function push-pull */1 i. F% P* @3 O, k, O/ V
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
$ A! V# G- k) y' P) [  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;& m& n6 R4 J( O+ j# {
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;2 c4 V2 ~5 ?5 D( d8 ~7 x
  GPIO_Init(GPIOA, &GPIO_InitStructure);    ) b3 N( B9 m# t2 ^9 r8 c
  /* Configure USART2 Rx (PA.03) as input floating */
  g; [4 T; z$ s& e: Y/ h  w  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
* j/ h7 X' Q8 Y  t8 R4 p/ N  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
0 _) P2 K/ r3 C7 Z  a* O4 W  GPIO_Init(GPIOA, &GPIO_InitStructure);; Z9 k) s( A  \

( P' s5 u7 R% z5 a1 X4 m9 M  /* USART2 mode config 115200 8-N-1*/
9 B1 I: @; X- p! y2 ~& I  USART_InitStructure.USART_BaudRate = 115200;
" f' l2 ^! }9 G9 h3 w  USART_InitStructure.USART_WordLength = USART_WordLength_8b;+ I+ _( [: U8 f
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
8 {! @7 U2 L7 A$ J) a2 _7 |  USART_InitStructure.USART_Parity = USART_Parity_No ;' {" e( c; u1 `
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
6 h3 f$ `! X, c; N  Z; t  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
+ J5 S. r, t3 M, [% I  USART_Init(USART2, &USART_InitStructure); * r1 b5 o- ^6 M1 B2 ?( C2 s
  USART_Cmd(USART2, ENABLE);
9 K( A# U2 w5 ]' R+ q4 g; t2 s6 N/ E& f  |! Y& Z
1 c9 E% k* L) O, t7 L, d
  USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);
8 d! l1 K8 k5 Z# v  /* Enable USART2 DMA TX request */
# I- [/ C; E8 r7 q8 H  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
# i2 Z- S* x4 Z. A) N
4 q: w" t/ l6 Q% ~( _7 ]. e* p  DMA_DeInit(DMA1_Channel7);
  l  C, A% q! w8 Z7 _7 ~8 o  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&USART2->DR);
" M7 g3 z9 X! B) L: p1 r( c4 v  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART2_DMA_TX_Buf;
/ L4 e0 a) M3 R  P% T5 t, R  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;0 j9 P1 ]# u4 o: i: @% d4 v# P
  DMA_InitStructure.DMA_BufferSize = 0;
, g5 d0 \& ^4 S; k; B  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
: h" E6 m9 ?8 \1 N8 U  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;# r! x5 p/ E+ \& q$ i" _+ S. B) D8 g8 C
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;! x% G+ D# L/ ?8 u% y7 i
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
+ q! T! B' b/ V6 M, T. y& D  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;$ g8 H* S; ?  t' B
  DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
6 d4 T3 n2 _7 w  J  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
" w& q8 N! c: i! o% \5 I% W  DMA_Init(DMA1_Channel7, &DMA_InitStructure);' r! O4 z6 b+ m' [6 U5 d& i! f( [
  DMA_ITConfig(DMA1_Channel7, DMA_IT_TC, ENABLE);1 ?9 D: Z4 A% d
( z  u! I2 ^% ^/ v
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);0 m$ l( Y7 `+ X. @. w7 e/ B  g

, {; }; H; n0 g) B! }* R: S  /* Enable USART2 DMA TX Finish Interrupt */
  l+ \8 K2 r/ @* J( R  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel7_IRQn;9 C( V- O% G3 U9 V; z% S3 ]1 S
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;- `/ T$ f9 N& V2 F# f
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;0 X& f1 b9 k- v9 n* M  e, e
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;- r) ?+ X3 ~2 V9 i' I* \% J4 G1 U
  NVIC_Init(&NVIC_InitStructure);
4 w& V3 v' M' E5 M4 q" q! W0 R6 Z' e  e: c* [
  /* Enable USART2 Interrupt */
$ I$ r; F% {% f& ]) u7 s  NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
& x% J. Y2 Z0 u  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
4 m4 j+ c$ F8 S# x  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
0 Y: k2 e$ i) h7 V0 ]  NVIC_Init(&NVIC_InitStructure);
( Z/ R0 w  w" V9 d8 X0 Y}
! p6 R, P0 t) T/**& q% U( |: y) j1 ^& f# |3 \9 {/ `
  * Function Name  : USART2_Data_Load( j  D# W" l: n( [
  * Description    : None
% V# g9 v, A1 M. I9 h: Z% g% m  * Input          : None7 Z0 c' J- \8 @+ T: A' G2 u
  * Output         : None
: o4 B1 ?4 V. m: S. n: b! W  * Return         : None8 N# @) z+ Q1 N" u; t/ ~
  */
* N  e  b& {4 t# }1 r. B5 z4 bvoid USART2_Data_Load(uint16_t temp1, uint16_t temp2, uint8_t temp3){" P5 R1 b! G  a  f0 J6 o
  USART2_DMA_TX_Buf[0] = HEX_CODE[temp1 >> 4];9 H2 i) N8 |3 p
  USART2_DMA_TX_Buf[1] = HEX_CODE[temp1 & 0x0F];
6 x% J) Y! M8 y1 Y* i  USART2_DMA_TX_Buf[2] = HEX_CODE[temp2 >> 4];& t% q, J/ o; p$ y! B7 Q
  USART2_DMA_TX_Buf[3] = HEX_CODE[temp2 & 0x0F];* a; z  J+ X! @3 b% ?6 `
  USART2_DMA_TX_Buf[4] = 0x20;
. w, v& Y' g7 u" N  USART2_DMA_TX_Buf[5] = HEX_CODE[temp3];
* j; y+ r2 \% |0 Z7 p& Y  USART2_DMA_TX_Buf[6] = 0x0D;) N8 g$ D. g4 T& n" A1 ]
  USART2_DMA_TX_Buf[7] = 0x0A;
. ?7 i! Y' {# c: @4 l3 `6 n  Flag_USART2_Send = 1;& Z0 S  b9 X. s0 W+ m
}
- [4 Q5 I( Y% ~$ e" k% D/**
7 @9 H  Y# ]7 m9 H  n. c  W  * Function Name  : USART2_Data_Send
% s1 R: l- q$ R/ }  * Description    : None# |# L2 M& h9 z, Z
  * Input          : None
: k1 }  t  s% D; F$ K# L  * Output         : None
' t( d3 i3 W* `5 k0 A  * Return         : None
  y0 k1 F% i1 x8 {" H  */* i) Z3 H) K, T7 r
void USART2_Data_Send(uint16_t len) {# J, Z" s+ h, l( _) o
  if(Flag_USART2_Send){
6 W' N" L/ O* I. ~$ Y9 ]    if(Flag_USART2_DMA_TX_Finished == 1){' X7 a$ l9 t3 ]
      Flag_USART2_DMA_TX_Finished = 0;
8 \0 I4 @3 @" @9 a: s      DMA1_Channel7->CMAR  = (uint32_t)&USART2_DMA_TX_Buf[0];2 v: J( R8 Y4 [: v2 W: ]
      DMA1_Channel7->CNDTR = 8; // len
3 z% z* y, h6 H1 h% H+ o* M! C      DMA_Cmd(DMA1_Channel7, ENABLE);3 M1 E/ l# h; L& V" G
      Flag_USART2_Send = 0;: V2 X* E2 j0 t' {
    }
9 `& G" `4 S7 O  }
& J" L1 L0 f4 @5 k! i" a}4 q# [% P8 H8 Z1 Y* Z( @/ m! o4 ]( J
/**% |7 n; ^( t' W3 U* ]
  * Function Name  : USART2_IRQHandler. G* `9 r0 L3 U; U, }
  * Description    : This function handles USART2 global interrupt request.8 C3 o# @8 D1 x
  * Input          : None4 B6 f7 k' S% Z7 A
  * Output         : None
. e1 Z1 k! l/ D/ ]! p  * Return         : None
- I6 `0 T1 N2 i# v9 f4 i  */
8 y' [# B' s: V( |: a! l) w) i$ M3 fvoid USART2_IRQHandler(void) {
8 P, P$ {: Z' I* E  if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET) {
) ?% {1 G2 |% ]    (void)USART_ReceiveData(USART2);/ m8 M7 Y5 C; L
  }8 t) N8 K% R1 y9 R& @/ z" w$ F
  if (USART_GetITStatus(USART2, USART_IT_TC) != RESET) {
, p# x' h" Q- v. G1 f6 X: c- ~    /* Disable the USART2 Transmit Complete interrupt */
+ }9 [' b0 u# ]' \    USART_ITConfig(USART2, USART_IT_TC, DISABLE);! t$ X( ]- ^8 f# s5 C' d
    Flag_USART2_DMA_TX_Finished = 1;
' B2 `- c4 D0 S; }" }. ?  }     
! X! Y" T; Q  H: j2 I  /* If overrun condition occurs, clear the ORE flag a.nd recover communication */    / G6 E! S) t# u& ^$ R$ r) H
  if(USART_GetFlagStatus(USART2,USART_FLAG_ORE) != RESET) {2 z4 u8 k3 A3 Z! j2 \. [6 l  l
    (void)USART_ReceiveData(USART2);
6 _* }+ l2 Y6 o) O/ s. c, P) |  }
' |" y! Y8 T( B- g}
. l. I  b; H! S6 j$ k/**
; h) y" l- f0 i( S  * Function Name  : DMA1_Channel7_IRQHandler6 m9 `7 O# N$ V* {# B
  * Description    : This function handles DMA1 Channel 7 interrupt request.& D( A# j7 ^' p) u2 b
  * Input          : None  A. g  ~1 w1 x, \8 w" @
  * Output         : None
+ C: m. J) r% m$ d) v  @' Z4 e: h  * Return         : None
9 a8 W8 _2 H5 e  */8 Q  M* O8 \- g5 w
void DMA1_Channel7_IRQHandler(void)
, y% V3 h+ [4 [6 Q# D{% k* `# I7 U4 C% `/ C; N
  if(DMA_GetITStatus(DMA1_IT_TC7)) {
3 o: {* r1 _1 }$ ?+ q  V    /* USART2 DMA 传输完成 */
! }  G5 U% F9 @5 D; ]* W" _8 d- e    DMA_ClearITPendingBit(DMA1_IT_TC7);" a, o! l; f, Q2 l' a# F% F
    DMA_Cmd(DMA1_Channel7, DISABLE);3 ?8 u& j0 x$ q9 v* ~9 J
    /* Enable USART2 Transmit complete interrupt */
# x/ f2 A$ X2 W6 ]$ W" o    USART_ITConfig(USART2, USART_IT_TC, ENABLE);
# J$ F) O- w/ g" X/ r  }
/ _$ [- E& i2 o}
3 z) e6 Z* V* ]3 j; V- [
  i" |+ o; E, Z
收藏 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 编辑
$ k3 |  x" J) a8 D4 }
; j  h/ x2 W( b" j' B: b. Y6 Z所谓STM32F103串口数据的DMA发送,其本质流程如下:: u4 h  T( Z0 V6 v2 Z
1. 要发送的数据放在USART2_DMA_TX_Buf缓冲。4 [2 w9 i" ~2 `# }" W
2. STM32串口DMA发送和DSP相比的优势。6 T; M0 ~) ?$ r
   启动DMA传输后,USART2_DMA_TX_Buf缓冲中的数据通过DMA1_Channel7通道,' z% [  h/ \: i( O1 U
   自动传输到USART2->DR寄存器,这个工作不需要CPU干预,可以极大的节省CPU的资源。; ^6 A" ]4 y3 U( Q
   和DSP的FIFO相比,这优势很大,因为DSP的FIFO只有16字节,这意味着DSP的串口通过6 h) L, u" e0 o: M
   FIFO发送数据时,如果FIFO缓冲为空,可以迅速填入16个字节,然后去处理其它的事务。
4 E3 _2 y6 W( i/ O   而STM32的DMA发送则没有此种限制。更具体的说,如果DSP发送的数据超过16字节,+ Q  o* }& m3 c2 S
   则必须等待前16个字节数据发送完毕,然后再继续发送后续的数据,需要第二次甚至
/ j1 o# R, e% o6 N$ w# F' R   第N次处理。而STM32启动一次DMA就搞定(DMA最大传输65535个数据)。
  L" s7 i6 V; c# X3. 发送结束的一些事务处理
1 a) D, u7 Q. q% X) Y0 G   DMA传输完毕,数据全部通过DMA1_Channel7通道依次传入USART2-DR,这里开启了. h/ d. ?+ p) A& X3 j
   DMA传输完毕中断,进这个中断时,USART2-DR寄存器是最后一个要发送的数据,
' c7 m& k# y5 D) M/ C1 O. n: f   此时打开USART2发送完毕中断,进入USART2发送完毕中断后,可以设定标识,
) L$ Y8 T3 H1 t) {   也可以操作GPIO, 进行RS485的换向动作。# Z# {& S. h* K$ Y
4 b& v. ?: h8 g- q
最新的STM32F103的HAL库,几乎所有的通信,都可以启用DMA,HAL库函数抽象层次过高,灵活性不够,% e' q9 C- ~$ Z* o7 r
但比较适合使用操作系统的场合。可以把HAL库的宏定义拷贝过来使用,以提高标准外设驱动库的效率,& U: A2 ]7 C; Z. A% N
又保证标准外设驱动库的灵活性。
, L% u- b5 s+ t7 X0 x' H0 i  ?3 O9 ]8 E
9 `6 e2 R) y# A& n9 b2 p2 ^
6 m; c1 }2 a( f, `% b8 D. A
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管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版