打印
[STM32F1]

关于stm32 spi 的NSS问题(爱智求真的伙伴们帮我!)

[复制链接]
2377|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
1、spi寄存器中SSOE具体是什么意思?
     a、英文文档里说:SS output enable. 是否这个位设置为1就表示,芯片内不的nss信号就连接到了芯片的nss引脚上了?当该位为0,是否表示,芯片内部的nss引号跟芯片的引脚断开?
     b、如果(a)成立,那要使用芯片的nss引脚用作spi引脚的nss,是否需要把引脚设置成复用功能?当芯片的引脚如果不设置成复用功能,是否是:即使SSOE设置成1,芯片引脚设置成普通io口功能时,普通io口的功能能正常使用?
    c、一般什么情况下的使用设置SSOE=1,什么情况下的使用设置SSOE=0?
2、设置主模式除了置位MSTR和SPE,也要置位NSS。英文文档是:The MSTR and SPE bits must be set (they remain set only if the NSS pin is connected to a high-level signal).  但我实际应用中,设置成主模式软件模式下,即MSTR=1,SSM=1。但SSI=0。这样spi还能正常的把数据发送给从模式的器件上。请问这是为什么?
3、主模式下的接收。文档说在SPE=1后就开始接收数据。在英文文档里的spi中的Start sequence in master mode中的两种情况中:
    情况1:BIDIMODE=0 and RXONLY=1中说,The sequence begins as soon as SPE=1。
    情况2:BIDIMODE=1 and BIDIOE=0中说,The sequence begins as soon as SPE=1 and BIDIOE=0.
但我看到在读的时候,都是先写一字节来产生时钟,然后在来读取数据。
    a、为什么是这样?是不是我哪些地方理解的不到位?
    b、如果读都要先写来产生时钟,那用DMA来读数据的时候,dma是否也会自发的先写数据来产生始终而后才获取数据?


     
沙发
gejigeji521| | 2015-12-7 22:16 | 只看该作者
关于这个NSS我曾经为它头痛了很久,看手册,看程序,看视频,看帖子,我都没有彻底搞明白它。曾经几次想彻底解决它,但是都夭折了,只能把自己写好的笔记抛弃。还因此多虑导致气血不足,上火,由此导致牙痛,嘴唇干裂。简直痛苦不已。那时候,我真的觉得我可能永远搞不明白了。就这样算了吧。老师说,让我先做做技术,再去追求原理,后来我通过接手了一个用SPI控制ADXL345加速度传感器的任务并结合了一个SPI全双工的实例,才由此慢慢使谜团浮出水面,再通过学会调试技术,终于搞明白了。SPI真的很复杂,不过复杂而有趣。我以一个菜鸟的身份,写出我对STM32 SPI NSS的相关理解。希望大家指正。
    这个NSS到底是怎么作用呢?回答是片选。
    主设备和从设备在进行SPI通信的时候,从设备都有个CS片选信号,低电平有效,我们通常都要用这个NSS连到从设备的CS上。但是这里只是大体让大家大体明白怎么回事,东西很多,关于这个NSS,还有很多东西呢,下面让我娓娓道来。
    先看输入输出模式.
    对于每个SPI的NSS可以输入,也可以输出。所谓输入,就是NSS的电平信号给自己,所谓输出,就是将NSS的电平信号发送出去,给从机。配置为输出,还是不输出,我们可以通过SPI_CR2寄存器的SSOE位。当SSOE为1时,并且SPI处于主模式控制时,NSS就输出低电平,也就是拉低,因此当其他SPI设备的NSS引脚与它相连,必然接收到低电平,则片选成功,都成为从设备了。NSS的输出就介绍到这里
     下面介绍NSS的输入。
    我们都知道NSS输入又分为硬件输入和软件控制输入两种模式,那么就从这两种模式入手,来揭开它的面纱吧。
     先说软件模式吧。
     1对于SPI主机来说,需要设置SPI_CR1寄存器的SSM为1和SSI位为1,SSM为1是为了使能软件管理。,NSS有内部和外部引脚。这时候,外部引脚留作他用(可以用来作为GPIO驱动从设备的片选信号)。内部NSS引脚电平则通过SPI_CRL寄存器的SSI位来驱动。SSI位为1是为了使NSS内电平为高电平。这时候,不免产生疑问,为什么主设备的内部NSS电平要为1呢?
