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

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

[复制链接]
wjandsq 发布时间:2015-6-25 14:07
STM32电机培训online,大佬带你玩电机
3 U" l) t8 L5 F) [7 W- Q" p
% V  S5 B; K# d! A' d' g3 ?7 D$ s  D
#include "stm32f10x.h"
$ x& c: w( A- Y) ~+ F  ~#include "stm32f10x_usart.h"
" j8 l: ~9 ^' C+ u, k#include "stm32f10x_dma.h"0 K( Z* y  {; y

% C4 B2 s6 |, \' n# _8 p# \uint8_t HEX_CODE[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};' `! G0 a% g& d1 G! j1 A0 H& @. B
uint8_t USART2_DMA_TX_Buf[1024];
! o9 b$ t8 |. Tuint8_t Flag_USART2_DMA_TX_Finished = 1;4 ^6 U$ P& q' ^4 T5 }/ H0 v
uint8_t Flag_USART2_Send = 0;2 @' V) A( }; A3 F& {

. I' D) Q- S% w1 p. o/**
. _$ z( b# i0 B& T" N) _  * Function Name  : USART2_Config4 ~/ i& F5 X5 w! ?& S" k: G) Q- u7 `6 Z
  * Description    : None3 t0 o# S4 J7 @
  * Input          : None
6 F. Z% s+ D) i- |5 `  * Output         : None
: h& V* G" y! t# P% g  * Return         : None& W" N1 |7 E5 Y4 ~  O
  */! j4 Y; T! r/ Z. o% m+ n
void USART2_Config(void) {
% D& x+ A% P* E( d  GPIO_InitTypeDef GPIO_InitStructure;; |% z9 I8 D- x5 e3 w7 @+ @- t( d" W$ Z
  USART_InitTypeDef USART_InitStructure;
. G$ X8 S6 u$ E9 [- @3 M' r+ z4 [  DMA_InitTypeDef DMA_InitStructure;( h6 ~& Q) w) [5 ^; G8 K
  NVIC_InitTypeDef NVIC_InitStructure;
: `/ L( a; G- X
- q- U) c' n7 M3 V9 {) y: `  /* config USART2 clock */) D. L" k! q* i; B. `9 Z4 B
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
0 Y5 G3 S8 A4 p' ?& }+ m  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);1 S: T& R/ L/ V

0 E/ |2 K3 p1 I% f% k  /* *********************USART2 GPIO config **********************/
  C" p6 _/ l: |/ y! z1 t! v  /* Configure USART1 Tx (PA.02) as alternate function push-pull */) B0 T" i% z+ }/ w# I/ A
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; ) h# s5 Z' l8 G0 k- D- J
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
/ t  o% w; R. @  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
0 n7 F0 j/ q; g; I7 x7 e/ \! a, c  GPIO_Init(GPIOA, &GPIO_InitStructure);    : {" ^* y( L, w$ U
  /* Configure USART2 Rx (PA.03) as input floating */
5 ?: f1 z9 P9 C5 }- a8 h  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;5 R; }- f2 \1 {/ a
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;' n9 a7 r6 t; B# V$ ?* x
  GPIO_Init(GPIOA, &GPIO_InitStructure);
' l) V  g3 d* \; j' F5 h6 u- Y& x/ I5 E4 t% H% k9 M
  /* USART2 mode config 115200 8-N-1*/4 J# E/ G# ^* N; P8 j% j
  USART_InitStructure.USART_BaudRate = 115200;
  Q: s5 Z' A% V  USART_InitStructure.USART_WordLength = USART_WordLength_8b;7 v3 B5 b, C. z$ }9 i) b& M2 u
  USART_InitStructure.USART_StopBits = USART_StopBits_1;% g, }) Y2 T, f3 K6 Y) Q
  USART_InitStructure.USART_Parity = USART_Parity_No ;7 p  ~- M3 }! T8 W( ?3 R! [
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
) w0 _8 v7 k8 T( T7 |8 k- x& r  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;' P  M0 }9 I6 I& a
  USART_Init(USART2, &USART_InitStructure); : G/ w5 K3 t% G  t0 _; ?
  USART_Cmd(USART2, ENABLE);" `3 o- L9 N! C( I, N8 k

7 n2 s$ s: l' Z* K; ]8 j! V/ {6 s0 O9 a$ P
  USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);
# c7 l( ]0 m- L  /* Enable USART2 DMA TX request */
$ X2 x0 r! B5 o+ {  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);1 K: a4 M; b/ ]6 Q* t
  V4 Y# ]3 y0 _) P! j# `' `5 W, G
  DMA_DeInit(DMA1_Channel7);
