我在某处读到,只要SPI主机启用,NSS就会被拉低,并在禁用SPI主机时再次拉高。我尝试使用来自ST的STM32L476和轮询SPI1的HAL库(Cube/STM32CubeMX)。在传输之前进行初始化和之后进行去初始化并没有设置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 );
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
请查看您的STM32芯片参考手册。我不知道它们是否都相同,但根据我的(STM32WB55xx)和我能够找到的一个公共网页链接的手册(STM32F0)...
请参阅SPI功能描述中的NSS引脚管理(我提供的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 / CS来同步数据帧,则可能会有用。或者,如果您的设备通过中止当前操作来响应NSS变为高电平,则可能不是很有用,因为该文本似乎表明它会在每个传输的字之间脉冲NSS,而不是在缓冲区之间。
不幸的是,这似乎不是最灵活的实现。根据您的应用程序,您可能会发现保持软模式并通过GPIO切换NSS引脚更容易。