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

【经验分享】STM32学习之SPI

[复制链接]
STMCU小助手 发布时间:2022-2-1 18:00
一、SPI简介
  SPI(Serial Peripheral Interface )是串行外围接口设备,是一种高速的,全双工,同步的通信总线,并且在芯片上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便,正是处于这种简单易用的特性,现在越来越多的芯片集成了这种协议。
  SPI 是一个环形总线结构,由 ss(cs)、 sck、 sdi、 sdo 构成,其时序其实很简单,主要是在 sck 的控制下,两个双向移位寄存器进行数据交换。
* i5 L5 b+ H) V3 e$ p3 O& M
# y$ R# @( M  L1 }7 \! L
1476996-20190812102446929-859969798.png
& K4 U# P, F: _0 w$ I5 j
因为是全双工同步通信,所以在传输数据时,左边主机的数据从移位寄存器进入MOSI线上进入右边的从机,并存入最低位,同时从机的最高位通过MISO传输到主机的最低位,当第二位数据进行发送时,最低位的数据会向左移一位并将新数据存入最低位。
二、通信协议
1、物理层
 motorola公司  首先提出的全双工三线同步串行外围接口,采用主从模式( Master Slave)架构;支持多 slave 模式应用,一般仅支持单Master(单主机模式)。
 管脚
  三线SPI:SCLK(时钟线),MISO(主机接收从机发送),MOSI(主机发送从机接收)
  四线SPI:CS(片选线),SCLK,MISO,MOSI
  片选:被选,确定该设备处于何种工作模式
   连接方式
  1476996-20190812103946425-2031876581.png  
