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

基于STM32F1 SPI3 使用DMA发送和接收

[复制链接]
攻城狮Melo 发布时间:2023-5-22 19:50
关于STM32F1 的SPI 操作讲解已经很普遍了,这里分享一下STM32F1 系列 SPI3 使用DMA 发送和接收,关于SPI3 DMA发送和 接收大多数所都是在中断中 执行的,其实原理一样都需要死循环,等待数据发送完毕后在执行下一步操作。
  A+ s/ g) J% u4 `$ O6 a0 Y0 I( F. A& B  _

5 v# Q: H0 m9 F$ p% o. o. e& W) `9 u
  1. // 初始化SPI3
    ( r* s: t  d2 K4 b+ n+ c& s0 q
  2. void SPI3_Init(void)* [" R& p! N+ K) W" |
  3. {1 w7 f4 |' {% Q$ E: }
  4.         GPIO_InitTypeDef GPIO_InitStructure;6 ]& v; i4 V+ e+ F
  5.         SPI_InitTypeDef SPI_InitStructure;9 q: ?, {, L) R1 k' f; g
  6.         DMA_InitTypeDef DMA_InitStructure;
    7 [+ d$ v: N1 }( q. N& F3 |, `* e
  7.         RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);
    ! b' a; ]) d8 d$ r
  8.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE);  V1 ~2 V  i9 x. `
  9.         GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE); //禁止JTAG功能(保留SWD下载口)
    0 b/ p! B( S) L& m
  10.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE);
    . i- F+ \: B2 t8 t

  11. % F. \$ Z  G. N2 v7 f' j
  12.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;. G) C9 o% I% ]& _
  13.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;   5 \9 f9 b/ L6 Y$ }0 R" V! \
  14.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    ! L! T/ y9 B0 R0 a) S* a* j" h2 |
  15.         GPIO_Init(GPIOB, &GPIO_InitStructure);  
    + I- f7 N& K2 n8 G' P

  16. 1 p; F8 s9 l4 L% E+ D* y2 s5 E
  17.         GPIO_InitStructure.GPIO_Pin =GPIO_Pin_15; //PA15 =16 c$ W) \7 A+ d7 }$ |
  18.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    ; u( n- O4 x, _1 T+ C
  19.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;7 z5 u3 Z$ i! t: W7 `* x) {
  20.         GPIO_Init(GPIOA, &GPIO_InitStructure);. c9 W' z6 E( w6 m
  21.         PAout(15)=1;
    5 |8 C6 T- ^) Y* r3 |- w" [% L* d
  22.         SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;8 J5 K0 I7 V- H+ _, E
  23.         SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
    - t* s( l: I% T1 C. O2 `( Z* f# k, E
  24.         SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
    + ?7 I" r. F( U6 y6 [7 E
  25.         SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;                3 K: J/ F( B+ M; x
  26.         SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;4 _$ n# B5 |0 h8 c1 l
  27.         SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;& d; P% H( n; ~
  28.         SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;5 K3 V' d( G0 c: {& T6 a6 M; \5 a
  29.         SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;7 }& E% G9 P  O; m% K0 ?- i" F% H2 [
  30.         SPI_InitStructure.SPI_CRCPolynomial = 7;
    " h8 C2 c1 [5 i/ f0 m! ~. ]
  31.         SPI_Init(SPI3, &SPI_InitStructure);
    8 W" n/ g6 X! Q% {
  32.         //使能DMA发送
    8 T& a9 B+ a2 y# T8 j
  33.         DMA_DeInit(DMA2_Channel2);
    4 u: F$ p: g% G: [
  34.         DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI3->DR; 5 J7 T+ \* ]6 q4 g
  35.         DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
    " c/ v8 S+ p: q- E6 h, J+ d! t2 \# w
  36.         DMA_InitStructure.DMA_BufferSize = 1024;
    # M3 p! d7 n; J. Y, D' |5 n
  37.         DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;1 r) C* g" t5 s' d2 r% z7 r, M
  38.         DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    3 @6 d1 T& S. k0 R3 N9 V3 Y
  39.         DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    & a7 Q- ?9 E1 x
  40.         DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    : P4 p' j4 e5 m
  41.         DMA_InitStructure.DMA_Mode =   DMA_Mode_Normal;
    . _8 l- x1 z/ j; q% U! U  Z3 g
  42.         DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
    7 k$ y1 f" `4 p6 Y
  43.         DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    - m0 }$ |. \+ n, a. ~' q9 X0 f
  44.         DMA_Init(DMA2_Channel2, &DMA_InitStructure); . K+ }) U! Z2 q9 B/ J
  45.         //使能DMA接收
    ( {& p0 z' M0 N* L$ [; Q
  46.         DMA_DeInit(DMA2_Channel1);9 r  B$ }( o% f4 Z& W9 w+ B
  47.         DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI3->DR;
    2 ~, Q( Q- H, F( I! \- w$ q
  48.         DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;. }7 y3 [; T4 y
  49.         DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;8 d# y) H6 Z; r! F
  50.         DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    ! |, G& E$ Y) I! w8 o) U
  51.         DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;6 w6 u( Z1 x6 u  h  p3 O
  52.         DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;* R5 e' Q1 x, t# r9 L
  53.         DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;$ f2 i6 i1 j$ U: h; [
  54.         DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
    5 T; ^: `% G8 D
  55.         DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    ! f0 l8 E6 ?0 P. j0 D; G9 x
  56.         DMA_Init(DMA2_Channel1, &DMA_InitStructure);3 J/ ~6 i5 |# y0 B' l
  57.         SPI_I2S_DMACmd(SPI3, SPI_I2S_DMAReq_Rx, ENABLE);
    ; {! U" t3 Z  Q- h; M/ g9 F$ t! f
  58.         SPI_I2S_DMACmd(SPI3,SPI_I2S_DMAReq_Tx,ENABLE);
    + r& _( T: H- V" |; \) t1 G
  59.         SPI_Cmd(SPI3, ENABLE);
    3 K9 E, G5 {. A8 t9 j8 ^) Y
  60. }
    , L7 {% h6 n4 [4 `( f: J2 P
  61. // 速度设置! W; [; }& X. C6 J/ j
  62. void SPI3_SetSpeed(u8 SpeedSet)
    . ?+ D; g2 B( V1 I7 Y6 q& n
  63. {! T; z. d, T, z# M4 ?7 `2 ]; M
  64.         SPI3->CR1&=0XFFC7;
    % y: N* z$ n8 [+ G" }
  65.         SPI3->CR1|=SpeedSet;) g( ?4 w! y. t% P3 b
  66.         SPI_Cmd(SPI3,ENABLE);
    * b) v0 r4 `. p+ q$ @
  67. }   p& N& W2 ?0 w3 a4 O
  68. // CPU发送9 H7 F  g6 b# e. |
  69. uint8_t SPI3_ReadWriteByte(u8 TxData)
    9 b0 O* Y, c5 A6 e$ m( g( T
  70. {                ! V  u" m$ e( \0 t2 F4 i
  71.         while((SPI3->SR&1<<1)==0){;        }
    7 ?& \. i* h4 a: @9 c/ L2 I* y0 H* \
  72.         SPI3->DR=TxData;                                    
    ; P1 e* Y: B& L% h  J2 r% t3 I5 z9 u
  73.         while((SPI3->SR&1<<0)==0){;        }         : C7 r/ z" o  [4 g+ M4 N9 P
  74.         while(SPI3->SR&(1<<7)){;}
    6 t. X. _0 n2 s3 |- b" G1 A
  75.         return SPI3->DR;
    $ H7 B, P; a! r6 M+ N6 `( x2 ?
  76. }
    1 r& h/ l* S6 J6 |- v; e0 R
  77. // SPI3 DMA发送1 ~6 A2 v3 K# H5 ~) c( c
  78. void DMA_SPI3_TX(uint8_t *buffer,uint16_t len)
    ) T  w3 x, O) _0 u
  79. {$ a7 F/ A. @' Z2 t5 G1 }! P
  80.         DMA2->IFCR |=(0xf<<4);
    / S1 n0 N5 ~: h" S: o  V7 \# Q* z1 h
  81.         DMA2_Channel2->CNDTR=len; //设置要传输的数据长度
    - }3 k  w; _) k0 u' m
  82.         DMA2_Channel2->CMAR=(u32)buffer; //设置RAM缓冲区地址. P7 v6 }* _1 l5 |$ v" y
  83.         DMA2_Channel2->CCR|=0x1;% z* n, c+ _+ Y. a1 [
  84.         while(!(DMA2->ISR&(1<<5))){;}3 m% i! j( @9 M9 {
  85.         while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) == RESET){;}
    , X9 y: \+ v+ D. u( u
  86.         DMA2_Channel2->CCR &=(uint32_t)~0x1;
    ! D- E  Q$ ]1 ^" m. a2 p; p
  87. }
    ; T5 @+ u0 _2 Q# F+ e% P
  88. // SPI3 DMA 接收
    % l  ^8 d, C8 H. b2 F6 }
  89. void DMA_SPI3_RX(uint8_t *buffer,uint16_t len)
    % A* }$ W  c0 o& C. T" L! D: d9 G
  90. {6 S- w3 v9 ~9 \/ Q9 _* C: B7 c
  91.         SPI3->CR1|=SPI_Direction_2Lines_RxOnly;1 t" ~2 a; l+ v/ C) T
  92.         buffer[0] = SPI3->DR;// 读取一次数据' X% ~% N$ F/ J3 u4 N$ U  M
  93.         DMA2->IFCR |=(0xf<<0);% \! Z- C4 W, C) {. a9 Z
  94.         DMA2_Channel1->CNDTR=len; //设置要传输的数据长度
    6 j& a& g! R  B/ B. v1 `  K8 v- ~5 j5 g
  95.         DMA2_Channel1->CMAR=(u32)buffer; //设置RAM缓冲区地址
    6 @: T, [* q" c/ u, W( T( p
  96.         DMA2_Channel1->CCR|=0x1;( R  O# j) P4 x2 O
  97.         while(!(DMA2->ISR&(1<<1))){;}
    * X+ |1 K0 Y. x, V: X$ K  N
  98.         DMA2_Channel1->CCR &=(uint32_t)~0x1;
    ' n/ D- n' q1 n
  99.         SPI3->CR1&=~SPI_Direction_2Lines_RxOnly;! f: c' w2 O; `
  100. }
复制代码
; {3 h# p. \3 j0 ^' n
转载自:kensey  A/ I6 f  O. \; l
如有侵权请联系删除
6 x: t3 G3 e, ?6 z8 y- A2 e, |, j1 z3 K
1 E  H, V/ N8 C6 Q# {1 {1 l) |$ e: V) h
0 x9 l8 y# r! F1 D; o
赞 收藏 评论0 发布时间:2023-5-22 19:50

举报

0个回答

所属标签

相似技术帖

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版