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

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

[复制链接]
wjandsq 发布时间:2015-6-25 14:07
STM32电机培训online,大佬带你玩电机
: a' d, ]0 Z; ~" ]" e* w# I* ]& o' u* V

# H0 ]1 v" ?; u3 l& j+ K#include "stm32f10x.h"
+ H. b* J  f8 W8 p( K  q, W#include "stm32f10x_usart.h") D+ U! n. ?& L. ?5 }
#include "stm32f10x_dma.h"
% }* T0 F% m: z: w5 u9 m# M, {) r/ h* G7 D6 P8 L# ~
uint8_t HEX_CODE[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};; Y$ ^! P# o) b" r4 i1 ?0 U6 n8 c( |
uint8_t USART2_DMA_TX_Buf[1024];
( W) P! B" P9 W/ Z/ ruint8_t Flag_USART2_DMA_TX_Finished = 1;3 o# P/ u3 `; Y6 t1 O
uint8_t Flag_USART2_Send = 0;
5 J% ~4 w& i* X1 M# }9 }: ?& D7 A2 I
6 `- B9 m! o7 ?/**3 g. I4 P; a* Y, F
  * Function Name  : USART2_Config  u1 s/ M5 q% N. |
  * Description    : None
5 }9 y0 ~7 \+ j  * Input          : None
, ^- \7 J* g1 g# ?; X2 i  * Output         : None" Q0 ]/ A; g# a
  * Return         : None" k! g4 p0 z. K% V$ i# B
  */: E5 T. q6 C) D1 R
void USART2_Config(void) {
- J0 j3 K0 u( w- m  GPIO_InitTypeDef GPIO_InitStructure;
- ]# d  R, W* U  USART_InitTypeDef USART_InitStructure;
7 o0 n1 g  G5 K# M2 p  DMA_InitTypeDef DMA_InitStructure;8 L* z; G2 U; Q
  NVIC_InitTypeDef NVIC_InitStructure;
; \2 x- ^  i9 d) |, d
1 v# Z7 R/ l& Y7 x  /* config USART2 clock */
3 v6 B; p* y4 x& k  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
4 t1 Q* J1 N" `8 \* X3 x. G  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
. V0 N$ |5 x3 C; g, o7 [# R/ k
! b& ^1 X# g; k0 l  /* *********************USART2 GPIO config **********************/+ a' @$ L3 I7 Q# u
  /* Configure USART1 Tx (PA.02) as alternate function push-pull */
( c, i+ W4 @! G: M$ u4 W  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; ! T& r4 R' r+ L* T0 i
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;1 o0 V8 c3 N& a: w7 L% K. `
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;: ]$ R' V' b- r/ w$ a+ e
  GPIO_Init(GPIOA, &GPIO_InitStructure);    & X1 ]/ ?7 w% N, o( b' F
  /* Configure USART2 Rx (PA.03) as input floating */
6 W& d7 d: T" K  K0 D* U  S  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
) s" B/ f6 r6 D1 `" |5 y0 C  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;7 g9 M- v" n' L* b5 e' O  a
  GPIO_Init(GPIOA, &GPIO_InitStructure);! v' {7 j* `. A7 Y! |( ?: I
6 X7 M3 I! o, R3 f5 t& j# l4 }% z
  /* USART2 mode config 115200 8-N-1*/
9 f% B' k0 w/ y1 q5 w  USART_InitStructure.USART_BaudRate = 115200;5 A& @1 Q. @, ~2 `$ f4 e/ n
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;/ g, ~0 D! B4 T( q! @& Y3 }! `
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
# V' Y. M$ H0 c% A; F# z  USART_InitStructure.USART_Parity = USART_Parity_No ;3 T; G2 j7 o# M) c+ h. c
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;9 p9 K. T, w+ d: W/ |
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
# g6 D2 u3 G; b2 o$ T% ^, B& d  c  USART_Init(USART2, &USART_InitStructure);
4 o2 X% x& @5 i9 O8 C  USART_Cmd(USART2, ENABLE);6 M/ `/ ~) q9 D  D' v
5 s' I' ]! v3 Z5 A

