直接存储器存取(DMA)用于在外围设备和内存以及内存到内存。数据可以通过DMA快速移动没有任何CPU操作。这使CPU资源对其他操作保持空闲。DMA控制器有5个通道,每个通道专门用于管理内存访问请求。来自一个或多个外围设备。它有一个仲裁器来处理DMA之间的优先级请求。0 `6 ?3 l0 O- }4 r$ }7 T; D+ C
! W0 `. L& v& U/ [& m! X( C配置过程详解:* B3 [1 j# J/ p4 i4 O
7 n3 e% J0 F2 E, n
% G) g7 z6 |7 x8 P
8 z1 d" T& x u |. ?* j, h a! G, I+ v1 ]
首先调用RCC_AHBPeriphClockCmd()函数,进行DMA时钟的初始化。
8 a4 i- E5 F: C- ^' g7 I
P# m! f. d$ D, I2 g! n
i) h$ e( r2 ^* q' J5 D" E6 w
, n/ Q4 R6 ?1 ?: `' z可以看到DMA在AHB时钟上。所以我们使用以下语句打开DMA1的时钟。. t) j" b. [; i; v
$ ~% V l, P0 H" b1 L8 V0 @- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);//使能DMA1时钟
复制代码 . |3 `" H! X2 T0 p) R
接着在DMA.c中编写如下两个函数。来设置DMA从UART1到内存和内存到UART的传输通道。
5 ]/ }3 u6 @- f9 i: q) ^! O/ n% o' P- /**************************************************************************************
( n3 w# f3 b3 s( k: L* E - * FunctionName : DMA_MemoryToPeripheral()
1 [( N- J# S6 m4 Z5 ^ \ - * Description : DMA传输(内存-->外设)& k1 t7 K# o8 X, Z. K
- * EntryParameter :
3 I2 v8 @: V. b - * ReturnValue : None
3 ?1 W a' C U3 }5 B! r) M5 G - * Function : 5 \# v% R8 E$ a3 f* F
- **************************************************************************************/8 n7 m; m/ ?2 `3 H
- void DMA_MemoryToPeripheral(uint32_t MemoryAddr,uint32_t PeripheralAddr,uint16_t BufferSize)
# r3 k" p& E$ h" W/ t7 g, N; W - {
' K9 X& A4 I7 ?% \. Y - DMA_InitTypeDef DMA_InitStructure;0 I0 r- r( B+ {* k: ]7 A
-
$ E. F' P& b! ~$ j! v3 Q - DMA_DeInit(DMA1_Channel2);//复位DMA1_Channel2 N/ {$ J- ]$ G8 Z0 i4 ` a
- & ?; e$ I- N' N! X5 C
- DMA_InitStructure.DMA_PeripheralBaseAddr=PeripheralAddr;//外设地址
) X5 F% B" l$ o# e+ S - DMA_InitStructure.DMA_MemoryBaseAddr=MemoryAddr;//内存地址
H$ U) t+ |( Y* b - DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralDST;//传输方向:内存到外设4 [' i; X$ Y3 W% T) \2 C2 u
- DMA_InitStructure.DMA_BufferSize=BufferSize;//传输长度
( C6 e5 |: e! R5 `, d8 j3 q - DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;//外设累增:NO
$ r$ x2 d1 Q( P* R7 l7 c - DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;//外设累增:YES6 @% q: L+ m1 ]* n; j# `& L( p
- DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte;3 O0 H+ u! y3 A7 a
- DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_Byte;
1 g9 C& a7 J# [$ W2 u9 L - DMA_InitStructure.DMA_Mode=DMA_Mode_Normal;//循环模式:NO: U7 O1 v' ?& ~0 l# ?' [
- DMA_InitStructure.DMA_Priority=DMA_Priority_VeryHigh;8 b' P2 d/ \& C: r' e
- DMA_InitStructure.DMA_M2M=DMA_M2M_Disable;//内存-内存:NO
2 k8 D: s" N3 y) [ - DMA_Init(DMA1_Channel2,&DMA_InitStructure);4 L( p, b- H" d+ h2 S
-
2 r8 D+ l/ c; J) ?: L - DMA_Cmd(DMA1_Channel2,ENABLE);//使能DMA传输
: \( b9 _" H: N2 R4 a - % B3 t5 n) R6 ]. W2 n) Z+ D3 b. n
- }
复制代码- /************************************************************************************** & V! b4 Z) t/ z1 U6 g: {) ^) Y
- * FunctionName : DMA_PeripheralToMemory() 1 z: U& x* q1 m3 s
- * Description : DMA传输(内设-->内存)
' k- `# Q6 T3 W% o - * EntryParameter : 1 B/ M2 w% `, B, ?
- * ReturnValue : None
1 w. x" ]. s7 f - * Function :
6 k9 ^6 }! D5 a% { - **************************************************************************************/% B, c7 Z. {/ L) a
- void DMA_PeripheralToMemory(uint32_t PeripheralAddr,uint32_t MemoryAddr,uint16_t BufferSize)
6 z" O7 n: N, o1 E4 Q7 ]; w - {
# t0 g9 D/ c* ]2 j. | - DMA_InitTypeDef DMA_InitStructure;//声明结构体
/ V' p0 t1 ]3 y - ( X) t. A+ r3 L0 w! D; N: O5 V
- DMA_DeInit(DMA1_Channel3);//复位DMA1_Channel3
1 \8 _; [: S }& E% s -
* Z3 a9 b2 _: {4 D$ [( E: h! D, B3 o# F - DMA_InitStructure.DMA_PeripheralBaseAddr=PeripheralAddr;//外设地址
) G8 G7 d" o4 R8 a' @; C - DMA_InitStructure.DMA_MemoryBaseAddr=MemoryAddr;//内存地址6 u9 ]8 O7 C, K& l! Q: G: B9 Y( N
- DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC;//传输方向:内存到外设
_% `. l" X9 O* B, K! d - DMA_InitStructure.DMA_BufferSize=BufferSize;//传输长度# Z" l+ r R& J* m! G, h
- DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;//外设累增:NO
; H' |. V; w9 q/ P$ z- C9 E - DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;//外设累增:YES
3 G2 |( i" s: x - DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte; j9 N2 T" \5 D: ]7 z
- DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_Byte;
. P+ e2 R& h' v- O - DMA_InitStructure.DMA_Mode=DMA_Mode_Normal;//循环模式:NO
4 \# ]* B0 d' y0 v0 M' G - DMA_InitStructure.DMA_Priority=DMA_Priority_VeryHigh;
( H5 a; Q/ a- N; S) Q" T - DMA_InitStructure.DMA_M2M=DMA_M2M_Disable;//内存-内存:NO
& W, j! Z8 |. Z/ ?5 b3 S - DMA_Init(DMA1_Channel2,&DMA_InitStructure);2 Q8 l. ]7 J7 e0 E( a: ?
- ) J) f9 r% O% S/ i/ |
- DMA_Cmd(DMA1_Channel3,ENABLE);//使能DMA传输' r0 h* G6 e: ^4 m
- - t3 n/ I% o5 \. ?6 {. a, p
- }
复制代码 7 w+ Y, g: Q( k" A4 i9 y1 A
通过以上两个函数可以初始化两个通道,一个从内存到外设,一个从外设到内存。2 g6 K( n- u. H6 a1 L. E
. J* ~9 B# y6 e5 B$ _! @
当然在我们调用这两个通道的时候需要知道一些东西。
% \8 p0 b7 f1 H- \9 O; w5 y2 w3 W8 U, Z# U) S
1.有关通道的信息:3 r& J1 R- n( `* x8 S
) l$ D {% K, I- w0 n' t9 `4 z3 @' Q! Q/ x& m3 f; t
4 k7 r8 k5 B) v( m
|