' C7 f3 C2 `+ u* q8 J3 a7 }  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&USART2->DR);/ o( J/ [) F+ W1 I) P7 `
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART2_DMA_TX_Buf;$ ?1 A1 ?5 d4 T5 q1 r1 D
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
% w: ~( z, z; ?0 H6 J  e: g5 K  DMA_InitStructure.DMA_BufferSize = 0;
# N9 d3 O/ Y5 t* x& u$ w  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
) E* H/ H1 {; u& y- E  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
* s* T# M" n+ r8 Y9 i$ A  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;+ x4 j' L! p2 O$ V8 k5 ?
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
1 g, e4 N( E  t0 W  P  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;" H( N1 }$ Z+ a3 n6 _  O
  DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;2 F/ e0 s- D* L
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
) V2 b, f' ]$ x7 n6 J6 S$ z$ O5 T! ?  DMA_Init(DMA1_Channel7, &DMA_InitStructure);
4 C$ `1 x1 ^- O# e. l, c+ X  DMA_ITConfig(DMA1_Channel7, DMA_IT_TC, ENABLE);
" ^9 x* i% J9 |& h8 s+ V4 l& Y7 S5 k8 N+ w/ j% k- @
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
4 i' U& D( S& J/ \  V
- u' f  r, o# B+ q  /* Enable USART2 DMA TX Finish Interrupt */
2 Z; j5 _4 f* ?4 B  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel7_IRQn;; s0 f& ]5 m" _" @, R
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;- d+ x2 p: Y7 U5 W* R. `: y
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
3 M; W4 T( ^6 i% ?3 Y  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;0 |# x$ Z% {+ k
  NVIC_Init(&NVIC_InitStructure);; p1 [- d- s5 t. }( f+ P

* C. D% E) M0 b( o, ~3 q  /* Enable USART2 Interrupt */2 y: |: m+ J* E
  NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;* j& H6 a7 ?$ _% J7 S: o/ ^' f
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;/ n+ i' x$ W$ y# s6 X7 ]/ E5 K
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;/ W2 j4 {5 j  G0 h$ k2 Z
  NVIC_Init(&NVIC_InitStructure);
* o) z% h' d( X* e( \8 [9 e}
# i0 z1 f5 ~! `; t6 o) j/**
# D' r' Z) g8 _) H5 U  * Function Name  : USART2_Data_Load9 r) ]) E8 S- N: u9 L% ~) n3 r) G
  * Description    : None9 A8 D' ~$ v9 k. v7 R/ y
  * Input          : None
7 X% b: Q9 z$ j0 h  * Output         : None' P3 W) N9 s/ V" h0 l" o8 ]# y9 M
  * Return         : None# h0 u; s, c& T  @# `( Y, |* K
  */; ]) B, `8 n% v$ A
void USART2_Data_Load(uint16_t temp1, uint16_t temp2, uint8_t temp3){- U& d/ O) r* ]
  USART2_DMA_TX_Buf[0] = HEX_CODE[temp1 >> 4];
  W2 g8 V; s2 O8 f1 F. _  USART2_DMA_TX_Buf[1] = HEX_CODE[temp1 & 0x0F];
  i& i$ y0 `) h+ D+ K) \' W3 X+ p* R  USART2_DMA_TX_Buf[2] = HEX_CODE[temp2 >> 4];) e/ K6 ]8 e) ~; G5 t1 O
  USART2_DMA_TX_Buf[3] = HEX_CODE[temp2 & 0x0F];