* D0 {7 z$ b+ `. f7 X) b  USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);) B! z+ o% A  G7 z0 `5 g3 L. T
  /* Enable USART2 DMA TX request */% O: S2 E" p$ K$ z0 H5 |7 J
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);- k/ x/ W3 b0 j+ A) Z

. T& ~8 D( w2 p! z& a3 e- E  DMA_DeInit(DMA1_Channel7);" @$ ^8 }1 ?) z$ O, a
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&USART2->DR);$ o7 F! h0 [0 q; o
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART2_DMA_TX_Buf;) a$ n! v2 Y7 T' \
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;: j% t8 }4 b* n1 s+ t
  DMA_InitStructure.DMA_BufferSize = 0;4 Z+ S3 \& v+ `6 m7 G* g
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
% B7 C/ Y% d) K# P( Y  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;2 {6 g; o) c0 R" t, c. h, w- A9 D4 S
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;4 }7 `9 f5 }" n3 J
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;5 Q1 t0 c1 X4 M8 p: e" U
  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
* c. n! F' ~4 B0 Z6 }: ]  DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;! u" j) l: }6 g; _0 C: b
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
6 f9 N1 `, o6 G  DMA_Init(DMA1_Channel7, &DMA_InitStructure);
4 I! S) O+ L- R4 `) @7 |& a, @" V  DMA_ITConfig(DMA1_Channel7, DMA_IT_TC, ENABLE);6 ^2 V4 B/ J9 T( r* U
1 k6 a$ i& a3 ]( |
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);& C. X  z7 I# \7 q; R! |1 u7 N
: i3 E5 h/ K- h% q# ]; s
  /* Enable USART2 DMA TX Finish Interrupt */
* n& {) \/ z. Z. l( @6 p  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel7_IRQn;9 H# N3 S$ t; ~3 K
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
& N$ W+ |* ]. g& |) n: h0 x5 I  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
9 z+ j- z$ ]2 }0 ^  o' y  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;& p& X: N) Q1 e; f. z
  NVIC_Init(&NVIC_InitStructure);
! [0 G# p, h( m, e& V
7 D0 e8 M# `: P% a+ j  /* Enable USART2 Interrupt */
( k! h: q) T# m+ ^' y: I  NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
( `  X2 ^% w6 ]: \4 D  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;) E% D3 s5 w, a  P
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
0 _% i3 X' U7 C, R" x  NVIC_Init(&NVIC_InitStructure);* {: h9 s- `4 }0 Z
}
; {/ @9 G3 e2 r. i+ A: ?+ s/**
3 q8 i/ k' F6 K& X  e  I  * Function Name  : USART2_Data_Load8 J+ p1 q5 n0 Z
  * Description    : None
0 b/ _! G) m+ _% q) r  * Input          : None$ _3 N1 ?! s/ u2 Y8 c* M
  * Output         : None
# C# @! Y! f3 X" P# s4 z  * Return         : None6 @' u& K# P1 ?& w$ o% y' X6 k
  */5 ]! F6 B( N3 f) h9 c- f) C
