如何在stm32f4上使用硬件NSS(SPI)?

mko*_*kom 8 microcontroller arm spi stm32 stm32f4discovery

所以我尝试将硬件NSS信号与HAL库一起使用,但我找不到任何使NSS引脚具有低电平或高电平的功能.我也试图在HAL文档中找到答案,但也没有任何信息.Internet中的所有示例仅包含NSS软件.如何使用硬件NSS?

pee*_*ets 7

在某处我读到,只要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;
Run Code Online (Sandbox Code Playgroud)

传输顺序:

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 );
Run Code Online (Sandbox Code Playgroud)

所以我决定使用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
Run Code Online (Sandbox Code Playgroud)

我使用阻塞传输(没有DMA或中断),因为它足够快,没有其他任务等待.事实证明,DMA设置在20MHz时仅发送24个字节的时间长得令人无法接受.IT将是一个可接受的替代方案.

据我所知,在STM32L4xx手册第38.4.12/13章中,自动NSS在每个字节/字传输后变为高电平,因此不适用于整个传输中保持NSS为低的较长流.


小智 2

您可以将 NSS 引脚用作标准 GPIO,并通过中断例程驱动它。你应该通过软件来完成这部分。首先将 NSS 设置为低电平,然后发送帧 ( HAL_SPI_Transmit )。

\n

从机获取所有帧后,使用HAL_SPI_RxCpltCallback函数并在该中断中将 NSS 引脚设置为高电平。

\n

不要忘记将 GPIO 引脚连接到从机上的 NSS 引脚。

\n