所以我尝试将硬件NSS信号与HAL库一起使用,但我找不到任何使NSS引脚具有低电平或高电平的功能。我也试图在HAL文档中找到答案,但也没有任何信息。 Internet中的所有示例仅包含NSS软件。 如何使用硬件NSS?
答案 0 :(得分:6)
在某处我读到,只要SPI主器件被使能,NSS就被驱动为低电平,如果SPI主器件被禁止,则NSS再次被驱动为高电平。 我尝试使用ST的HAL库(Cube / CubeMX)和STM32L476并轮询SPI1。传输之前的初始化和传输之后的初始化没有设置NSS引脚 - 但需要很长时间:
初始结构:
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;
hspi1.Init.NSS = SPI_NSS_HARD_OUTPUT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 7;
hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
传输顺序:
HAL_SPI_Init( &hspi1 );
HAL_SPI_TransmitReceive( &hspi1, btx, brx, l, 5 ); // timeout 5msec;
while( hspi1.State == HAL_SPI_STATE_BUSY ); // wait for xmission complete
HAL_SPI_DeInit( &hspi1 );
所以我决定使用GPIO手动设置引脚(在init中使用SPI_NSS_SOFT):
HAL_GPIO_WritePin( NSS1_GPIO_Port, NSS1_Pin, GPIO_PIN_RESET ); // NSS1 low
HAL_SPI_TransmitReceive( &hspi1, btx, brx, l, 5 ); // timeout 5msec;
while( hspi1.State == HAL_SPI_STATE_BUSY ); // wait xmission complete
HAL_GPIO_WritePin( NSS1_GPIO_Port, NSS1_Pin, GPIO_PIN_SET ); // NSS1 high
我使用了阻塞传输(没有DMA或中断),因为它足够快,没有其他任务在等待。事实证明,DMA设置在20MHz时仅发送24个字节的时间长得令人无法接受。 IT将是一个可接受的替代方案。
据我所知,在STM32L4xx手册第38.4.12 / 13章中,自动NSS在每次字节/字传输后变为高电平,因此不适用于在整个传输过程中保持NSS较低的较长流。
答案 1 :(得分:2)
您可以将NSS引脚用作标准GPIO并使用中断例程驱动它。您应该通过软件执行该操作。首先将Nss置为低电平然后发送帧(HAL_SPI_Transmit) 从器件获得所有帧后,使用HAL_SPI_RxCpltCallback并将Nss置于该中断的高位。
别忘了将GPIO引脚连接到从机上的Nss引脚。
答案 2 :(得分:0)
查看STM32芯片的参考手册。我不知道它们是否都相同,但是根据我的一个(STM32WB55xx),我可以找到一个指向(STM32F0)的公共Web链接...
请参阅有关NSS引脚管理的SPI功能描述(我链接到的STM32F0文档的28.5.5节),其中描述了三种模式:
软件NSS管理(SPIx_CR1寄存器SSM位= 1)。内部从机选择信息由寄存器SPIx_CR1中的SSI位内部驱动。外部NSS引脚可供应用免费使用。
硬件NSS管理(SSM位= 0)。根据寄存器SPIx_CR1中的SSOE位,有两种可能的配置:
查看我的SoC的标头,软模式为SSM = 1(软件NSS管理)。硬输出模式为SSM = 0和SSOE = 1(NSS输出使能)。硬输入模式为全零(NSS输出禁用)。
如果使用硬输出模式,则可能还需要查看NSS脉冲模式(我链接到的STM32F0文档中的28.5.12节)。它用时序图描述了系统在大多数情况下如何将NSS保持为低电平,从而在数据帧之间将NSS置于高电平。如果您的设备使用NSS / CS同步数据帧,则这可能会很有用。也许不是,如果您的设备通过中止当前操作来对NSS变高做出反应,因为文本似乎表明它将在您传输的每个字之间(而不是在缓冲区之间)对NSS产生脉冲。
不幸的是,这看起来并不是最灵活的实现。根据您的应用程序,您可能会发现更容易将其置于软模式,而只需通过GPIO切换NSS引脚即可。
答案 3 :(得分:0)
如果HiZ [未记录],NSS引脚可能需要上拉电阻器