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

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

[复制链接]
wjandsq 发布时间:2015-6-25 14:07
STM32电机培训online,大佬带你玩电机
& W& P- Y  y0 e, N9 \
4 w( j1 {1 c6 G- x
+ q6 A. ?. V2 E- ]3 }( `#include "stm32f10x.h"
! F& b5 }: c$ i8 D8 s#include "stm32f10x_usart.h"
) u, b# P. r" }6 e#include "stm32f10x_dma.h"5 z0 ^! s( L1 o7 f6 \9 K) m5 ?9 j

/ o! ]; b% `/ q! Y8 [$ u) `) p7 i3 puint8_t HEX_CODE[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
5 G) z+ o3 L4 Z- [uint8_t USART2_DMA_TX_Buf[1024];1 w4 _0 |- _, u6 [% O3 ?4 S* a
uint8_t Flag_USART2_DMA_TX_Finished = 1;. N1 |( A) s: O6 H
uint8_t Flag_USART2_Send = 0;
+ l; a0 \% S8 J) {
5 R3 _; x' O% t0 l- s# s$ X/**& S) r% q" q- R) O9 {
  * Function Name  : USART2_Config
& h- B0 _7 D7 w* ^' j$ o  * Description    : None
7 f- b8 T+ n  e/ H  * Input          : None4 f) W' N( [; c, T# h/ a
  * Output         : None
5 o0 m4 O$ R/ c  * Return         : None, m% _5 R9 I8 D' n' D. F
  */
6 Z8 }8 }6 g" ^5 R6 y; g# svoid USART2_Config(void) {
3 E9 u) o0 E% B' m  t  GPIO_InitTypeDef GPIO_InitStructure;
+ W2 z2 i/ d+ r9 [( H  Z( @  USART_InitTypeDef USART_InitStructure;
: Q1 s* D" M5 b- N4 f  V# o1 |1 ~7 x  DMA_InitTypeDef DMA_InitStructure;, L4 P! S9 B) a) m! {' B6 @$ j
  NVIC_InitTypeDef NVIC_InitStructure; & J$ x! k1 u( b4 A

' U% i* H# Z5 w' y- M  /* config USART2 clock */
& C8 h  I/ h: I& z: ]& c8 Z  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);# ~2 a" m+ j5 I7 D* i3 D
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);& q0 R% M; |: C+ [/ T
$ ~% G' K" y5 f* ]4 x
  /* *********************USART2 GPIO config **********************/. x- T3 t/ @' l8 ~
  /* Configure USART1 Tx (PA.02) as alternate function push-pull */
6 P' n7 p) D, x6 Y  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
  n; G( p6 Y& Y4 Q  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- |7 L4 o% F/ c: J2 |- ^  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
% \+ t% J" W- O2 ^2 w) u. ]  GPIO_Init(GPIOA, &GPIO_InitStructure);    7 ]) @8 b+ v4 x6 \: B$ `
  /* Configure USART2 Rx (PA.03) as input floating */( @% ], d' f4 H/ U7 ?
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
1 A$ y1 B, J; L- j- K  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;2 W! L& m' a: d7 }
  GPIO_Init(GPIOA, &GPIO_InitStructure);
0 c, d2 i/ E, l* R/ K! L8 j6 ^. S7 t/ i4 i# A
  /* USART2 mode config 115200 8-N-1*/9 {0 [% U8 {% h
  USART_InitStructure.USART_BaudRate = 115200;
, Y. D. A6 ^) N' V  USART_InitStructure.USART_WordLength = USART_WordLength_8b;. V$ }1 y5 C; |# I( ]5 X/ }
  USART_InitStructure.USART_StopBits = USART_StopBits_1;* N# Z5 S' J9 h: a
  USART_InitStructure.USART_Parity = USART_Parity_No ;! s7 v7 v- Z' |  Y9 r6 X
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;' S1 E/ C. \" Q" p6 b
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
# n/ x* i1 `3 `- G7 b3 }  C  USART_Init(USART2, &USART_InitStructure);
0 h7 r" d, v7 L. _' {  H  USART_Cmd(USART2, ENABLE);% R; Y) `3 ?( [0 G: y- a3 ~9 u
' j" d6 Y9 u5 s. R

8 q, {- V: M( v  USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);
& q4 j7 Z% }1 x8 ], m, y  /* Enable USART2 DMA TX request */% a0 {6 K, Z; G' ^; d
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);& E( b9 _5 Y9 q  h/ Z$ W6 @2 e

+ t! J1 y8 V4 _/ D' g  DMA_DeInit(DMA1_Channel7);
9 C  J9 t* w: [4 k" l  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&USART2->DR);
0 j& K+ \) P: U8 ^# s  f/ r. h. ~3 m! X  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART2_DMA_TX_Buf;& O6 _" ~4 A3 J* X$ V% r4 `3 D
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;3 d* y' v& M$ ~! N
  DMA_InitStructure.DMA_BufferSize = 0;
! i6 U4 f4 x7 P- u+ J3 \  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
! j6 ^; }! `4 E5 E  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
* |" ?! ^: ^  f5 N# D  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
3 [' n$ l7 Z" z" v3 n  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;+ y0 K( W" s' @1 G6 n. r8 P
  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
( T* @5 u* o  E+ b$ v$ |  DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
/ V- v6 M6 ]6 ]: f3 K) D  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;2 i/ i0 N6 [; k
  DMA_Init(DMA1_Channel7, &DMA_InitStructure);
! b& N  B) R) F  DMA_ITConfig(DMA1_Channel7, DMA_IT_TC, ENABLE);
# @- M' b8 C1 T# N( D4 Q8 n( S# A/ h( I2 P
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);1 P% C7 m. ~: {2 z: y

2 I, a1 S$ B7 e/ _$ x  /* Enable USART2 DMA TX Finish Interrupt */
6 t% g) u3 {0 K8 b  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel7_IRQn;
1 c6 y) a% q5 M. a  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;- ~: e5 }; S% p( M; o
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
3 b) [$ E' n/ D& p5 L  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;. [% n; h# t* H2 a+ h
  NVIC_Init(&NVIC_InitStructure);
  P* g+ ?$ {4 F, }  S+ I; ]2 r/ ^$ I( |# _& _% E
  /* Enable USART2 Interrupt */7 o4 q. K) e+ d% S
  NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;0 x$ a7 \" {; F  {! b+ H2 F
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
# d" K" y) q' P4 \4 h  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
7 E6 |/ V; [$ N+ |! l  NVIC_Init(&NVIC_InitStructure);& B, P: j' Y# M$ R
}; j; Z3 I' `! B9 ^% |
/**% [3 E1 q& d7 t% Q1 |# ]: Z3 R
  * Function Name  : USART2_Data_Load
! P' Q: ]% F) P8 @4 u  * Description    : None* g' k; s# |, t
  * Input          : None
( ]5 Z* f- O% a1 s: u  * Output         : None
5 \6 t& l1 r+ f' J8 T) @# d  * Return         : None
; H5 I3 A, V# w. f  */
0 d$ G0 t; A4 [# E3 [9 `$ s# Uvoid USART2_Data_Load(uint16_t temp1, uint16_t temp2, uint8_t temp3){
1 J, c5 r, f" Q* m" q, Q+ C  USART2_DMA_TX_Buf[0] = HEX_CODE[temp1 >> 4];
( a1 v9 k+ C2 x! `' z# f" i- W  USART2_DMA_TX_Buf[1] = HEX_CODE[temp1 & 0x0F];! r/ n" p" |* d2 ^" ?
  USART2_DMA_TX_Buf[2] = HEX_CODE[temp2 >> 4];
+ o3 A+ y  g3 K5 K, u' q8 O  USART2_DMA_TX_Buf[3] = HEX_CODE[temp2 & 0x0F];  y# G, R4 {* {# P. l+ y. K. o
  USART2_DMA_TX_Buf[4] = 0x20;1 u+ |% v3 }7 g: ]4 S
  USART2_DMA_TX_Buf[5] = HEX_CODE[temp3];8 B5 B5 ]' v+ H6 v# W! l  @
  USART2_DMA_TX_Buf[6] = 0x0D;7 u) M2 d4 K1 i; o2 s9 F5 D* V
  USART2_DMA_TX_Buf[7] = 0x0A;
. F: B: w9 d' {* \, q  Flag_USART2_Send = 1;' ~, p0 X" _; U3 Y1 [4 L
}
9 x' p* L! w, P& a4 Y+ ~/**- a' t9 Q& [4 k9 k/ P1 D- s2 ?) M
  * Function Name  : USART2_Data_Send! h0 U5 ]% S2 R- }
  * Description    : None& T" g. u; I- E! f3 |8 K5 O- ?) K0 F$ z% |
  * Input          : None
) u  y" f! m* R7 J, Q  * Output         : None6 z9 J; L1 m) Z$ X) O' B: b
  * Return         : None8 K7 [' P$ t9 j4 k# \8 g
  */
" [  V. A1 z* R3 w% F7 R# \void USART2_Data_Send(uint16_t len) {
4 \7 {2 T1 E. h* g# |+ K  if(Flag_USART2_Send){
8 h  Q! [- Z2 l    if(Flag_USART2_DMA_TX_Finished == 1){) K% |1 n# D0 o( C3 |* f
      Flag_USART2_DMA_TX_Finished = 0;9 w2 @9 b5 O3 V" T+ M# {
      DMA1_Channel7->CMAR  = (uint32_t)&USART2_DMA_TX_Buf[0];* [' z3 c% E2 @
      DMA1_Channel7->CNDTR = 8; // len! f( G2 O- T2 u  b* P- z/ b
      DMA_Cmd(DMA1_Channel7, ENABLE);/ @9 E: G& V, ]7 o4 L0 K: p
      Flag_USART2_Send = 0;
# u+ d3 }3 a! W, G  q/ B9 Z3 W    }
5 m# r" `' c& w# P: p+ d  }% M& h; l. [- U/ U: T
}
8 C! \2 F, l6 |+ t. x* j/**  Y5 {$ g) h! g1 h1 v7 W
  * Function Name  : USART2_IRQHandler) A0 I5 M7 I' T! |( P4 L
  * Description    : This function handles USART2 global interrupt request.
. ^0 R/ b: p, x# e( t  * Input          : None  I3 H3 \/ k3 W7 O
  * Output         : None
) d! x5 u$ h. R- g3 M" ^  * Return         : None8 i! t( Q* b( A& t$ D" E
  */
! |3 L9 @% U7 n4 Z. I+ `$ J/ Zvoid USART2_IRQHandler(void) {' b0 y( Y* \' v. K
  if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET) {
2 O- ~/ M" Q4 i    (void)USART_ReceiveData(USART2);8 \( h6 }8 `0 t; K" a( P
  }, i: Y5 u# U! y# w
  if (USART_GetITStatus(USART2, USART_IT_TC) != RESET) {
6 f, g7 d/ W9 e    /* Disable the USART2 Transmit Complete interrupt *// i8 _$ }6 f+ _- I" Z+ b) s
    USART_ITConfig(USART2, USART_IT_TC, DISABLE);
6 D, N1 E3 s9 k  r3 C" n# F    Flag_USART2_DMA_TX_Finished = 1;8 Z! h" @- z' {& T. E
  }     
5 l1 H+ o. I* p! [; a8 n: M  /* If overrun condition occurs, clear the ORE flag a.nd recover communication */    7 o" K3 a6 S& @) S! E# z
  if(USART_GetFlagStatus(USART2,USART_FLAG_ORE) != RESET) {( |% o- W' U: u; ^" t- V3 z
    (void)USART_ReceiveData(USART2);
8 x- H: A: {4 Y' n$ x' r  }4 Q  `# V5 ]5 j5 {+ q. F6 L5 y  i  t
}
/ G1 P! @6 K& W/**' I% Z0 @4 t# z& ]. e
  * Function Name  : DMA1_Channel7_IRQHandler
  {& k* ^: g  d* l+ j" k2 ~( N% ]  * Description    : This function handles DMA1 Channel 7 interrupt request.
1 b7 s2 t1 M. L: C* r, ~  * Input          : None( I. c1 ~. p3 A& p# l: ^6 _1 W
  * Output         : None4 J2 \. a3 I1 T/ [& \/ }$ i! U0 n
  * Return         : None( n+ R! B' w: x* A
  */2 {9 ~/ Q5 I/ k, d  \$ G
void DMA1_Channel7_IRQHandler(void)) o2 W/ F9 D' U: r& C  Q
{
( Y0 L& M9 Q) C. N) }# i  if(DMA_GetITStatus(DMA1_IT_TC7)) {
2 L# ?) a' \4 j# h    /* USART2 DMA 传输完成 */
  N0 H# ^6 d+ L" b# y8 ^; c3 ^1 i    DMA_ClearITPendingBit(DMA1_IT_TC7);
, d6 y; _+ a% a% `; y, u% Y( R/ }* ~1 Z& [    DMA_Cmd(DMA1_Channel7, DISABLE);
( a! b- y' x0 D    /* Enable USART2 Transmit complete interrupt */
5 _- H! Q* l& X6 g& F    USART_ITConfig(USART2, USART_IT_TC, ENABLE); , L( v, p# Q7 w* w" f
  }9 u& U: h2 q; a: n* t7 f
}; }  R& o* C/ H  `) v
) T" _. s5 u% O  @
赞 收藏 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 编辑 0 Q$ Q( @" @# C* h' s
! m* r4 L# N$ v, H0 c
所谓STM32F103串口数据的DMA发送,其本质流程如下:
) r2 B$ k) G- Z1. 要发送的数据放在USART2_DMA_TX_Buf缓冲。
' }, t* c  ~! F) i  B, z) E0 b2. STM32串口DMA发送和DSP相比的优势。  n% t9 p5 ~* \
   启动DMA传输后,USART2_DMA_TX_Buf缓冲中的数据通过DMA1_Channel7通道,
, B* I; u: @0 G, e1 Y) `; c+ a/ Q   自动传输到USART2->DR寄存器,这个工作不需要CPU干预,可以极大的节省CPU的资源。
/ _7 r% }5 T8 U/ {- H8 p   和DSP的FIFO相比,这优势很大,因为DSP的FIFO只有16字节,这意味着DSP的串口通过
- c1 m% U3 i& b: @3 C' q6 n( h   FIFO发送数据时,如果FIFO缓冲为空,可以迅速填入16个字节,然后去处理其它的事务。
0 n6 `# @& c$ ]) A5 o   而STM32的DMA发送则没有此种限制。更具体的说,如果DSP发送的数据超过16字节,( ^. Z1 ]6 [4 c! |) e6 Z
   则必须等待前16个字节数据发送完毕,然后再继续发送后续的数据,需要第二次甚至
4 u2 \" n( O2 K4 B# Z# ?   第N次处理。而STM32启动一次DMA就搞定(DMA最大传输65535个数据)。$ b# I+ n" N2 u
3. 发送结束的一些事务处理
+ b( {* V' j5 v   DMA传输完毕,数据全部通过DMA1_Channel7通道依次传入USART2-DR,这里开启了7 l7 f3 E2 A2 R1 G  G
   DMA传输完毕中断,进这个中断时,USART2-DR寄存器是最后一个要发送的数据,
- l( L- [# {- L& s: u0 ]   此时打开USART2发送完毕中断,进入USART2发送完毕中断后,可以设定标识,: w% H. J( O. i' M) F
   也可以操作GPIO, 进行RS485的换向动作。
( A# o5 E1 [( @8 Z/ i; R$ R- L9 [5 z* ~
最新的STM32F103的HAL库,几乎所有的通信,都可以启用DMA,HAL库函数抽象层次过高,灵活性不够,
/ Z& m3 f$ Q  g% h9 w# X但比较适合使用操作系统的场合。可以把HAL库的宏定义拷贝过来使用,以提高标准外设驱动库的效率,
) r7 i5 O0 V4 O, P: _- b又保证标准外设驱动库的灵活性。) _, R( b/ b6 A$ U6 \" W: O
6 `  \% }1 Q" t: \
! G, h8 p. A2 Z' f

9 C' a9 u# F! c, m2 x
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 手机版