& F* m0 Z+ @5 ^) m3 o1 E4 B
2、数据链路层6 J( q7 ^/ G+ z6 M+ |- H
 SPI采用位协议,------高位在前,低位在后
 SPI有四种工作模式,SPI0 SPI1 SPI2 SPI3
           SPI 模块为了和外设进行数据交换,根据外设工作要求,其输出串行同步时钟极性和相位可以进行配置,时钟极性(CPOL)对传输协
议没有重大的影响。如果 CPOL=0,串行同步时钟的空闲状态为低电平;如果 CPOL=1,串行同步时钟的空闲状态为高电平。时钟相位(CPHA)% e* V& @/ V+ Z$ v# e+ y
能够配置用于选择两种不同的传输协议之一进行数据传输。如果 CPHA=0,在串行同步时钟的第一个跳变沿(上升或下降)数据被采样;如
& U0 P; x. P1 d! w5 P5 N* k3 F果 CPHA=1,在串行同步时钟的第二个跳变沿(上升或下降)数据被采样。 SPI 主模块和与之通信的外设音时钟相位和极性应该一致。; K; J0 [8 X. X9 [! [
SPI 时序图详解---SPI 接口在模式 0 下输出第一位数据的时刻$ P( i# \% l* |$ M+ M8 W9 R3 a' r
   1476996-20190812104142912-47058004.png   
三、STM32中SPI控制器
数量:2个  SPI1  SPI2
特性:全双工同步通信
            8/16是传输帧选择
            主从结构
            8个主模式波特率预分频系数
            主模式和从模式下均可以由软件或硬件进行NSS管理
            可编程的时钟极性和相位
             可编程的数据顺序, MSB在前或LSB在前
四、配置工作模式
1、NSS管理
      SPI可以工作为主机模式和从机模式,可以通过软件模式和硬件模式进行管理。
  SPI的NSS引脚分为内部引脚和外部引脚,当内部引脚检测到高电平的时候,设备会工作在主机模式,检测到低电平,工作在从机模式。
 先说软件模式,软件模式可以通过SPI_CR1寄存器的SSM为进行设置,当SSM位为1时,SPI的模式管理为软件管理模式,且当SSI位为1时(SSI位仅在SSM位为1时有效),内部的NSS会被驱动为高电平,该设备就设置为主机模式且外部NSS引脚会输出一个低电平信号,当其他的设备检测到低电平信号时,会自动进入从机模式。

3 o7 t( d2 L5 s* j& u6 \5 H
1476996-20190812111816419-1926161631.png

& j1 N9 F, E7 t  b3 F7 o
1476996-20190812111842139-85469141.png
2 E- ]( q2 ?( Z! Q( T& j: Y3 J
1476996-20190812111927107-2097536754.png
2 @2 f6 T" V5 |( U4 S
硬件模式:
   1476996-20190812112323385-509397557.png

& G3 m& @; J" {
       NSS输出使能通过CR2的SSOE位进行控制,一旦该位被使能,NSS引脚作为一个输出引脚,若SPI工作为主机模式,NSS会输出一个低电平,当其他设备的NSS引脚接到主设备的引脚,会检测到一个低电平,并会自动进入从设备状态。当配置为主模式,NSS配置为输入引脚,(MSTR=1,SSOE=0)时,如果NSS被拉低,则配置为主模式水白,会自动进入从工作模式。
       若向通过硬件管理工作模式,只需将需要配置为主模式的NSS引脚接高电平,从模式的NSS接低电平即可。
% @% e, w' c5 R) v& |5 _* B
五、SPI配置过程
1、查看原理图确定引脚,以及各个引脚的工作模式: ~  ^- K( C$ C- e  t* W) q+ E
8 e9 G$ r7 W( @1 T5 o1 }, P
1476996-20190814204736605-344149557.png
7 C. G4 K2 r9 n: ?
这里spi的四个引脚分别对应pa4,pa5,pa6,pa7,SPI作为主机,MOSI,cs,clk应给配置为输出模式,miso配置为输入。

# X' t9 J) Y% E  _5 i
1476996-20190814204938344-1712911787.png

1 x# q2 g5 N" x* k- m' \; B' g- `
所以为了将SPI的功能复用到IO扣上,pa5,pa7要用作复用推挽输出。(pa4为什么配置为通用推挽输出现在我还没弄明白,等明白了再改回来)
2、确定spi的时钟相位以及时钟极性等工作模式
因为时钟相位和时钟极性可以配置出4种spi的模式,而spi的工作模式与数据的采集以及输出有关,所以我们这里要根据外设来确当spi的工作模式。
  1. #include "spi.h"+ `, i% d, g) o9 Z% g, \

  2. ' g" X. O* m1 x0 V) ?# c
  3. void SPI_Config(void)
    - ?8 w" G9 _2 F8 R* J: Z2 Z1 D% v) r+ W
  4. {
      @; ?9 ^( _# }  H+ o
  5.     /*
    5 W4 E' N3 n3 n; A. v
  6.         pa4        sf cs            通用推挽输出7 a: f6 b9 T/ `7 [! q: h% g
  7.         pa5        sc clk        复用推挽输出
    " y' U$ B" m  |% k: x. e* \
  8.         pa6        miso            浮空输入
    * j* Y; J: A; P9 h) c" n: N
  9.         pa7        mosi            复用推挽输出
      Y5 @! V& m4 g3 F8 c6 V0 B
  10.     */
    , C0 w3 S" F3 p% t
  11.     //GPIO4 W. y# u8 Q8 Y- Y$ l
  12.     GPIO_InitTypeDef GPIOInitStruct;+ s& W5 a. D( t) b: F! }
  13.     //SPI' C6 i2 Q' c" Z! e2 V" e; a3 h9 K
  14.     SPI_InitTypeDef SPIInitStruct;3 R. u8 x5 h+ u) I. H! |' u6 X& S
  15.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_SPI1,ENABLE);+ T9 u+ X+ K- o, q
  16.     //pa4 通用推挽输出
    7 m, L( x5 r' g+ E8 d1 Q& v
  17.     GPIOInitStruct.GPIO_Mode = GPIO_Mode_Out_PP;1 P, @4 }, w$ Q7 }; j
  18.     GPIOInitStruct.GPIO_Pin = GPIO_Pin_4;
    8 S+ \; e5 B* o, E
  19.     GPIOInitStruct.GPIO_Speed = GPIO_Speed_50MHz;: P9 k! a6 w$ j* p8 s+ z" p8 ~
  20.     GPIO_Init(GPIOA,&GPIOInitStruct);
    - _+ D1 ^+ U$ y- ]3 d
  21.     //pa5 pa7 复用推挽输出
    . A, e) P9 H# V% ~
  22.     GPIOInitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
    # |/ y* y# K5 H0 i) h
  23.     GPIOInitStruct.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;& r% h' ~+ {: N: J- ~' U$ ]0 x2 O  ?
  24.     GPIO_Init(GPIOA,&GPIOInitStruct);
    ( @- U6 ]  d$ C) X; \
  25.     //pa6 浮空输入
    2 R7 m; E1 T( _$ t# F
  26.     GPIOInitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    3 N! y+ n" j! f/ ?8 S  B7 o
  27.     GPIOInitStruct.GPIO_Pin = GPIO_Pin_6;
    5 |% W% E1 w$ N9 w3 F  R6 p
  28.     GPIO_Init(GPIOA,&GPIOInitStruct);
    " s3 a0 l$ h# a/ n
  29.    
    2 I& V6 X; G5 }- o1 [, |4 f0 ?
  30.     //SPI; P! G' s& ~9 C: F& u
  31.     SPIInitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;            //分频0 ]8 @& F3 h& m8 B/ q; P1 ?; b2 G
  32.     SPIInitStruct.SPI_CPHA = SPI_CPHA_1Edge;                                                        //时钟相位
    . h$ c  y9 I% X5 @  r
  33.     SPIInitStruct.SPI_CPOL = SPI_CPOL_Low;                                                            //时钟极性+ R$ b& a7 E# Y/ H" Z
  34.     SPIInitStruct.SPI_DataSize = SPI_DataSize_8b;                                                //数据宽度0 u/ Z" J4 ~3 k8 Q$ H5 }; o6 D
  35.     SPIInitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;            //全双工$ Z6 {8 ?' S8 G- F5 j. V
  36.     SPIInitStruct.SPI_FirstBit = SPI_FirstBit_MSB;                                            //高位在前6 Y% W5 s4 q+ R1 C* E& g) x5 Z
  37.     SPIInitStruct.SPI_Mode = SPI_Mode_Master;                                                        //主机
    ) J% x. C, x- C# M9 W: X! |) o; z
  38.     SPIInitStruct.SPI_NSS = SPI_NSS_Soft;                                                                //软件模式
    * `# f% O# _/ H/ m( N8 y
  39.     SPI_Init(SPI1,&SPIInitStruct);, k4 n/ p! o, _. Q& Q6 Q. ]4 l
  40.     //使能SPI% G/ U+ q* I; A( v/ o5 b& v5 Q) P4 \3 g
  41.     SPI_Cmd(SPI1,ENABLE);1 ]( `; W2 w* j+ `& @
  42.    
    2 w" ]( u0 z* q
  43. }
复制代码

  J7 r1 B  {: h2 L. ~: n; N
赞 收藏 评论0 发布时间:2022-2-1 18:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

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