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

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

[复制链接]
wjandsq 发布时间:2015-6-25 14:07
STM32电机培训online,大佬带你玩电机
1 [( y1 E, V7 x% r! d& s; Y  R  n  o$ s
' c% Y2 |8 }' n" l
#include "stm32f10x.h"
( ~6 w9 m  w5 y+ X8 }9 p#include "stm32f10x_usart.h"
  }4 z' [; M0 z$ h4 I#include "stm32f10x_dma.h"* [+ F, I' X  S6 m- e' A
2 h$ s* `4 Z+ M# b7 z7 J
uint8_t HEX_CODE[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
* ^6 P5 F+ h$ ^! T6 c: h* }, ~uint8_t USART2_DMA_TX_Buf[1024];
$ \  [. j4 |+ m& }' ?* m% zuint8_t Flag_USART2_DMA_TX_Finished = 1;! L" X& N5 f, t7 g
uint8_t Flag_USART2_Send = 0;/ o! f, A. R* O

& b: I2 k# y' s1 T  ]/**
3 Y% u( T' W+ `; W, E7 q3 [' P  * Function Name  : USART2_Config
% h$ h7 f; Y  j& d& N" _. f  * Description    : None9 K' ?: k- T  C! R
  * Input          : None
, U: G  Q( L: X0 J2 Y1 O  * Output         : None
- I5 j+ K& Z3 r* A; @  * Return         : None
5 H4 T' q1 f. C/ h  */
7 a! I/ j- I5 N7 v" zvoid USART2_Config(void) {
7 Q8 I6 s! l5 [9 `. i* c  GPIO_InitTypeDef GPIO_InitStructure;
6 F- l" _1 B5 R2 J' C  USART_InitTypeDef USART_InitStructure;2 H$ s# |* w  C$ D* c( M
  DMA_InitTypeDef DMA_InitStructure;
6 m2 ]% b0 O7 U6 Y: X) i  NVIC_InitTypeDef NVIC_InitStructure;
# x8 c' N4 ~; Q# t+ l8 \) K% |; Y  x* T4 \9 r
  /* config USART2 clock */
6 e- y) G4 L  m4 Y! k3 n) R  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
! f) |2 ]3 g8 G4 c  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);; z! }& Z& N" G! J

/ @) i1 ~) g3 [& d# f  /* *********************USART2 GPIO config **********************/+ {- m% l2 D/ X& f- q" w
  /* Configure USART1 Tx (PA.02) as alternate function push-pull */
. E# C9 _, C% w& U7 }1 c3 A9 O  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
" I2 d" f6 V3 l  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
! w# `9 D; F7 k! V) z+ [( S  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
0 f  b8 S, ~" l' R0 V( S  GPIO_Init(GPIOA, &GPIO_InitStructure);    ; v0 `+ q9 X, a3 P5 L" \
  /* Configure USART2 Rx (PA.03) as input floating */" p* O% U8 v% B# I
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
, E6 ?; @$ E0 \- r7 j  {& l  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;) j3 h0 T; J- t6 n
  GPIO_Init(GPIOA, &GPIO_InitStructure);
2 Y1 j; i- j4 n" Q
- |4 j  r% w# F* v  |; \/ E5 p  /* USART2 mode config 115200 8-N-1*/
* [% p- ~8 F, _4 z3 Z  USART_InitStructure.USART_BaudRate = 115200;
" E. X9 A2 m2 z! n( u' S% x  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
4 A, d, ~, ]' S. {: k$ A5 i; D  USART_InitStructure.USART_StopBits = USART_StopBits_1;5 |1 h# E% o# `; I5 E3 |' i5 U
  USART_InitStructure.USART_Parity = USART_Parity_No ;
0 r5 b4 J5 _1 _/ K4 J+ v2 Q  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
+ [% D" w! M7 b. |7 x$ S: K  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
" U* x5 b2 e+ m5 Y  USART_Init(USART2, &USART_InitStructure); ' \* k3 g1 h7 I: i+ f7 P& j
  USART_Cmd(USART2, ENABLE);
: C9 G8 z& r# O4 o/ {$ }
1 l. V4 H8 c  T" G" q  N
5 y, l  U  F4 h+ z; g/ c3 L  USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);1 n3 S  w4 c$ t8 ^; k8 _: R9 ^
  /* Enable USART2 DMA TX request */# j# l% W* R0 q" c
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);* G9 @4 x* C. n% ?' D/ U9 v9 [  G

" X$ d+ ]/ G; h  A& _' H1 X6 Y  DMA_DeInit(DMA1_Channel7);- N- {) _6 w9 F
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&USART2->DR);
9 K8 U/ G& Y' {' d1 a  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART2_DMA_TX_Buf;6 t  k) [5 A) ?/ {: l
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;/ |2 e- o8 @+ h1 D3 I
  DMA_InitStructure.DMA_BufferSize = 0;' K- R9 p2 G& R! o0 h
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;, |* `8 W. l! G6 x! I
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
: C1 O/ M* c" T7 H* ~9 D- P  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;0 \# Y- p6 s( [$ W5 S! M
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
$ g: c& v; b" U9 p! j- y  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;7 ~# H1 v. s! F" @0 ?  F# U% [. U/ c
  DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
/ S2 d& T. B% p0 y  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
: n, K7 d; `, @. h  DMA_Init(DMA1_Channel7, &DMA_InitStructure);
$ _4 }* w: u8 o9 D5 y5 B  DMA_ITConfig(DMA1_Channel7, DMA_IT_TC, ENABLE);; o6 f2 d7 {. {1 f
/ D* R  `3 w  \3 U2 \$ r& w
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);0 b+ Y0 l: k/ H5 d& N' I0 S7 e

6 S- @* m  Q0 u& D  /* Enable USART2 DMA TX Finish Interrupt */6 ]' y* D; F( Y7 J& _; j6 e
  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel7_IRQn;
! b- `) Y$ B+ E' }$ E  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;0 m% h! C. p3 s- D
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
+ y5 F$ d4 d$ b7 x0 v  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
$ o/ v( d( Q  F. Q9 L  NVIC_Init(&NVIC_InitStructure);" r' S2 J; G) K9 \
* `0 k7 a; O8 r' Q1 b
  /* Enable USART2 Interrupt */
  m* ?6 G3 S, v/ `3 P6 u; f1 e  NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
1 M$ E. Z3 n6 |2 [) @  B# t% L2 [2 w$ `  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
2 B# f" c; r% d; l. ?. C& m. N  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;8 a& t2 e$ t0 C& `9 a
  NVIC_Init(&NVIC_InitStructure);' ?: u, g' |" J3 }! P
}
6 J& n+ L: G/ B/**
, D3 `+ R7 x! c0 A5 W  * Function Name  : USART2_Data_Load: g8 ^7 N6 P3 P0 T0 }+ \* ~
  * Description    : None
4 p# {4 K6 m8 A6 r' B+ `( D  * Input          : None
( d  S% c' p3 @$ C5 d% t& n  * Output         : None3 D" Q) y, x$ _5 J/ J5 Q
  * Return         : None) O. M% z. u9 q. g. `) i( l* |  C0 ~6 j
  */. l  f! F, }7 L" N- y7 |5 `- h7 s
void USART2_Data_Load(uint16_t temp1, uint16_t temp2, uint8_t temp3){
/ L5 [+ M" h0 j: R( M  USART2_DMA_TX_Buf[0] = HEX_CODE[temp1 >> 4];: E5 M2 ~8 @; \* T! n  r+ ]
  USART2_DMA_TX_Buf[1] = HEX_CODE[temp1 & 0x0F];
1 `  f7 S0 ?1 z9 u  USART2_DMA_TX_Buf[2] = HEX_CODE[temp2 >> 4];
9 o5 _+ O) G& q' f  |) R. x9 c  USART2_DMA_TX_Buf[3] = HEX_CODE[temp2 & 0x0F];
8 [' |. K7 N+ n" a  USART2_DMA_TX_Buf[4] = 0x20;
9 a0 {+ @+ u) Y  USART2_DMA_TX_Buf[5] = HEX_CODE[temp3];
) x, v  }( s5 c# q  USART2_DMA_TX_Buf[6] = 0x0D;
! K0 e$ ?7 s. k/ u4 z! x  K. Q  USART2_DMA_TX_Buf[7] = 0x0A;
; l: k( `9 O3 @; M9 r  Flag_USART2_Send = 1;8 \" h4 G9 U6 r1 Q. d. ^
}/ q8 r- M0 U: @  N" L% G
/**2 ~% W- ~4 D8 @/ P4 Q( Q9 D
  * Function Name  : USART2_Data_Send6 Q% z5 _6 L/ a7 v- s! t
  * Description    : None; Z6 N% Y9 o5 |& d
  * Input          : None
7 ?; V+ b- y# n3 L; i: C  * Output         : None& D- f7 o  D9 _; ~. v
  * Return         : None
( I5 v' d9 R2 d! K  */
5 r  W8 ?2 x3 |, b/ `8 `8 ?void USART2_Data_Send(uint16_t len) {: X' ?8 E9 M: v* N; H% Y6 N
  if(Flag_USART2_Send){
& I+ [. r2 q  f: B, E    if(Flag_USART2_DMA_TX_Finished == 1){
& A- u1 U& V9 Y. d; M      Flag_USART2_DMA_TX_Finished = 0;
3 }% ], e0 `* y+ N: W      DMA1_Channel7->CMAR  = (uint32_t)&USART2_DMA_TX_Buf[0];! d7 I# B2 e% _* N' U, ^4 p( v
      DMA1_Channel7->CNDTR = 8; // len9 w, ~3 Y7 a2 Y
      DMA_Cmd(DMA1_Channel7, ENABLE);
; n. M/ |  D$ i$ V5 x1 C      Flag_USART2_Send = 0;1 Z5 o+ O7 z0 e- ^$ y- w
    }* T* }$ K' R$ H! a& c
  }1 P" c5 _9 f* V+ m: P" Y8 I
}  a* i$ F8 G. a3 Q3 D
/**
. \/ U1 p  d/ P- G7 n- U. P1 w, p  * Function Name  : USART2_IRQHandler
1 T  d# v& W+ A. ~% z8 J, ]9 Z  * Description    : This function handles USART2 global interrupt request.* o6 L/ N% K; [% I) O
  * Input          : None& {- y: A; B3 v
  * Output         : None7 I5 k6 f: B! m
  * Return         : None
' ^: ?* d# D0 b0 D: j6 w  */: b+ G* S* F; t) x& y
void USART2_IRQHandler(void) {* [" y" j1 _3 w7 a/ o4 {
  if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET) {1 {: v# `! M! j% h+ p
    (void)USART_ReceiveData(USART2);
  G7 @& O- o% T3 N  V9 Y0 B: w  }2 \( ]. |- R& Q+ f
  if (USART_GetITStatus(USART2, USART_IT_TC) != RESET) {
: I. W* j# E; Z4 ~5 Q) t$ m    /* Disable the USART2 Transmit Complete interrupt */- m7 K+ y$ A9 |5 R# o5 G
    USART_ITConfig(USART2, USART_IT_TC, DISABLE);1 D' r, L2 i" u; I1 Q1 j+ |
    Flag_USART2_DMA_TX_Finished = 1;# `) I3 \1 I) b1 j$ ?& V" W
  }     
+ }2 }5 [+ [- k  X' b  /* If overrun condition occurs, clear the ORE flag a.nd recover communication */   
7 k  \1 e, l# r1 i' K! w  u$ u7 x  if(USART_GetFlagStatus(USART2,USART_FLAG_ORE) != RESET) {. q; C5 u# T9 Q+ p
    (void)USART_ReceiveData(USART2);0 Y1 U- e: U. L* r
  }
, m* e9 c$ l/ \& R}; n& H) T* G3 a
/**
' a: r9 l! m  B" L& c, P  _  * Function Name  : DMA1_Channel7_IRQHandler) G" W! y, p0 A$ w. @
  * Description    : This function handles DMA1 Channel 7 interrupt request.
2 I8 L% o: W' y  * Input          : None
/ A! v+ _- Q" g1 }2 h! Y% M" r/ t  * Output         : None
" T! ^6 G/ a$ y* y  * Return         : None
: \/ F' l4 O. `9 H# c  */
0 R5 o0 Q, c! a( b' Wvoid DMA1_Channel7_IRQHandler(void)
; O9 p1 c- K9 n* k0 m3 }{/ h8 A! C5 H$ g! R$ F+ J
  if(DMA_GetITStatus(DMA1_IT_TC7)) {
0 U2 G% S! e$ Y/ Q& B8 T    /* USART2 DMA 传输完成 */# x3 c& m. ^3 ?' K* m9 s. Z2 h
    DMA_ClearITPendingBit(DMA1_IT_TC7);
- ]9 \( P( |* ?' M2 D# B: Y1 X; L    DMA_Cmd(DMA1_Channel7, DISABLE);+ q: t" j) g3 `4 V% Y& b# {
    /* Enable USART2 Transmit complete interrupt */! x4 ?2 o8 U9 t- f% U! s3 r. ?
    USART_ITConfig(USART2, USART_IT_TC, ENABLE);
9 h# Y* W4 t2 j& l. ]9 Q  }0 Y( M2 s# I3 i7 M; m& J
}
. T: f7 L7 t5 F& @% Y
+ `! O5 ^- V5 w$ 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 编辑 5 Q/ M: \- a9 l+ d. x" w

0 @+ Q: Y2 |0 \6 A+ [. Z; z' V所谓STM32F103串口数据的DMA发送,其本质流程如下:
  u  a. y# I0 I& b+ @1. 要发送的数据放在USART2_DMA_TX_Buf缓冲。# k; W) ~0 g  G1 D! S3 b0 F
2. STM32串口DMA发送和DSP相比的优势。
/ n* ^; d) ]7 v3 ]. b( n   启动DMA传输后,USART2_DMA_TX_Buf缓冲中的数据通过DMA1_Channel7通道,
3 S7 w$ g3 M  h0 y8 @   自动传输到USART2->DR寄存器,这个工作不需要CPU干预,可以极大的节省CPU的资源。
" ]1 M, P# Z7 l, @4 Z- M+ i   和DSP的FIFO相比,这优势很大,因为DSP的FIFO只有16字节,这意味着DSP的串口通过
1 [( f7 a, ]$ |  f& C   FIFO发送数据时,如果FIFO缓冲为空,可以迅速填入16个字节,然后去处理其它的事务。6 {9 y' q/ J/ B" X
   而STM32的DMA发送则没有此种限制。更具体的说,如果DSP发送的数据超过16字节,
" ]2 `" c2 {) D4 A, _   则必须等待前16个字节数据发送完毕,然后再继续发送后续的数据,需要第二次甚至  ]4 O- @6 b2 G
   第N次处理。而STM32启动一次DMA就搞定(DMA最大传输65535个数据)。
. f% y: r/ @6 m( Y3. 发送结束的一些事务处理
" F3 U/ j6 E( X9 u! O- t: S0 Q   DMA传输完毕,数据全部通过DMA1_Channel7通道依次传入USART2-DR,这里开启了: c  n# S& y4 @8 Q6 R( ~
   DMA传输完毕中断,进这个中断时,USART2-DR寄存器是最后一个要发送的数据,; K9 Q9 h+ ^1 ^3 h
   此时打开USART2发送完毕中断,进入USART2发送完毕中断后,可以设定标识,) U6 @0 Q- A4 V7 t5 C
   也可以操作GPIO, 进行RS485的换向动作。0 I5 I$ s" Y; u- V$ _) S! h
9 F, `% O" c4 q8 {% ~, u
最新的STM32F103的HAL库,几乎所有的通信,都可以启用DMA,HAL库函数抽象层次过高,灵活性不够,
2 z8 Z7 c4 A. {9 C; {9 s8 h! Q但比较适合使用操作系统的场合。可以把HAL库的宏定义拷贝过来使用,以提高标准外设驱动库的效率,1 v$ S% |" Y- y) u7 j0 ?
又保证标准外设驱动库的灵活性。1 @+ c$ N+ K! Z' L( C. {
6 U# V: {# K, J, o
0 {; R5 A1 {8 |9 P

# f. G' P1 u  B: P2 M( `$ T
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 手机版