void USART2_Data_Load(uint16_t temp1, uint16_t temp2, uint8_t temp3){
3 u+ I  e( E4 ~. d  USART2_DMA_TX_Buf[0] = HEX_CODE[temp1 >> 4];% f3 D+ R- k% G8 t
  USART2_DMA_TX_Buf[1] = HEX_CODE[temp1 & 0x0F];
; i- I& P& c* {# F" c  USART2_DMA_TX_Buf[2] = HEX_CODE[temp2 >> 4];! a1 i1 m% `+ `4 ]. ], w
  USART2_DMA_TX_Buf[3] = HEX_CODE[temp2 & 0x0F];
$ P8 D5 L* Y+ I+ X$ T% {1 C& u  USART2_DMA_TX_Buf[4] = 0x20;! u5 Q7 m- B) q( n
  USART2_DMA_TX_Buf[5] = HEX_CODE[temp3];
1 Y6 h5 T! O2 Z; A  USART2_DMA_TX_Buf[6] = 0x0D;1 d) m6 r$ N$ J  T; r; O' E! i# e
  USART2_DMA_TX_Buf[7] = 0x0A;
& b1 n3 z! @# N/ W: e! f! R1 ?! w0 A6 \  Flag_USART2_Send = 1;
6 Q2 ^7 c0 F2 `& M- E- _. l( O- F}; f. V0 _  N2 T
/**- J8 O/ N) B3 ~0 U0 j
  * Function Name  : USART2_Data_Send
( F0 f: d* {" w; |7 @  * Description    : None) U" w+ ^: R6 o+ j) c9 R& p, P& h
  * Input          : None
# ^1 A0 h8 \+ Z# G  * Output         : None7 P  d  x3 {4 r) i, E$ ^9 z% @$ K
  * Return         : None. `- N% F& j4 \
  */
# D& v  x4 }+ y  E: p+ P* Pvoid USART2_Data_Send(uint16_t len) {5 e. n7 \# X4 o. L0 A2 M5 ?8 l
  if(Flag_USART2_Send){0 y" G0 q! K$ }9 V
    if(Flag_USART2_DMA_TX_Finished == 1){
- u$ p8 L5 |& o/ C7 y' N& m      Flag_USART2_DMA_TX_Finished = 0;9 S% x2 T- c6 Y
      DMA1_Channel7->CMAR  = (uint32_t)&USART2_DMA_TX_Buf[0];
9 n/ N8 H( p  n, i      DMA1_Channel7->CNDTR = 8; // len% q1 \; f; P/ i
      DMA_Cmd(DMA1_Channel7, ENABLE);4 B) U6 U+ ^0 S7 |
      Flag_USART2_Send = 0;+ B+ p0 q2 G$ v. a) O/ A3 X+ E
    }
: a* y; F" W# E& A  }
1 f* M8 S% m  e* r1 r$ _}
: I) \! e0 O3 x/ C/ |/ O3 _/**
8 a7 I- @- @) W: ], i: P  * Function Name  : USART2_IRQHandler
/ ?! q; H) O9 Y) J' v/ ]9 i$ [+ J  * Description    : This function handles USART2 global interrupt request.7 m1 V% [- _( |5 E* n4 m5 {
  * Input          : None, a& D( x/ ?5 \( l( }
  * Output         : None
: [1 E  _# \! L' z7 c  * Return         : None
! x% H7 s4 O9 ]# D# p9 k; j. u  */
& a: `, _, X- a, v, Q# Xvoid USART2_IRQHandler(void) {
" _  {* w% l+ w; e9 w  if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET) {
( `9 B6 m' M# W' H: f    (void)USART_ReceiveData(USART2);
* a/ K5 Z6 R: W  }
  h; b3 x  I7 _  a  if (USART_GetITStatus(USART2, USART_IT_TC) != RESET) {
- `$ g# I. Y7 a% Y* B" r    /* Disable the USART2 Transmit Complete interrupt */" o( ]( B# `: M; \9 y
    USART_ITConfig(USART2, USART_IT_TC, DISABLE);
/ C; w, P# Y: Y& V9 n8 Z    Flag_USART2_DMA_TX_Finished = 1;2 X1 h1 T, y: v' l
  }     3 E) q0 H: c2 h: Y0 G
  /* If overrun condition occurs, clear the ORE flag a.nd recover communication */    * O  d" G. D7 T' Y& T# K5 F
  if(USART_GetFlagStatus(USART2,USART_FLAG_ORE) != RESET) {, v+ M% N, G: D$ J  d
    (void)USART_ReceiveData(USART2);, W2 }7 s+ @1 D, U5 g; g
  }
) ]5 c* w; E" D! I8 E+ X7 t" \}
, `7 H7 z! F$ r6 x/**7 n2 g+ Y6 C: T  K' z
  * Function Name  : DMA1_Channel7_IRQHandler
# a; b( S! e6 R& _* V  * Description    : This function handles DMA1 Channel 7 interrupt request.. ^) x+ r8 H1 B" ~: P' E, W
  * Input          : None0 ?2 q. S* M9 f6 O' m. v: m
  * Output         : None
4 `  _3 O. h+ {5 O  * Return         : None
  a1 }# \: T( g+ r; R  */
