关于STM32F1 的SPI 操作讲解已经很普遍了,这里分享一下STM32F1 系列 SPI3 使用DMA 发送和接收,关于SPI3 DMA发送和 接收大多数所都是在中断中 执行的,其实原理一样都需要死循环,等待数据发送完毕后在执行下一步操作。0 U0 \' V, T s' O7 z) }9 j
: |6 c; w) I( n e7 T7 @- C3 i4 b1 N5 B# q
- // 初始化SPI3
% g- C3 {- q! z% M4 R - void SPI3_Init(void)
& d' L0 s; H+ q; T/ m - {% V C3 @/ x* U
- GPIO_InitTypeDef GPIO_InitStructure;
$ h; G$ ]( l7 {9 X1 q7 S, _ - SPI_InitTypeDef SPI_InitStructure;
E) O0 [/ S: C - DMA_InitTypeDef DMA_InitStructure;
) p9 @; I- U' Z2 g. V. @4 z - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);
0 w; d4 f: ]0 X" z& S0 D" k& p# E - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE);
7 F* ^" G! ]& s. X - GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE); //禁止JTAG功能(保留SWD下载口). g% ^, Y, V: P. j l. Y
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE);
& _6 I6 U! _1 ^. c; ] -
% U/ Z! F/ m+ Z; U' ]/ b v8 t - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;$ \2 v3 W2 [$ j
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
, E+ n5 l+ J9 f9 q- Q - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;: I3 Y3 f; U1 Z1 O: s7 Y) a
- GPIO_Init(GPIOB, &GPIO_InitStructure);
1 w# H! @( {0 L6 q& ] - 5 L+ C% a o5 H# Y* [
- GPIO_InitStructure.GPIO_Pin =GPIO_Pin_15; //PA15 =1* [8 D3 T6 x2 b* x* T
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
* k5 |9 ^9 y4 L* w4 I! W - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;7 q" V$ U6 w0 Q
- GPIO_Init(GPIOA, &GPIO_InitStructure);
1 Y; d9 T& j: O, \: U0 g$ s - PAout(15)=1; ' P5 m6 d+ g: ]6 S9 }
- SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;' S: }$ `, D1 Z) q H1 c/ `" b
- SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
, s9 @1 n+ R9 X% K, ?; Q - SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;) P4 z5 s, j' l$ H. g
- SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
/ h7 k' z% T* r) ^7 T - SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
$ G( v" }( m% O; P- @ - SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;0 [1 J. k6 u* n( ?
- SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
& ]. w/ R7 X( M - SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
1 k, [$ s* g6 r3 D0 ]6 b; _0 b& M9 d - SPI_InitStructure.SPI_CRCPolynomial = 7;
+ q3 g. J; b4 V. X" c; a - SPI_Init(SPI3, &SPI_InitStructure);* b4 h0 m$ n* ^2 x3 p
- //使能DMA发送, r# t: ?; s4 f$ f
- DMA_DeInit(DMA2_Channel2);
( W* G1 F6 ?& a: q% \* b; e9 H0 s* w - DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI3->DR;
+ D7 j) N% u3 m3 Y: G - DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; . Q3 o" w; `3 n4 [" K
- DMA_InitStructure.DMA_BufferSize = 1024; ! h1 }$ K9 i+ H" O# @
- DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
* l u; {2 f$ k2 ]9 {# u9 z5 O - DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
9 T, {4 h# A( F# `& p0 c - DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
% k$ I2 S. e8 f b, f - DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
" D( W! Z2 }/ t( W$ Y/ Q- K, y - DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;8 G: q6 m" Y$ ~7 e. _& ~
- DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
0 [$ t- P4 V& j! J - DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; $ W) f4 f" P' {! i5 G5 @
- DMA_Init(DMA2_Channel2, &DMA_InitStructure); $ {! Z: c: Z; i# A! c, M1 @
- //使能DMA接收7 r8 K/ ^4 ^1 g+ J
- DMA_DeInit(DMA2_Channel1);
% {7 w+ U. G( Y& m1 X. N% J" X6 |3 C - DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI3->DR;
: y( K$ U$ d4 Q. X( ? - DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;( J- F2 a4 |: l8 w2 P- [
- DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
* N/ l6 F# U+ f5 Q - DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;' E& H* }5 C! E. b; t4 G+ Z
- DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;# S1 g" c4 o2 Q# F
- DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
, W) {; x- B% o5 R9 \& n! Y) T - DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; K" r b2 g( B5 f7 _
- DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;% L( b3 B. h% g% w1 s+ B
- DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
, |4 e# J) j6 O% |3 f - DMA_Init(DMA2_Channel1, &DMA_InitStructure);7 s' R9 y0 F4 q9 \* Y
- SPI_I2S_DMACmd(SPI3, SPI_I2S_DMAReq_Rx, ENABLE);
3 N1 l$ N0 k! I/ s - SPI_I2S_DMACmd(SPI3,SPI_I2S_DMAReq_Tx,ENABLE);/ C: T, a8 p4 f4 T: ^2 g' O
- SPI_Cmd(SPI3, ENABLE);
- \) Y# q) h# w# L" `7 U - }
. |! J& W' v8 H. f+ C8 Q2 ` - // 速度设置
6 S/ |6 C: K. } - void SPI3_SetSpeed(u8 SpeedSet) y( Q: }# J" w
- {- N, F& r& `# {+ p P
- SPI3->CR1&=0XFFC7; " O, ?$ z! e% v' m/ R E
- SPI3->CR1|=SpeedSet;; ]! w6 A* g" J) K1 p
- SPI_Cmd(SPI3,ENABLE); & V5 I* `9 ?4 s. H6 E9 ?
- }
M. @( f0 n! e5 ?+ l9 a( `& B! i - // CPU发送8 w! O. M' t" F+ N$ c2 Q! }
- uint8_t SPI3_ReadWriteByte(u8 TxData)$ ~' a# v$ b7 d+ w# q9 x0 K
- {
9 H$ _* }6 D& ^8 K6 n; a/ S" P N7 K - while((SPI3->SR&1<<1)==0){; }: b3 A3 G* p0 N/ U
- SPI3->DR=TxData;
. C1 n, z* j' x6 |+ u4 |+ r - while((SPI3->SR&1<<0)==0){; }
" [. l: J0 S2 [: e5 k! ?& j - while(SPI3->SR&(1<<7)){;}
5 S8 `; d' s! y7 ?" ~% G - return SPI3->DR;
4 \! x9 B9 G r- J3 g3 b* P - }& C/ `; E4 l5 J) m9 Y" j' M
- // SPI3 DMA发送$ r R u# k6 s) Z, C" W
- void DMA_SPI3_TX(uint8_t *buffer,uint16_t len)5 _& s7 R1 J; c1 C
- {
& C0 Y [9 e5 z! y: M7 \ - DMA2->IFCR |=(0xf<<4);
7 S2 C- q5 s2 x) Z8 i; X - DMA2_Channel2->CNDTR=len; //设置要传输的数据长度
! ~- |7 B, N8 Z. e - DMA2_Channel2->CMAR=(u32)buffer; //设置RAM缓冲区地址
! F' y) f% ` E2 h! |# Z - DMA2_Channel2->CCR|=0x1;" Y' m' ?% E3 r0 j6 A7 p
- while(!(DMA2->ISR&(1<<5))){;}
6 E" s2 k# @% z4 ?8 z - while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) == RESET){;}! i- Q: |9 d) b; n+ A
- DMA2_Channel2->CCR &=(uint32_t)~0x1;
( I+ W7 C/ v8 e5 q - }+ x6 b: b+ ^4 i* ^" c
- // SPI3 DMA 接收
% F4 e- V w- a* V; k - void DMA_SPI3_RX(uint8_t *buffer,uint16_t len)
8 D- Q/ G7 q- T7 [ - {$ g4 y% z4 ^* z8 a# u/ y1 n
- SPI3->CR1|=SPI_Direction_2Lines_RxOnly;
6 C$ I. k' l; k1 q3 q+ W& f# Z; l9 N - buffer[0] = SPI3->DR;// 读取一次数据
0 M9 a5 I# T: N - DMA2->IFCR |=(0xf<<0);
4 M% p I/ k: @& z - DMA2_Channel1->CNDTR=len; //设置要传输的数据长度, d4 ^. G" a& c- `) B$ O& Z
- DMA2_Channel1->CMAR=(u32)buffer; //设置RAM缓冲区地址 [# E) C" L5 V+ [- p8 j# y- ?
- DMA2_Channel1->CCR|=0x1;
, a# S0 n/ b$ M7 q: a - while(!(DMA2->ISR&(1<<1))){;}' r7 b; z/ {3 Q- m3 {( m
- DMA2_Channel1->CCR &=(uint32_t)~0x1;0 u5 @& u" ~! v. N2 J
- SPI3->CR1&=~SPI_Direction_2Lines_RxOnly;& S, K' b3 n# O- ~) _8 i
- }
复制代码 [ V7 k0 }4 U9 b! b9 x
转载自:kensey
- ]4 M, U8 d/ H2 U; D如有侵权请联系删除
5 o; t; J7 l$ i' @" F7 `1 D) K- m3 ?, t0 I, ~
1 x n6 S; a. ^; S
, a. o5 W& K$ i' w1 f8 K- u |