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

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

[复制链接]
wjandsq 发布时间:2015-6-25 14:07
STM32电机培训online,大佬带你玩电机; `3 n3 c$ l* Y" `! i8 O$ d3 |- ]
& X+ {0 R5 |% h3 k  t, B3 {$ o" K) Z
6 l4 F5 W* c2 a" M8 }
#include "stm32f10x.h"2 J" x" V) [5 j% P  R
#include "stm32f10x_usart.h"
2 F# x- ?* Q6 V6 k8 U9 y#include "stm32f10x_dma.h"  P7 D7 |! t4 D. D1 R% H( Q

  b& k. P: W. ^% F; Ruint8_t HEX_CODE[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};1 U2 {  l9 r! h$ N1 [
uint8_t USART2_DMA_TX_Buf[1024];
: {( g, j$ Y9 ?) v, wuint8_t Flag_USART2_DMA_TX_Finished = 1;
5 U9 i' t7 A; m9 o8 c2 Fuint8_t Flag_USART2_Send = 0;
2 |, R' q  h5 [7 |' P. F4 i
0 o' q5 g0 P* ~* u/ ^) v/**+ P! C3 ]3 ^% y( D
  * Function Name  : USART2_Config
$ l  Q) |+ n2 b0 b+ G- o  * Description    : None
- j+ G& b4 _0 r, V' D4 j$ j0 ]5 ]  * Input          : None5 c# E; X) M) q) z$ `& P1 g2 c! X$ G
  * Output         : None
) G9 T4 I0 W9 w9 g9 A  * Return         : None
; i6 w$ H. i: |: ^9 s5 t2 k  */
7 P! Z' ~8 ?# Evoid USART2_Config(void) {# W: ~4 m! Y8 d9 O8 q  Y, G, s: J
  GPIO_InitTypeDef GPIO_InitStructure;
, L  u( E( e0 n+ k+ l$ C9 w1 j3 B  USART_InitTypeDef USART_InitStructure;- }4 D* j- F- X
  DMA_InitTypeDef DMA_InitStructure;
! r; ~' v, S9 e/ |2 q* U9 x# l  NVIC_InitTypeDef NVIC_InitStructure;
. R8 i8 ^  T; H; v2 I+ S: ~
$ b7 {9 ?8 G, A9 M: Z; }  /* config USART2 clock */1 S# h% ]/ |. ~" U/ ~
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);# }; w1 S. ~" {  u! m
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);# v; `0 l* X3 P% }7 F

: p: C  C2 O& C$ t! s  /* *********************USART2 GPIO config **********************/$ Q/ {/ p8 m+ b9 u% Z4 \( v
  /* Configure USART1 Tx (PA.02) as alternate function push-pull */
$ {* C  F7 J& K* p+ X  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; ' D# N4 w* |# S) {
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
0 U) \5 R: _9 z9 F" ?+ [  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;; Z* B1 F0 d; E$ Y( Y5 p5 M: x
  GPIO_Init(GPIOA, &GPIO_InitStructure);   
9 D1 d# r: n5 y1 D; `0 h  /* Configure USART2 Rx (PA.03) as input floating */7 p, Z0 {+ E& w3 M9 s* u
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;& }  u" p- C% i3 [5 A* E: I) z
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  a. Y8 j7 H  U/ m# o+ i
  GPIO_Init(GPIOA, &GPIO_InitStructure);
1 \& n4 j2 Q+ F! u
/ v/ e2 M3 _# g8 L2 |  /* USART2 mode config 115200 8-N-1*/8 H! y8 D* f: a; C* `+ p) ]
  USART_InitStructure.USART_BaudRate = 115200;% `( N8 Y4 `! s
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;  Q% [+ s, g! p) D
  USART_InitStructure.USART_StopBits = USART_StopBits_1;* b& r* X. v  f, e7 l; i; T
  USART_InitStructure.USART_Parity = USART_Parity_No ;
6 Q" b, Q" ~2 f4 W5 e& i  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
; i7 f( L" b7 a' Y5 _. x  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
, \! R- |' g1 k, w  E  USART_Init(USART2, &USART_InitStructure);
. w. P% L* j* y  USART_Cmd(USART2, ENABLE);9 t3 A- O9 `1 s/ z" b3 E' o& g; p

% o. J: i# S* P1 V
; I& F7 o8 U8 M1 x! X. T  H# @  USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);. H9 ~0 F. A2 z2 Z6 H! n8 Q$ Q% Q# ]
  /* Enable USART2 DMA TX request */) x7 W$ u- k6 C2 M
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
+ W, G, F; [/ g+ ^% s. [, b7 }* U; v& P% K3 e+ G
  DMA_DeInit(DMA1_Channel7);
( n" }/ p( t% j" @  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&USART2->DR);6 R( L& h$ t$ z
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART2_DMA_TX_Buf;  H3 A7 N' [+ |: ~) q
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;2 V0 W, L- w  Z! u) @) {9 q
  DMA_InitStructure.DMA_BufferSize = 0;
, F" k! v+ w* W  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
% E7 d% H" M( F9 L2 @2 B  b  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
3 x" f  G& _4 M% {5 e6 D5 Y  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
7 D6 F1 n, z7 i" c1 M  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
, f. D& q6 ]/ ^2 L/ T  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;9 V3 j# U4 L* |
  DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
. \6 m- [# D3 `4 ]: S  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;' J: z& k$ |  {9 g% f* y+ d) i
  DMA_Init(DMA1_Channel7, &DMA_InitStructure);
: ~; z; r. u/ z# N: O; \) P0 q  DMA_ITConfig(DMA1_Channel7, DMA_IT_TC, ENABLE);7 O6 \$ }" H. c
( y5 t( Y/ x) W0 Y
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);# r! y3 c7 d! k' ~2 m; \, Z( h
3 w+ f8 Q7 K" w8 l" R# r( O/ _
  /* Enable USART2 DMA TX Finish Interrupt */
6 M8 a* ^! l$ n8 f, B  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel7_IRQn;! a2 }4 P* Z) H
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
+ m8 J5 |3 b0 |3 a+ X' c  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;; J3 y% [* F6 C- j* K* W$ N( A
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
8 y) Z6 F& P6 M8 v  NVIC_Init(&NVIC_InitStructure);4 [9 ^' E* @7 `3 H
' p6 b7 U2 L8 G8 b3 c
  /* Enable USART2 Interrupt */
) P8 o7 c0 @! {2 d1 p  NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;+ v. N; G( m, W  W% ~
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;) P2 e, A- y5 q( ?1 `1 H
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
6 P  u& ^+ W$ A  NVIC_Init(&NVIC_InitStructure);
& G4 p" P5 d8 ?5 |; ~}% A4 ?4 m; r. h$ I4 Z
/*** \- c1 i5 y9 J* |/ S1 F. q( |) N$ n0 D
  * Function Name  : USART2_Data_Load
) Y8 M9 i7 k& h2 m# n  * Description    : None
* g, }$ Y) p1 N) B  * Input          : None
/ p4 W/ A+ ]1 Z+ P; h! e  * Output         : None4 z" D* ~% i8 p) ~5 G1 E( x
  * Return         : None
0 V0 d! T3 a: o3 M$ X/ r- k  */6 z; q! j" ?& Q
void USART2_Data_Load(uint16_t temp1, uint16_t temp2, uint8_t temp3){- H6 \9 x& ?4 T+ i
  USART2_DMA_TX_Buf[0] = HEX_CODE[temp1 >> 4];
4 C/ E, \7 E2 w) p: B% _- Q+ X  USART2_DMA_TX_Buf[1] = HEX_CODE[temp1 & 0x0F];8 a- x3 v6 ^8 b. f' }
  USART2_DMA_TX_Buf[2] = HEX_CODE[temp2 >> 4];
* O8 a( s6 P0 l& L. u  USART2_DMA_TX_Buf[3] = HEX_CODE[temp2 & 0x0F];
! b' e/ L2 K/ H& [% o( h  USART2_DMA_TX_Buf[4] = 0x20;
$ [2 q# Y$ s! s" [2 L+ X& D  USART2_DMA_TX_Buf[5] = HEX_CODE[temp3];( _& p/ w; p( d
  USART2_DMA_TX_Buf[6] = 0x0D;
' J5 e. }$ i4 q) @8 F1 A  USART2_DMA_TX_Buf[7] = 0x0A;
" z" \0 b" t; j0 `2 `* m1 T- }  Flag_USART2_Send = 1;& G2 [9 i# j* o1 j$ p2 o( P
}1 o5 l9 f+ J) H: M6 \, ]) \. F
/**2 A0 W; J2 N% @
  * Function Name  : USART2_Data_Send; E1 d% H0 C: W. n5 n
  * Description    : None
, Q6 Y! I$ M( i; R* J1 @& o  * Input          : None: {5 z3 L) x9 t! H+ ?: n5 @
  * Output         : None
  }# I7 \, m; e6 O  * Return         : None
3 {6 {6 m0 L9 i+ a0 y7 ^* _6 u  */
, E! q& m% u; X& f' |) ~8 t3 [void USART2_Data_Send(uint16_t len) {& k; C1 x% T* B- S! J
  if(Flag_USART2_Send){
* h, m1 C- o0 `' ?( y- O0 K    if(Flag_USART2_DMA_TX_Finished == 1){
4 J4 K# F1 N; L, s      Flag_USART2_DMA_TX_Finished = 0;$ _. `# z2 s$ x2 f
      DMA1_Channel7->CMAR  = (uint32_t)&USART2_DMA_TX_Buf[0];
) @9 R9 ~9 f, Y( W2 O      DMA1_Channel7->CNDTR = 8; // len
& v8 ]# c' Q' T+ Q+ n; l      DMA_Cmd(DMA1_Channel7, ENABLE);
# U4 R  Y  w6 l0 p. C3 u+ _/ o      Flag_USART2_Send = 0;  R* S- _4 }1 M& ~" ^
    }
