关于STM32F1 的SPI 操作讲解已经很普遍了,这里分享一下STM32F1 系列 SPI3 使用DMA 发送和接收,关于SPI3 DMA发送和 接收大多数所都是在中断中 执行的,其实原理一样都需要死循环,等待数据发送完毕后在执行下一步操作。
3 I" N' T# B p \( y, i8 a7 N/ [( C" [4 q2 K- A4 x
c3 A! L+ O" N9 x2 {/ y
- // 初始化SPI3
" u2 Q, x. C* ]$ F) {) i8 b - void SPI3_Init(void)
7 W l, o/ I) _( P+ l- }4 N" O! K - {
. T$ Q6 ^ ^# j& K8 c3 h l p7 C; k# Z0 W$ v - GPIO_InitTypeDef GPIO_InitStructure;3 s1 ?9 ]8 o; j. i: d0 t
- SPI_InitTypeDef SPI_InitStructure;
+ y p% U* E, I. i) T9 L+ X r - DMA_InitTypeDef DMA_InitStructure;
' T/ X; S$ f; z/ o% o: } - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);- q& ~5 Z+ |0 Y% ^/ l- g( S2 v
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE);7 G* k( B; s5 E; ]; I
- GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE); //禁止JTAG功能(保留SWD下载口)
3 k- L: q U3 ^; l - RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE);
' \$ e$ [% G" ?3 _ -
5 z J% c/ \5 S# E( v, o - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;$ m6 `) h( Q1 e' x1 F' G* ^* M
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
. B7 E9 m% h5 Y: u1 O - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;3 b/ N# W4 ~7 o8 U" r g
- GPIO_Init(GPIOB, &GPIO_InitStructure); 0 F; |6 a# w) x" @8 H' Z& x
- - z3 R5 N0 R, ]# f2 \5 p
- GPIO_InitStructure.GPIO_Pin =GPIO_Pin_15; //PA15 =1# J% G+ Z. I* W+ o
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
2 X+ P* u& v0 m7 Y0 n5 q% b - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;5 A/ F% O( I* ]; [! N4 T
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- S9 k% s2 k: E0 I - PAout(15)=1; - m4 q( w" ]+ Z0 v! j
- SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;+ t& Y, {5 R. ]. D# w1 m/ E
- SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
q# R# o: R6 M2 r5 x1 } - SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;" A& p, e# H" ]* l0 I
- SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; % e+ u; h; _3 q d% F6 \
- SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;! q) r) ]/ u8 G) t7 Q, f
- SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
- S7 n) A& x2 U# v - SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;8 ]7 j* z! R5 J4 c" Z7 T
- SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
) @" R% e# N) W7 W - SPI_InitStructure.SPI_CRCPolynomial = 7;
/ T. S# ?0 `/ Z% ? ?' G3 ~* R$ M - SPI_Init(SPI3, &SPI_InitStructure);3 t1 r7 T9 {+ l# F4 p4 _
- //使能DMA发送
( T2 z8 y/ c) g( c - DMA_DeInit(DMA2_Channel2); . _5 K, o7 f( v. W' v% s$ A
- DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI3->DR;
! M! o$ D- v. z( X1 ] - DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; Z7 b# O9 M7 ~1 D. c5 n
- DMA_InitStructure.DMA_BufferSize = 1024; ' r6 Q l( U7 w m/ I' m
- DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
' K4 a, V5 |8 P T( a$ a0 l3 x - DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; 7 ^0 e, b2 c3 S2 a
- DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; : W, [! ^$ `7 M0 p% T
- DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
- ~4 _& R* L# `. i! R4 K - DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;& p4 Q: L8 r8 r* v" ]5 {& o) p
- DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
4 }% h, u6 ~- x$ O: X$ G0 ] - DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
# B7 F0 t0 v4 a- ^% p) J - DMA_Init(DMA2_Channel2, &DMA_InitStructure);
2 `% M' v/ Q' L' p& ~) O3 E. M - //使能DMA接收) S% G% ?# b% G
- DMA_DeInit(DMA2_Channel1);
0 u9 z# X) R$ f% T3 _1 x% f; _ - DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI3->DR;
, Y5 J) Q9 V, X' c: E - DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
& g6 V/ }9 Z0 S; X - DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;/ `: L3 F. @$ ^/ q( W! y
- DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;) |9 v" ?% y" @' U; f" U9 E! }6 T
- DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;; T) L4 g5 l9 N- q
- DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;6 M. z5 P5 y8 s# b/ ?' t
- DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
! Y+ L3 L' _) A& d0 B; |& z - DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;% A( v: a) i" n" r
- DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;* k: G$ y1 ~* A: O, H
- DMA_Init(DMA2_Channel1, &DMA_InitStructure);% f8 F$ }$ f, v8 W
- SPI_I2S_DMACmd(SPI3, SPI_I2S_DMAReq_Rx, ENABLE);! \, l/ X: l7 C6 F2 T1 @! x
- SPI_I2S_DMACmd(SPI3,SPI_I2S_DMAReq_Tx,ENABLE);
2 W8 t/ t. H5 \9 ^3 ` - SPI_Cmd(SPI3, ENABLE);
% S: B% p' k7 G, r: ^ - }$ P: J! C" J( ?
- // 速度设置 d0 B$ v- k2 E* Z
- void SPI3_SetSpeed(u8 SpeedSet)
m3 A* w8 R% S+ U& N - {3 ~' j( I- K+ d' m/ J
- SPI3->CR1&=0XFFC7;
( x) x* D% v: G% u - SPI3->CR1|=SpeedSet;8 a5 e6 M& X& u: A+ L
- SPI_Cmd(SPI3,ENABLE); 8 R; S$ ?9 a( X6 R1 U! ?* W; J
- }
0 {. M7 h7 `) n: j - // CPU发送# [0 l6 \# @+ C/ W
- uint8_t SPI3_ReadWriteByte(u8 TxData)
% ~: C0 f! @4 R/ q+ K/ j - {
- I( e/ m# P) E - while((SPI3->SR&1<<1)==0){; }, ?: n& i/ L$ L' `4 }( H
- SPI3->DR=TxData;
( H' S0 a- g% t; p; c - while((SPI3->SR&1<<0)==0){; } ; c7 n$ j- ~, n% y T- n. X) n
- while(SPI3->SR&(1<<7)){;}
7 T" k* B" ?1 {7 H1 L3 ?6 ] - return SPI3->DR;6 T1 l- h+ W Z6 \" G a. ?+ U( h" G
- }/ q7 [- t) E3 e6 r: I
- // SPI3 DMA发送, R# F; D' o& i& l0 B, \9 E
- void DMA_SPI3_TX(uint8_t *buffer,uint16_t len)$ [; J/ T$ M c' ~7 U" o
- {
6 l5 X! C$ ]% |0 C - DMA2->IFCR |=(0xf<<4);
: O2 p* d! q3 O - DMA2_Channel2->CNDTR=len; //设置要传输的数据长度+ u: ?/ q% C/ D# j
- DMA2_Channel2->CMAR=(u32)buffer; //设置RAM缓冲区地址
$ u5 _; C* ]0 N- J: Q, R - DMA2_Channel2->CCR|=0x1;
2 T! K& O' k/ a W; s) D$ `- a - while(!(DMA2->ISR&(1<<5))){;}
: q+ p$ U$ |" j* I, D9 r - while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) == RESET){;}
! W6 |, @- y$ \: f* \; O4 T - DMA2_Channel2->CCR &=(uint32_t)~0x1;$ O( _8 v. [' b; Y
- }
$ I3 Q5 f; }: j- A* L - // SPI3 DMA 接收3 ? z% k- j0 c* N3 v' u
- void DMA_SPI3_RX(uint8_t *buffer,uint16_t len)
7 Z& A X m0 ~8 U( G - {
9 x5 L) b/ ?; O8 h7 Z - SPI3->CR1|=SPI_Direction_2Lines_RxOnly;6 h9 E4 F0 r$ c* @
- buffer[0] = SPI3->DR;// 读取一次数据
5 s k; e( R3 {, f4 Q O - DMA2->IFCR |=(0xf<<0);
5 _. i' `8 V8 ?5 B% v- ]- `8 | - DMA2_Channel1->CNDTR=len; //设置要传输的数据长度
9 ]3 o% i, R( p7 U2 @ - DMA2_Channel1->CMAR=(u32)buffer; //设置RAM缓冲区地址. G" A. a, L6 I3 t3 _$ k
- DMA2_Channel1->CCR|=0x1;
. ^% u0 C( _) w! l - while(!(DMA2->ISR&(1<<1))){;}2 o9 _+ j; k3 T5 Y" I$ W
- DMA2_Channel1->CCR &=(uint32_t)~0x1;, e P6 x( \) K3 I+ s. ^
- SPI3->CR1&=~SPI_Direction_2Lines_RxOnly;
8 t7 V; G& A/ {2 k7 ~) h" k7 M - }
复制代码 ) `1 ?% m/ r2 f2 P1 v+ d0 |) j
转载自:kensey3 D. i' E* D, |% o% h
如有侵权请联系删除
; ?* }0 `$ i& `3 h3 K L/ f! |) a% @) q' t; s+ n/ L! O& X! X
# ]: O$ s( e, n3 n8 x
; S! G0 a5 v R$ p9 } |