关于STM32F1 的SPI 操作讲解已经很普遍了,这里分享一下STM32F1 系列 SPI3 使用DMA 发送和接收,关于SPI3 DMA发送和 接收大多数所都是在中断中 执行的,其实原理一样都需要死循环,等待数据发送完毕后在执行下一步操作。+ {- p u* v8 ]% {' `) f- z& a4 i
% e# }/ P/ I/ e0 N
5 I" W9 W3 x1 d4 Z9 |) @- // 初始化SPI3# R% Q% e% I! N* q: ~
- void SPI3_Init(void). V2 S, S* q5 }/ z5 F; e
- {
/ _& c$ ]( }( t# M! e) C: t7 ` - GPIO_InitTypeDef GPIO_InitStructure;
; \, A# m2 `4 J* P4 u - SPI_InitTypeDef SPI_InitStructure;; o1 r6 a0 \+ h& L% j
- DMA_InitTypeDef DMA_InitStructure;
|8 V. T* O- i: |3 {6 i - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);
' _4 h4 ^& t' h$ P0 w; R+ f - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE);
% v. T% P) h* ?5 h, K - GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE); //禁止JTAG功能(保留SWD下载口)7 ?7 x7 A8 F" @0 a" m
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE);
' O6 N, o2 X0 v7 Z! m' T -
' }$ h- P& {8 w( l5 g j% L, U - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;
0 j A, i" X' J, ]/ Q - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
5 R$ ~' d; H, z* T - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
6 R( z& U- n9 ? v2 \ - GPIO_Init(GPIOB, &GPIO_InitStructure); + J$ S( B. l( b6 X% Y6 l2 @
-
: y' n: C& S4 f- T) m - GPIO_InitStructure.GPIO_Pin =GPIO_Pin_15; //PA15 =1
& ]7 t& K$ f% P- {5 F7 {1 r - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
* t |! |3 g) h; D - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;" X, _8 K9 Z: V' B8 y6 Q; }
- GPIO_Init(GPIOA, &GPIO_InitStructure);. Q0 \0 [' v$ R0 n0 F
- PAout(15)=1; - o2 ^5 g" e/ m9 }3 z8 W+ t
- SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;2 O3 C: m* B+ j) }
- SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
' g/ r$ y i1 n6 i- ?% G* W2 p5 y- B - SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
/ Z! o t" `3 E# l! W - SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; + W4 ]9 L2 c5 K/ e
- SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;; L7 E; ` f: M c* C- c4 {
- SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
9 }# Z9 c" ?7 e$ s - SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
2 `. e/ o5 ^( O3 s, g7 d - SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
) O) f) T+ H- Q, s2 _+ E$ a, y - SPI_InitStructure.SPI_CRCPolynomial = 7;' M5 n. f w' e7 T6 U
- SPI_Init(SPI3, &SPI_InitStructure);% S* Q( @2 X8 v3 W
- //使能DMA发送
/ k/ V4 F# p) O6 m4 ~- Q - DMA_DeInit(DMA2_Channel2); & k6 i0 x1 }6 l `; [5 y! V
- DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI3->DR;
9 L6 z& g9 M# j' t - DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
" ?$ n2 y+ {% I) _) S; R# y9 p - DMA_InitStructure.DMA_BufferSize = 1024;
* \5 U9 `3 A4 J, e! _; T - DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
4 p$ |6 F4 ~1 x4 V, J5 y/ L* X8 { - DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; ' K( T5 s+ p9 | f* v" {* p
- DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
P! R& ^, e& O3 m9 O+ C: i3 Z - DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; 7 n- o$ F' }, `2 N9 R0 R1 p
- DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;) X1 X9 [+ a5 P& N& R7 i
- DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
) H$ }: [ q0 _/ } E; C$ k - DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; - x0 ~& j, x: z1 M& s7 [/ a0 {9 Y( \, m
- DMA_Init(DMA2_Channel2, &DMA_InitStructure); ! ^- k4 V% i; ]2 O: \* @
- //使能DMA接收
$ y# D8 W! _8 q N( O - DMA_DeInit(DMA2_Channel1);
# D f ~3 b4 R6 H5 n, b5 i9 @ - DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI3->DR;
. d+ g& C& c$ X6 S' C - DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;" u) H: [% K3 z- b( p6 T
- DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;, ^6 N B. D, v5 F$ g
- DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
% n. f& d! W m - DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;+ N8 d9 p; W( h0 }/ t# @7 p n
- DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
" O) @" V5 A( ? z - DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;- n4 T: b' l4 V% z3 m% w
- DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;$ a7 s! f: [7 `6 g' {
- DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;6 A+ ]+ }' w/ z3 i4 \
- DMA_Init(DMA2_Channel1, &DMA_InitStructure);& m! c& E' X) S% {
- SPI_I2S_DMACmd(SPI3, SPI_I2S_DMAReq_Rx, ENABLE);9 J% F z5 n; c& K3 D8 U& x
- SPI_I2S_DMACmd(SPI3,SPI_I2S_DMAReq_Tx,ENABLE);
. s5 [7 d1 `. a - SPI_Cmd(SPI3, ENABLE);! P4 s, H s v7 g9 M4 N4 Y
- }; E7 X: Q( |2 P9 E0 |
- // 速度设置
# N" g" W( m: l5 V - void SPI3_SetSpeed(u8 SpeedSet)
. X7 c' E& ]) P1 X/ i: Q) q) g - {& w4 _$ y0 ^- V
- SPI3->CR1&=0XFFC7;
+ W4 `* k0 I$ k3 A0 K# a# E& O - SPI3->CR1|=SpeedSet;3 g- g5 v7 p- J, o* D
- SPI_Cmd(SPI3,ENABLE); : x; o# @5 R7 a; Y
- } 4 n2 f" l$ d' A
- // CPU发送7 m0 _+ d+ i9 \
- uint8_t SPI3_ReadWriteByte(u8 TxData)' w0 B0 y: U/ X) e
- {
; H+ b S8 c, j# z( ]' t5 t - while((SPI3->SR&1<<1)==0){; }
5 Y! d* H4 D* y - SPI3->DR=TxData; 5 C4 W/ K) O" `( m
- while((SPI3->SR&1<<0)==0){; }
, V% H$ {& U% s* y# F - while(SPI3->SR&(1<<7)){;}# W0 [" h& _* f' X9 l0 I
- return SPI3->DR;
5 {! k O9 C R$ ~ - }4 U& k8 n; u) W0 x! t
- // SPI3 DMA发送
- i! W) b% V6 g; A$ M( Z - void DMA_SPI3_TX(uint8_t *buffer,uint16_t len)7 t2 }& S7 p; a* [# o( d. o
- {
- D9 ~# s% E0 W) f, Q' y - DMA2->IFCR |=(0xf<<4);4 q/ @3 u" a6 }' V* y; v! b
- DMA2_Channel2->CNDTR=len; //设置要传输的数据长度
6 z* X: p4 Y- V. `0 t8 N - DMA2_Channel2->CMAR=(u32)buffer; //设置RAM缓冲区地址8 I2 @7 `' ^8 Y3 j; L
- DMA2_Channel2->CCR|=0x1;1 s5 p: h$ h% J. C) s3 @
- while(!(DMA2->ISR&(1<<5))){;}
0 `$ l7 T0 {8 K* ` - while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) == RESET){;}
) R1 t4 Y' Z/ k- @: D: s @- S6 x - DMA2_Channel2->CCR &=(uint32_t)~0x1;4 ~# v2 F/ h' N5 x7 ], ~
- }$ T) n) N- C4 n& j4 f2 g
- // SPI3 DMA 接收
- R0 G0 a( B* k( N - void DMA_SPI3_RX(uint8_t *buffer,uint16_t len): N) |( u" E! q' c4 j7 ~$ `
- {
0 [+ d- A+ ^1 r' p) Z9 b- s) G - SPI3->CR1|=SPI_Direction_2Lines_RxOnly;; S. V& Z" @% S4 k1 J
- buffer[0] = SPI3->DR;// 读取一次数据6 w- U0 \& z2 F0 @3 E8 [8 z
- DMA2->IFCR |=(0xf<<0);
8 q5 y, M8 s% G. r& b - DMA2_Channel1->CNDTR=len; //设置要传输的数据长度
% b) i7 B& e5 R% l( _) Y. k: { - DMA2_Channel1->CMAR=(u32)buffer; //设置RAM缓冲区地址: B6 K( y% r5 a7 U. C
- DMA2_Channel1->CCR|=0x1;. Q9 ]+ S# S, B( ~% e! F4 t% K
- while(!(DMA2->ISR&(1<<1))){;}
. S# N/ w0 }9 u' K - DMA2_Channel1->CCR &=(uint32_t)~0x1; Q, f: B& c& }6 @9 @
- SPI3->CR1&=~SPI_Direction_2Lines_RxOnly;
' F' F# P4 L0 c' W - }
复制代码
9 e8 j( l- j" W8 I. J7 O转载自:kensey
+ g( ^" \% D! S; C( U如有侵权请联系删除+ m4 h* I& l8 F2 z
B' q- P5 E `* h' p
6 Z2 q& F M0 X* x9 N) M# B$ C) b
$ F) L$ ]: x- y8 a |