8 m3 B. B$ T! G3 X0 h( Ovoid DMA1_Channel7_IRQHandler(void)
7 M) }6 y9 a  a/ A' ^' j{$ J6 J! n, R+ }0 X! L& m
  if(DMA_GetITStatus(DMA1_IT_TC7)) {
9 G: u7 r, \- r+ n& ~' `    /* USART2 DMA 传输完成 */
3 R( A% P2 ^7 V! D    DMA_ClearITPendingBit(DMA1_IT_TC7);
$ c7 c7 q+ J: t    DMA_Cmd(DMA1_Channel7, DISABLE);4 z8 c, U7 x- P: q- i$ M0 ^# R
    /* Enable USART2 Transmit complete interrupt */
: N& S5 ?! V+ E) t! m" g0 M( ^; l    USART_ITConfig(USART2, USART_IT_TC, ENABLE); " B# Q# u6 N" V1 [
  }
( l$ E) `+ J8 X5 S# V" E}9 o8 A6 g5 K" o6 P1 @2 Y2 v

" m$ Q1 a8 o; U0 C9 Y3 f
收藏 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 编辑 ( M# B, i# l( j+ ]6 G, N1 f

/ k; e  e6 L3 w3 ?: {1 W* K/ _! |所谓STM32F103串口数据的DMA发送,其本质流程如下:6 {  L3 [- J3 a3 w! @/ ?
1. 要发送的数据放在USART2_DMA_TX_Buf缓冲。
0 {) N! S( k3 B: T/ H2. STM32串口DMA发送和DSP相比的优势。2 f2 s0 |6 E4 C* w  ]. L
   启动DMA传输后,USART2_DMA_TX_Buf缓冲中的数据通过DMA1_Channel7通道,% s/ Y' r) x9 K! o: {* D: g( H
   自动传输到USART2->DR寄存器,这个工作不需要CPU干预,可以极大的节省CPU的资源。" l7 e4 x# t* H5 X' u
   和DSP的FIFO相比,这优势很大,因为DSP的FIFO只有16字节,这意味着DSP的串口通过2 s) k" c- D# y& q' m5 Q
   FIFO发送数据时,如果FIFO缓冲为空,可以迅速填入16个字节,然后去处理其它的事务。
% q7 e) C# |0 \- C4 x& s  ]' o' r+ `   而STM32的DMA发送则没有此种限制。更具体的说,如果DSP发送的数据超过16字节,
2 z* q0 `  d+ {9 N0 s   则必须等待前16个字节数据发送完毕,然后再继续发送后续的数据,需要第二次甚至. o9 \, U- {% A" U* ^2 D6 O
   第N次处理。而STM32启动一次DMA就搞定(DMA最大传输65535个数据)。! w. W% B8 n) |0 l; ?, L
3. 发送结束的一些事务处理
% R! A& V# T% g+ @: S% P   DMA传输完毕,数据全部通过DMA1_Channel7通道依次传入USART2-DR,这里开启了2 }8 |, q" E9 a0 y8 r( j
   DMA传输完毕中断,进这个中断时,USART2-DR寄存器是最后一个要发送的数据,9 v  _2 E% D+ Q6 r( Y# ~' W3 z
   此时打开USART2发送完毕中断,进入USART2发送完毕中断后,可以设定标识,
7 @/ V# E! O7 `( f   也可以操作GPIO, 进行RS485的换向动作。: U- B7 n; Y" ]! z$ c& G( }

2 Y  ~3 F5 T# D2 d最新的STM32F103的HAL库,几乎所有的通信,都可以启用DMA,HAL库函数抽象层次过高,灵活性不够,
: p8 B% O! {6 F, T4 Z但比较适合使用操作系统的场合。可以把HAL库的宏定义拷贝过来使用,以提高标准外设驱动库的效率," O6 ?! s9 d- B. f1 E
又保证标准外设驱动库的灵活性。
* }+ \( t, X9 R6 ]& d1 J
* J+ z6 Q) n" ]& C6 O, X
* V/ [9 n) I. c* t0 P0 m3 n, i. S8 a* I, i$ o
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 手机版