, l1 Y, O( X' u4 L3 M3 G  L+ Q  USART2_DMA_TX_Buf[4] = 0x20;: `- j' R+ p' Y) W: {" c
  USART2_DMA_TX_Buf[5] = HEX_CODE[temp3];- ]2 e$ {4 |0 k! f* {: U6 t; m
  USART2_DMA_TX_Buf[6] = 0x0D;$ J5 H* `& m, r8 N% q
  USART2_DMA_TX_Buf[7] = 0x0A;
% J# p6 U  z' ~  Flag_USART2_Send = 1;. _7 h0 S% j/ [; c4 t
}% ?7 v0 O. u/ r) u( J4 }0 u
/**
, Y5 T9 W  D  _. @5 Y; G  P  * Function Name  : USART2_Data_Send- X' w- }0 x& e
  * Description    : None
7 \, K! ~* ^9 g; o/ n9 _* v: p- L  * Input          : None
* m8 \1 b4 a, R+ Z) H  * Output         : None, y; [! G# k; U2 f
  * Return         : None( W- X# H; P+ l% k" R! M
  */, R: ~% e! U8 B/ ]* d' t- x' E
void USART2_Data_Send(uint16_t len) {
4 f5 l. u& c! t* [8 z9 K2 d* X  if(Flag_USART2_Send){
# F! C% @# k6 b; h( r    if(Flag_USART2_DMA_TX_Finished == 1){, n+ Y- `0 e* J% {7 n
      Flag_USART2_DMA_TX_Finished = 0;( [6 }, O- a& ~# B7 q2 }/ g
      DMA1_Channel7->CMAR  = (uint32_t)&USART2_DMA_TX_Buf[0];4 d* v3 K$ k# |1 N; I
      DMA1_Channel7->CNDTR = 8; // len
" h- a0 H' O* o  q+ x8 W      DMA_Cmd(DMA1_Channel7, ENABLE);1 \8 m! f" D9 t& @+ X- Y
      Flag_USART2_Send = 0;
3 x  v$ x3 a5 T5 U2 U    }6 [6 ^- B" c; E
  }
, u' i) f- g* ], I# f( a}# ^2 C+ ^7 x: n9 d2 x
/**
2 c0 H3 w8 s, F* t, ~  * Function Name  : USART2_IRQHandler
( F9 D$ z6 w9 {: ]9 o  * Description    : This function handles USART2 global interrupt request.& y! P% B6 H- i+ D' [: K- B
  * Input          : None$ B# m! h2 |& l; A3 \) C4 m: v
  * Output         : None
4 k( ^# ]& M7 ?' s5 X  * Return         : None; i  g1 q% g6 p5 g+ @9 f
  */
& c1 S% w3 W% Evoid USART2_IRQHandler(void) {
+ u4 m7 f  G5 m$ S* X0 B5 K  if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET) {! U& B( l- u$ `! H5 f1 q
    (void)USART_ReceiveData(USART2);. i2 `2 P- |$ ~3 X! g3 i. K: s, y
  }
* E% B! g( i4 \! \  if (USART_GetITStatus(USART2, USART_IT_TC) != RESET) {
" N5 ^" `5 K) ?1 ~    /* Disable the USART2 Transmit Complete interrupt */) r1 k" u/ w* U) N' N+ g/ a# U
    USART_ITConfig(USART2, USART_IT_TC, DISABLE);
% L7 @8 U' Q, r2 X# d7 X% x3 J    Flag_USART2_DMA_TX_Finished = 1;
: n, _8 E, k+ A4 ]5 Z7 F  }     # r, H, L8 g  g9 s# v( j
  /* If overrun condition occurs, clear the ORE flag a.nd recover communication */    4 L0 b, l4 N3 q
  if(USART_GetFlagStatus(USART2,USART_FLAG_ORE) != RESET) {! u9 K" y" u+ B# Y
    (void)USART_ReceiveData(USART2);8 P9 m( C) w' W3 w
  }0 }7 g8 n( \9 e* v, U% {5 S
}
: |! l( t7 i2 j6 _' }* |( e/**& y* @  ^3 U9 B& K2 K  U2 B) A
  * Function Name  : DMA1_Channel7_IRQHandler! C& I6 b* t) O! Z+ A
  * Description    : This function handles DMA1 Channel 7 interrupt request.4 Q6 ?/ e% l# _6 x
  * Input          : None
5 k5 K( u! N8 x& E+ w  * Output         : None6 O2 H8 l$ `% U  u6 f
  * Return         : None2 R0 Q2 h3 M" _  y- e* V; n- z' ?' D
  */
. F3 J, ]0 [, q3 x7 M. ?2 u! ?void DMA1_Channel7_IRQHandler(void)" q4 M/ A6 h  Y8 y9 y
{
% f8 A3 L4 Z9 w# X  if(DMA_GetITStatus(DMA1_IT_TC7)) {, _) E; Q5 E! p
    /* USART2 DMA 传输完成 */( I! \' t$ l* z2 n1 v. x
    DMA_ClearITPendingBit(DMA1_IT_TC7);6 T  G& _) U! [, m, U
    DMA_Cmd(DMA1_Channel7, DISABLE);) ?4 B2 {( J! V+ r- {0 g4 R
    /* Enable USART2 Transmit complete interrupt */; Z' Q9 o* J8 v- f$ ]
    USART_ITConfig(USART2, USART_IT_TC, ENABLE);
* l& V' S& F" L  }; r( f: X' J  c4 N3 t! q5 P" `
}; K4 o' W2 }" R# V4 D% s

0 e; Y  b  N3 @7 i8 _
收藏 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 编辑
# L+ E. v1 e% N5 G" m, c
) U$ y+ m# k5 y! q所谓STM32F103串口数据的DMA发送,其本质流程如下:
6 N* i$ a+ }$ e# P. w1. 要发送的数据放在USART2_DMA_TX_Buf缓冲。
1 l6 n2 f# r- M" `: b, f2 H2. STM32串口DMA发送和DSP相比的优势。. t: j- X8 k5 x$ \( ?1 d, C
   启动DMA传输后,USART2_DMA_TX_Buf缓冲中的数据通过DMA1_Channel7通道,0 }2 j1 J+ [9 l
   自动传输到USART2->DR寄存器,这个工作不需要CPU干预,可以极大的节省CPU的资源。
) R3 [# A8 s9 Y1 c# C   和DSP的FIFO相比,这优势很大,因为DSP的FIFO只有16字节,这意味着DSP的串口通过: h. v2 ]. r. ~8 g& L9 w- K! G: ~* G
   FIFO发送数据时,如果FIFO缓冲为空,可以迅速填入16个字节,然后去处理其它的事务。: B9 H# _4 Q6 ^- c6 T
   而STM32的DMA发送则没有此种限制。更具体的说,如果DSP发送的数据超过16字节,
8 r& a, k  ^% @2 ^5 `3 Y   则必须等待前16个字节数据发送完毕,然后再继续发送后续的数据,需要第二次甚至
" j- q7 l# x7 |# ]% L   第N次处理。而STM32启动一次DMA就搞定(DMA最大传输65535个数据)。
  ~% r+ V: y7 P3 N& [3. 发送结束的一些事务处理5 U" U- W; h' H0 \1 ]1 K8 m, i
   DMA传输完毕,数据全部通过DMA1_Channel7通道依次传入USART2-DR,这里开启了" ?7 m, g# I/ w8 ?" `
   DMA传输完毕中断,进这个中断时,USART2-DR寄存器是最后一个要发送的数据,
1 u% ~% f, I7 Z! v# U% x   此时打开USART2发送完毕中断,进入USART2发送完毕中断后,可以设定标识,$ o& E# S* H& V
   也可以操作GPIO, 进行RS485的换向动作。0 |, \5 S# I' z+ y) W
; V# ?( T7 @8 w+ j; `: s7 Z, ~4 \! g/ x
最新的STM32F103的HAL库,几乎所有的通信,都可以启用DMA,HAL库函数抽象层次过高,灵活性不够," @0 F2 n. i" g2 c# Z. \
但比较适合使用操作系统的场合。可以把HAL库的宏定义拷贝过来使用,以提高标准外设驱动库的效率,
9 x7 X* i6 F1 |: W# E- z: \+ s又保证标准外设驱动库的灵活性。7 t% q' p/ P6 I6 a5 a$ P

! |: M' {1 P' t3 Q2 b9 k$ g* k7 v' e" c5 M  B3 k- ^4 v) K

' L4 q# {( `1 X& I+ q
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管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版