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

STM32 SPI NSS大揭秘

[复制链接]
一曲一离殇 发布时间:2017-9-14 10:04
SSM可以控制内部NSS引脚与SSI(一个寄存器,软件模式)相连,还是与NSS外部引脚(真正的STM32引脚,硬件模式)相连。真正作用的是内部NSS引脚(内部NSS引脚才真正连接到SPI通信控制器上)% Q" O' e/ |4 \  a# ]
3 l5 h, e. X8 M( a- ?1 i
SPI从模式的配置(MSTR=0)
1 ]2 E6 z3 m* m) c" @1 ?8 ^1.硬件模式:SSM=0,当外部NSS为低电平时,内部NSS也为低电平,此时可以传送数据。  f) o/ p* \1 I: Y3 Z
2.软件模式:SSM=1,并SSI=0.让内部NSS引脚为低电平,此时可以传送数据。9 T* A+ V2 X; z/ ~7 p4 P# R" ?- W! a
) I( Y6 C- \' h, \; G* [" r
相比较而言: 让stm32工作在软件从模式,还是硬件从模式,取决于主从之间的通讯协议,通讯协议中是否需要NSS控制。如果让STM32模拟一个存储器芯片W25Q16的话,则需工作在硬件模式。: \' }- L3 \. e: N
                  如果通讯协议不需要NSS控制,也能达到要求,就可以选择软件模式,可以释放出一个GPIO引脚做它用。
2 i3 r. M$ z  Z- I: V! A  k
1 ~0 K* D6 `) Y) L/ L& ?5 qSPI主模式配置(MSTR=1)5 E8 }; I1 y, [+ X' T0 t. a# t
1.硬件模式:SSM=0  
5 P1 N% u, f, w3 k' f1 \6 ]4 @   A:输入模式:SSOE=0,在外部NSS引脚为高电平,即内部NSS引脚也为高电平时,才能进行数据传输。 如果要使能从设备,还需要一个GPIO引脚。
* z7 D+ u6 d* a1 j/ Z6 J* M   B:输出模式:SSOE=1, 外部NSS引脚会输出低电平,使能从设备,进行数据传输。 不需要额外的GPIO引脚就能控制从设备。            6 G9 G0 T( J; S# K
2.软件模式:SSM=1,SSI=1,将内部NSS引脚设置为高电平。这样随时可以传输数据。当然多数情况还需要一个GPIO引脚输出低电平,来使能从设备,让从设备可以接收数据。
  _  ?( P+ B* w/ D  
& V" j+ j8 o5 K# P- e0 n% @以驱动W25Q16为例, SPI主模式配置的优劣可以想象到,硬件的输入模式,占用外部NSS引脚和GPIO引脚,一共两个引脚;0 a2 I' v0 H. s. U% k
硬件的输出模式和软件模式,都只占用一个引脚,他们的不同在于,硬件输出模式必须使用某固定的端口,而软件模式可以使用任意GPIO端口。
6 I! d& w& Z+ W( v
: U0 ^- W0 F9 F' P: N' c. I在实际中,stm32通常用作主模式,选择软件模式。 2 k& _# ?7 `$ t' t6 U

4 _  B* |( V6 j- T; @" l' H关于这个NSS我曾经为它头痛了很久,看手册,看程序,看视频,看帖子,我都没有彻底搞明白它。曾经几次想彻底解决它,但是都夭折了,只能把自己写好的笔记抛弃。还因此多虑导致气血不足,上火,由此导致牙痛,嘴唇干裂。简直痛苦不已。那时候,我真的觉得我可能永远搞不明白了。就这样算了吧。老师说,让我先做做技术,再去追求原理,后来我通过接手了一个用SPI控制ADXL345加速度传感器的任务并结合了一个SPI全双工的实例,才由此慢慢使谜团浮出水面,再通过学会调试技术,终于搞明白了。SPI真的很复杂,不过复杂而有趣。我以一个菜鸟的身份,写出我对STM32 SPI NSS的相关理解。希望大家指正。" x4 m* G  U/ C6 w2 y  }
     这个NSS到底是怎么作用呢?回答是片选。
2 t0 |" L9 `2 i$ c  z" k6 H0 C( |     主设备和从设备在进行SPI通信的时候,从设备都有个CS片选信号,低电平有效,我们通常都要用这个NSS连到从设备的CS上。但是这里只是大体让大家大体明白怎么回事,东西很多,关于这个NSS,还有很多东西呢,下面让我娓娓道来。
; ~4 k7 w" D0 ^; l     先看输入输出模式.
+ V9 {8 x( i; s! h5 D0 [3 t8 D& e7 ~0 q1 e# l
       对于每个SPI的NSS可以输入,也可以输出。所谓输入,就是NSS的电平信号给自己,所谓输出,就是将NSS的电平信号发送出去,给从机。配置为输出,还是不输出,我们可以通过SPI_CR2寄存器的SSOE位。当SSOE为1时,并且SPI处于主模式控制时,NSS就输出低电平,也就是拉低,因此当其他SPI设备的NSS引脚与它相连,必然接收到低电平,则片选成功,都成为从设备了。NSS的输出就介绍到这里
8 {* w$ z" x* ^' M     下面介绍NSS的输入。( b$ k; N' W# M& ~2 ~
     我们都知道NSS输入又分为硬件输入和软件控制输入两种模式,那么就从这两种模式入手,来揭开它的面纱吧。/ T+ {, I% m  U
     先说软件模式吧。! Q  Y4 f3 s3 m7 \' P4 @  {& }' U
     1 对于SPI主机来说,需要设置SPI_CR1寄存器的SSM为1和SSI位为1,SSM为1是为了使能软件管理。,NSS有内部和外部引脚。这时候,外部引脚留作他用(可以用来作为GPIO驱动从设备的片选信号)。内部NSS引脚电平则通过SPI_CRL寄存器的SSI位来驱动。SSI位为1是为了使NSS内电平为高电平。这时候,不免产生疑问,为什么主设备的内部NSS电平要为1呢?
9 M# L- B0 s& c1 }/ y/ E2 b2 I3 p8 U: ySTM32手册上说,要保持MSTR和SPE位为1,也就是说要保持主机模式,只有NSS接到高电平信号时,这两位才能保持置1.也就是说对于STM32的SPI,要保持为主机状态,内部输入的NSS电平必须为高。当然这里在硬件模式下也是如此。5 k. r% ?/ i$ ]2 n/ \( V/ s( e
     2 对于SPI 从机来说- s" F7 b0 O+ D. Z  m
     主机自己的内部NSS高电平解决了,那么SPI从机的NSS片选低电平也得解决啊。/ [+ Q) f; x: K/ R" d8 F
     如果从机选择STM32的一个SPI,譬如主机选为SPI1,从机选为SPI2,则要按照以下操作手册说,NSS引脚在完成字节传输之前必须连接到一个低电平信号。在软件模式下,则需要设置SPI_CR1寄存器的SSM为1(软件管理使能)和SSI位为0.果然如此。SSI必须要为0,也就是SPI2的片选为低,则片选成功。- W9 Q8 G$ c. {: P
若从机为一个其他的SPI芯片,譬如我那个ADXL345加速度传感器。那么,我们可以有两种方法  ?2 o" }! U5 \3 @  S" z
一种方法,是把芯片的CS接到GND上,另一种方法是,用一个GPIO口去输出低电平来控制CS片选成功。这个GPIO可以是任何一个GPIO口,当然我们上面提到当SPI的主机配置为软件模式,外部NSS引脚留作他用了,它就是一个GPIO了,我们也可以用它。这时候,我们可以设置它推挽输出为低电平,然后用线跟从机的CS相连,那么就可以片选从芯片了。; M1 {; P" E( \* ^2 a! S3 ?4 o7 M
再说说硬件模式。
# v2 D- G, K, x( J$ ^/ _+ ]% D对于主机,我们的NSS可以直接接到高电平,对于从机,NSS接低就可以。# l0 r8 D- p; U& P# d( b
当然我们上面提过当一个主机的SSOE为1时,主机工作在输出模式,而且NSS拉低了,我们要让从机片选,只要将CS接到主机的NSS上,CS自动拉低。9 ^3 O8 X- X8 p7 h* h  E" P( ~+ F
这便是,ST公司设计的STM32 SPI NSS的工作流程。下面用实例向大家介绍。
$ u9 z- G, ~! }1 i3 U4 ^6 {; t) a) \% E: l+ V1 Y5 ]2 R

# C! A' T' t! p
  1. /* SPI1 Config -------------------------------------------------------------*/  
    % V) S9 x. P, h. S( P# t+ k
  2.   * q7 v0 o, g) G5 c+ P- w- H
  3.   SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  
    ' D" n/ `' h$ [4 ]
  4.   % S, G7 R: V5 F
  5.   SPI_InitStructure.SPI_Mode = SPI_Mode_Master,//这里设置SPI1为主模式,设置SSI为1  $ ^! Q8 q% }3 A3 E
  6.   SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;  % l. q: \$ k& U# \' V* U; X9 n8 g; H
  7.   
    4 e* |% K  S* ^) ^5 i
  8.   SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;  
    9 q% w7 T. A3 O' u- r3 \% o
  9.   / f3 V6 p& ^6 T" H6 Y
  10.   SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;  & u- `. H5 {1 [6 K7 h3 h& U
  11.   ' v# R- ]! w1 G; F8 A: d: s
  12.   SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;//这里设置SSM为1,软件管理  * H; A' d5 G' f3 a/ r) l
  13.   SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;  
      K4 P+ x& f8 [- p5 v
  14.   " M8 t3 j+ r& B3 F
  15.   SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_LSB;  
    % ^. O% Q+ i- f3 a8 }* X$ a' q+ m! A
  16.   
    & l! T  N) N1 u3 l" f' W
  17.   SPI_InitStructure.SPI_CRCPolynomial = 7;  9 M8 l% Y0 A+ G' D3 U
  18.   1 Z1 [7 ^" P- @
  19.   SPI_Init(SPI1, &SPI_InitStructure);  # {0 F; b% [8 ^  h( D
  20.   
    0 r, z! }9 B) p4 t) Y
  21.   /* SPI2 Config -------------------------------------------------------------*/  2 A) J$ U, r% E
  22.   5 Z0 j3 t5 \/ T9 x4 B
  23.   SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;//这里设置SPI2为从模式SSI为0  5 _6 [! D; g* T( T- y: U( U
  24.   ; d; P& |+ w1 N6 K% p# n! R
  25.   //因为SPI2和SPI1用的是同一个SPI_InitStructure,所以SSM位已经为1  & o* o1 J3 b) f6 M+ f4 S6 R+ f
  26.   
    ) V' C( g! [2 I' g+ e: U
  27.   SPI_Init(SPI2, &SPI_InitStructure);
复制代码
对于SPI2的配置,和SPI1用的是同一个结构体,只需要把模式和SSI一改就行,其他的譬如软件使能,还有时序什么的都不用改。这样SPI1和SPI2就配置好了。以后就可以传输数据了。
  w7 z: O/ I. a4 b

3 M9 k) X: E9 Z! b3 T3 l7 R8 E, `1 v# ?

/ i8 I$ |( a6 Z# g8 e

评分

参与人数 1 ST金币 +10 收起 理由
MrJiu + 10 很给力!

查看全部评分

收藏 1 评论4 发布时间:2017-9-14 10:04

举报

4个回答
五哥1 回答时间:2017-9-14 11:44:45
非常好的文章,有个疑问,SPI1和SPI2的总线不一样,配置是不是也不同。
五哥1 回答时间:2017-9-14 12:30:57
楼主我还有个SPI使用上的问题  ,见链接    寄存器版本的程序如何改成HAL库的? - STM32 - 意法半导体STM32/STM8技术社区 https://www.stmcu.org.cn/module/forum/thread-611831-1-1.html寄存器版本的程序如何改成HAL库的?4 `( ?; Y1 ]( l4 c
MrJiu 回答时间:2017-9-14 14:42:38
写的不错。。。。
lunar-412568 回答时间:2020-6-16 10:34:51
多谢!我正头痛呢!只想吐槽一句,ST写器件手册的人写的不够条理清晰,看得人一头雾水。

所属标签

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