关于STM32中SPI硬件的NSS配置
NSS:从器件选择,即可作输入也可作输出。主机(master)利用此引脚选择需要通信的从机(slave)。感觉这个概念较复杂,本人阅读了一些文章后写下自己的见解,如有不对请指出。另外,本文默认片选低电平使能,我不太清楚有没有高电平使能的设备。。。。。。
首先让我们看看NSS的结构图,其中最重要的是左侧标红的NSS引脚和右侧标红的内部NSS。对于主机,其内部NSS需要被设置为高电平;对于需要通信的从机,其内部NSS应为低电平。

0. 英文缩写
SSM:软件从设备管理 (Software slave management)
SSI:内部从设备选择 (Internal slave select)
SSOE:SS输出使能 (SS output enable)
MSTR:主设备选择 (Master selection)
1. 主机寄存器配置
1.1 软件从设备管理(SPI_CR1寄存器的SSM置1)
1.1.1 NSS输入
根据官方文档,当SSM被置1时,NSS input 的电平由 SSI bit 的值决定(官方文档翻译的不准确,困扰我很久),这个很好理解,就是那个数据选择器选择来自SSI bit的输入。那么SSI bit该怎么设置呢?我在查看了官方库函数发现:
将STM32配置为主机会将SSI bit置1(上面的红色数字,对应SPI_CRI寄存器的第8位),那么现在 NSS input 就被设置为了1,Internal nss 被设置为1,STM32被配置为主设备。
1.1.2 NSS输出
在配置输出前,我们需要知道一般1个主设备需要管理多个从设备,在某一时刻主机只能与一个从机通信。
(1)通过任意一个GPIO来控制(SSM = 1, SSOE = 0)
假如我们有10个设备,那么我们可以将这10个设备的片选(chip slect)引脚与STM32的10个引脚相连,我们如果想要和某个设备通信,只需将这个设备的CS拉低,其他设备的CS保持高电平就可以了。
如果采用GPIO控制片选的话,NSS引脚就自由了,它也可以当作普通GPIO用了。
(2)通过SPI的NSS引脚控制(SSM = 1, SSOE = 1)
此模式不存在,因为软件从设备管理(SSM为1)时无法控制NSS引脚的输出(看图中的那行英文字)。所以对于软件从设备管理,主机想要选择从机只能通过GPIO。另外,手动将需要通信的从机的片选拉低也行,但不推荐。
1.2 硬件从设备管理(SPI_CR1寄存器的SSM置0)
1.2.1 NSS输入
当SSM被置0时,NSS input 的电平由NSS引脚决定。前面我们讨论过,对于主机,其内部NSS需要被设置为高电平。那么这个输入就一定为高电平,例如将NSS引脚通过上拉电阻连接VCC。
1.2.2 NSS输出
(1)允许NSS输出(SSM = 0, SSOE = 1)
此配置仅在设备以主模式运行时使用。当主机启动通信时,NSS引脚被驱动为低电平,并且在SPI被禁用之前一直处于低电平。
作为硬件从设备管理的主机,要求NSS引脚为高电平;当开始通信后,NSS又被拉低。这里我不太懂,请大家帮我看看。
(2)禁止NSS输出(SSM = 0, SSOE = 0)
此配置允许在主模式下运行的设备具有多主功能。此时应采用GPIO控制从机的片选。

2. 从机寄存器配置
2.1 软件从设备管理(SPI_CR1寄存器的SSM置1)
此时 NSS input 的信号来自于 SSI bit(由程序设置),且 SSI bit 必须设置为0。要不然都是主机,通信个毛啊......
2.2 硬件从设备管理(SPI_CR1寄存器的SSM置0)
此时 NSS input 的信号由NSS引脚决定,从机可以受控于其他主设备。

3. 使用推荐
个人觉得选择软件从器件管理还比较简单,只需把SSM置1,并用GPIO控制片选就可以了(概念清晰,其他模式把我都绕晕了)。
最后,有时候还是得看英文文档啊,虽然看的头都大了......