: w; x/ X5 x) X6 S6 a* T  }
) ?; c* ]6 ?; p9 S. C8 N: ^2 _}) X# N. j% p- ]  M& h; |
/**
7 b: D) Y) X, l. b) o9 N. v; m  * Function Name  : USART2_IRQHandler) \! B2 R0 C' c+ I
  * Description    : This function handles USART2 global interrupt request.5 k5 e  K) x7 K; X6 A
  * Input          : None0 n6 x# z& X6 m* S
  * Output         : None# h3 A/ K- z8 {0 `; e5 g& }  w
  * Return         : None
) `1 y/ G* v+ L  K% Q, n: m* `  */3 b4 m' d- S- u! `  U
void USART2_IRQHandler(void) {+ {) {' `9 b+ N" }- g+ s% _
  if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET) {! R) m3 H5 I" c
    (void)USART_ReceiveData(USART2);
% |3 Z6 ?& @2 l9 u+ i  }8 Y0 `$ O* B# u* b; G8 y4 @
  if (USART_GetITStatus(USART2, USART_IT_TC) != RESET) {
  ?, ?, V# ?7 c/ n2 K8 r    /* Disable the USART2 Transmit Complete interrupt */% b2 A- g6 C# O3 c: f, D+ M
    USART_ITConfig(USART2, USART_IT_TC, DISABLE);9 t1 ^' W+ _; z2 R& A$ c6 d( l) D5 m
    Flag_USART2_DMA_TX_Finished = 1;1 d) u; [. c/ l! R( z3 I& W
  }     3 `: X% s# q2 ~' }# }: [- B9 \; x
  /* If overrun condition occurs, clear the ORE flag a.nd recover communication */    ' a9 j* ]4 [: M* q- r! W* ^
  if(USART_GetFlagStatus(USART2,USART_FLAG_ORE) != RESET) {1 H4 b" U9 m* E" l) T
    (void)USART_ReceiveData(USART2);% Z1 K$ `# |) {0 o
  }% y+ w4 b2 g# b( R% S
}
" i- N9 d" H  w+ j' ~* m: A! p/**
) P8 [$ ^) e' F; o# O  * Function Name  : DMA1_Channel7_IRQHandler
$ \( N0 F+ p, j7 W% h5 i  * Description    : This function handles DMA1 Channel 7 interrupt request.
6 ~& u5 C( x! ?, Z8 l0 e# S4 [  * Input          : None: |( F$ F- L9 N
  * Output         : None+ {/ j3 o! L) z, T; q3 t5 L
  * Return         : None0 ~9 M0 q# p' [
  */3 D2 C; U6 T$ g( f0 ~9 P
void DMA1_Channel7_IRQHandler(void)
1 J4 u7 U. X1 D3 J9 ?{+ ]5 k1 c. e8 V1 [! S" c
  if(DMA_GetITStatus(DMA1_IT_TC7)) {% @  [1 A& _+ W% V9 ]6 ^0 w* A1 c
    /* USART2 DMA 传输完成 */- Z4 C2 j, g1 ?+ u
    DMA_ClearITPendingBit(DMA1_IT_TC7);
0 [9 m/ W/ ^6 R; h, X    DMA_Cmd(DMA1_Channel7, DISABLE);
" J2 J$ @: I0 O$ A, t0 i    /* Enable USART2 Transmit complete interrupt */) R- N; |. P+ b
    USART_ITConfig(USART2, USART_IT_TC, ENABLE);
1 S7 i, j# Q9 l) i! @* v3 o# ^% K  }* J9 |* u5 R' C; t5 R0 R
}
! m8 ?! ?: k  }) n1 d) v3 ^- D& \9 T* 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 编辑 4 e% E. o% H* f' S* ~6 G

, d+ A/ \. x. N所谓STM32F103串口数据的DMA发送,其本质流程如下:
' I$ |. |( e% O* G# l" R1. 要发送的数据放在USART2_DMA_TX_Buf缓冲。
; N. c) b+ u0 _* w2. STM32串口DMA发送和DSP相比的优势。
3 M6 ~7 ]6 v" s7 ^  G9 R: V   启动DMA传输后,USART2_DMA_TX_Buf缓冲中的数据通过DMA1_Channel7通道,
2 m) C* d- e- @# P4 E" D5 {   自动传输到USART2->DR寄存器,这个工作不需要CPU干预,可以极大的节省CPU的资源。8 R0 t* C4 q9 M$ t  V! A; A
   和DSP的FIFO相比,这优势很大,因为DSP的FIFO只有16字节,这意味着DSP的串口通过# d, a* I4 o9 j( x7 P; o' l
   FIFO发送数据时,如果FIFO缓冲为空,可以迅速填入16个字节,然后去处理其它的事务。
+ z. }) J9 T4 ?% u1 o- H" b5 e   而STM32的DMA发送则没有此种限制。更具体的说,如果DSP发送的数据超过16字节,
. b+ v2 {, S( R& d# q   则必须等待前16个字节数据发送完毕,然后再继续发送后续的数据,需要第二次甚至
1 L6 w" V$ r  a+ ^   第N次处理。而STM32启动一次DMA就搞定(DMA最大传输65535个数据)。
& d$ k) g$ k% ]) P& X3. 发送结束的一些事务处理; f( p- x# k8 n
   DMA传输完毕,数据全部通过DMA1_Channel7通道依次传入USART2-DR,这里开启了
- i, }% b  S( G' W6 V; E0 G, i   DMA传输完毕中断,进这个中断时,USART2-DR寄存器是最后一个要发送的数据,
; d; C. B7 g2 h& e9 i& f8 M   此时打开USART2发送完毕中断,进入USART2发送完毕中断后,可以设定标识,9 d& k: x$ l5 s
   也可以操作GPIO, 进行RS485的换向动作。
) ~  R% q& o+ |7 f5 p4 j( M' N8 ^0 N; U5 D: x* {8 `7 `
最新的STM32F103的HAL库,几乎所有的通信,都可以启用DMA,HAL库函数抽象层次过高,灵活性不够,
  Q' [# _/ z- f但比较适合使用操作系统的场合。可以把HAL库的宏定义拷贝过来使用,以提高标准外设驱动库的效率,
3 V( v: {& M8 ?: F0 I5 T' A- i9 a又保证标准外设驱动库的灵活性。
/ i3 n; ~( `) ]! k$ ~" e+ O& g5 a# d' u! I) O' q4 o
  b0 D1 Q9 P% X$ b* a/ W- j
2 z8 Y$ j+ w8 K3 x8 b. 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 手机版