STM32手册上说,要保持MSTR和SPE位为1,也就是说要保持主机模式,只有NSS接到高电平信号时,这两位才能保持置1.也就是说对于STM32的SPI,要保持为主机状态,内部输入的NSS电平必须为高。当然这里在硬件模式下也是如此。
2对于SPI从机来说
主机自己的内部NSS高电平解决了,那么SPI从机的NSS片选低电平也得解决啊。
如果从机选择STM32的一个SPI,譬如主机选为SPI1,从机选为SPI2,则要按照以下操作
手册说,NSS引脚在完成字节传输之前必须连接到一个低电平信号。在软件模式下,则需要设置SPI_CR1寄存器的SSM位为1(软件管理使能)和SSI位为0.果然如此。SSI必须要为0,也就是SPI2的片选为低,则片选成功。
若从机为一个其他的SPI芯片,譬如我那个ADXL345加速度传感器。那么,我们可以有两种方法
一种方法,是把芯片的CS接到GND上,另一种方法是,用一个GPIO口去输出低电平来控制CS片选成功。这个GPIO可以是任何一个GPIO口,当然我们上面提到当SPI的主机配置为软件模式,外部NSS引脚留作他用了,它就是一个GPIO了,我们也可以用它。这时候,我们可以设置它推挽输出为低电平,然后用线跟从机的CS相连,那么就可以片选从芯片了。
再说说硬件模式。
对于主机,我们的NSS可以直接接到高电平,对于从机,NSS接低就可以。
当然我们上面提过当一个主机的SSOE为1时,主机工作在输出模式,而且NSS拉低了,我们要让从机片选,只要将CS接到主机的NSS上,CS自动拉低。
这便是,ST公司设计的STM32 SPI NSS的工作流程。下面用实例向大家介绍。
我们介绍一个STM32上SPI1和SPI2全双工通信的程序,具体的程序,可以加QQ843538946,问我要。这里只介绍SPI配置方面的程序。
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master,//这里设置SPI1为主模式,设置SSI为1
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;//这里设置SSM为1,软件管理
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_LSB;
  SPI_InitStructure.SPI_CRCPolynomial = 7;
  SPI_Init(SPI1, &SPI_InitStructure);



  SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;//这里设置SPI2为从模式SSI为0
  //因为SPI2和SPI1用的是同一个SPI_InitStructure,所以SSM位已经为1
  SPI_Init(SPI2, &SPI_InitStructure);
对于SPI2的配置,和SPI1用的是同一个结构体,只需要把模式和SSI一改就行,其他的譬如软件使能,还有时序什么的都不用改。这样SPI1和SPI2就配置好了。以后就可以传输数据了。

使用特权

评论回复
板凳
gejigeji521| | 2015-12-7 22:18 | 只看该作者
这个NSS到底是怎么作用呢?回答是片选。

     主设备和从设备在进行SPI通信的时候,从设备都有个CS片选信号,低电平有效,我们通常都要用这个NSS连到从设备的CS上。但是这里只是大体让大家大体明白怎么回事,东西很多,关于这个NSS,还有很多东西呢,下面让我娓娓道来。

     先看输入输出模式.

     对于每个SPI的NSS可以输入,也可以输出。所谓输入,就是NSS的电平信号给自己,所谓输出,就是将NSS的电平信号发送出去,给从机。配置为输出,还是不输出,我们可以通过SPI_CR2寄存器的SSOE位。当SSOE为1时,并且SPI处于主模式控制时,NSS就输出低电平,也就是拉低,因此当其他SPI设备的NSS引脚与它相连,必然接收到低电平,则片选成功,都成为从设备了。NSS的输出就介绍到这里

     下面介绍NSS的输入。

     我们都知道NSS输入又分为硬件输入和软件控制输入两种模式,那么就从这两种模式入手,来揭开它的面纱吧。

     先说软件模式吧。

     1对于SPI主机来说,需要设置SPI_CR1寄存器的SSM为1和SSI位为1,SSM为1是为了使能软件管理。,NSS有内部和外部引脚。这时候,外部引脚留作他用(可以用来作为GPIO驱动从设备的片选信号)。内部NSS引脚电平则通过SPI_CRL寄存器的SSI位来驱动。SSI位为1是为了使NSS内电平为高电平。这时候,不免产生疑问,为什么主设备的内部NSS电平要为1呢?

STM32手册上说,要保持MSTR和SPE位为1,也就是说要保持主机模式,只有NSS接到高电平信号时,这两位才能保持置1.也就是说对于STM32的SPI,要保持为主机状态,内部输入的NSS电平必须为高。当然这里在硬件模式下也是如此。

2 对于SPI 从机来说

主机自己的内部NSS高电平解决了,那么SPI从机的NSS片选低电平也得解决啊。

如果从机选择STM32的一个SPI,譬如主机选为SPI1,从机选为SPI2,则要按照以下操作

手册说,NSS引脚在完成字节传输之前必须连接到一个低电平信号。在软件模式下,则需要设置SPI_CR1寄存器的SSM位为1(软件管理使能)和SSI位为0.果然如此。SSI必须要为0,也就是SPI2的片选为低,则片选成功。

若从机为一个其他的SPI芯片,譬如我那个ADXL345加速度传感器。那么,我们可以有两种方法

一种方法,是把芯片的CS接到GND上,另一种方法是,用一个GPIO口去输出低电平来控制CS片选成功。这个GPIO可以是任何一个GPIO口,当然我们上面提到当SPI的主机配置为软件模式,外部NSS引脚留作他用了,它就是一个GPIO了,我们也可以用它。这时候,我们可以设置它推挽输出为低电平,然后用线跟从机的CS相连,那么就可以片选从芯片了。

再说说硬件模式。

对于主机,我们的NSS可以直接接到高电平,对于从机,NSS接低就可以。

当然我们上面提过当一个主机的SSOE为1时,主机工作在输出模式,而且NSS拉低了,我们要让从机片选,只要将CS接到主机的NSS上,CS自动拉低。

这便是,ST公司设计的STM32SPI NSS的工作流程

使用特权

评论回复
地板
别活成了闰土|  楼主 | 2015-12-8 09:37 | 只看该作者
感谢gejigeji521,"当然我们上面提过当一个主机的SSOE为1时,主机工作在输出模式,而且NSS拉低了,我们要让从机片选,只要将CS接到主机的NSS上,CS自动拉低。"   输入模式下,有硬件模式吗?有主模式且硬件模式且输出模式下吗?如果有,怎么输出?
还有接收的时候一定要先发送吗?利用dma来传输时在接收的时候是怎么产生时钟的?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

11

帖子

0

粉丝