单片机
返回首页

STM32 SPI NSS 引脚为不能拉高问题

2018-12-12 来源:eefocus

使用过 STM32 的SPI 的朋友可能都会发现一个问题,那就是其NSS引脚 在硬件模式下无法自动拉高,可能也因为这个原因致使  。大部分朋友在使用SPI时候都是优先选用软件 控制NSS引脚的工作模式。


最近想用 SPI 直接 DMA 对一传感器进行数据通信,想直接用SPI的硬件NSS控制模式来操作SPI(之前一直是软件模式,这次对 CPU时间比要求较高,不想再用软件去切换引脚 ):


引脚配置 及 SPI DMA 配置如下:


/* 引脚配置 */

  GPIO_InitStructure.GPIO_Pin =  SPI_MASTER_PIN_NSS | SPI_MASTER_PIN_SCK | SPI_MASTER_PIN_MOSI | SPI_MASTER_PIN_MISO; // 

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;


  GPIO_Init(SPI_MASTER_GPIO, &GPIO_InitStructure);




/* SPI_配置 ----*/

  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;

  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;

  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;

  SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;

  SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;

  SPI_InitStructure.SPI_NSS = SPI_NSS_Hard;

  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;  // 36M/4 = 9M

  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;

  SPI_InitStructure.SPI_CRCPolynomial = 7;

  SPI_Init(SPI_MASTER, &SPI_InitStructure);


SPI_SSOutputCmd(SPI_MASTER, ENABLE);

SPI_I2S_DMACmd(SPI_MASTER, SPI_I2S_DMAReq_Tx, ENABLE);

SPI_Cmd(SPI_MASTER, ENABLE);


SPI_Cmd(SPI_MASTER, ENABLE);


DMA_DeInit(SPI_MASTER_Tx_DMA_Channel);

  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SPI_MASTER_DR_Base;

  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)SPI_MASTER_Buffer_Tx;

  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;

  DMA_InitStructure.DMA_BufferSize = BufferSize;

  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;

  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;

  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;

  DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;

  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;


  DMA_Init(SPI_MASTER_Tx_DMA_Channel, &DMA_InitStructure);


DMA_Cmd(SPI_MASTER_Tx_DMA_Channel, ENABLE);

while( DMA_GetFlagStatus(DMA1_FLAG_TC3) == RESET );


采用以上的配置发现,使能DMA 后,SPI有时钟和数据输出,说明SPI可以成功发送数据,但是问题的全程NSS引脚一直拉低( 按常理应该是SPI在发送数据时,NSS拉低,数据发送完成后NSS自动拉高才对),检查电路连接没有问题后再回去看ST官方手册发现其NSS的高低电平定义如下:



意思是说 SPI主模式下,启用石硬件NSS控制模式,并且NSS输出使能后,只要SPI模块打开,其NSS引脚就输出低电平,而且低电平将持续到SPI模块关闭(注意这里并不是发送数据完成,这就尴尬了,还用要手动去开关SPI模块),到这里是乎找到些线索,那就手动去关闭SPI和使能模块吧,将会用来下面的两个接口函数(也可以直接操作寄存器):


SPI_Cmd(SPI_MASTER, DISABLE);


SPI_Cmd(SPI_MASTER, ENABLE);


可以当我手动关闭SPI后,再去看NSS引脚电平时,发现其还是处于拉低状态(好坑呀,怎么还是低),不过这次的低电平好像还不如开启时低的那么稳定(用示波器看),怀疑此时NSS引脚处释放状态(内部并没有控制输出),给它外部上拉一个10K到3.3V的上拉电阻后,发现NSS引脚被成功拉高,进一步证实了前面的怀疑。这时后发现ST文档也好鸡贼,它并没有说明SPI模块关闭后NSS引脚会被拉高,只是说了在模块并闭前 NSS引脚都是低电平。这样一来发现又回到了解放前,感觉还是不能直接用硬件NSS模式。


如果非要用NSS硬件模式,电路设计时最好给NSS引脚接外部上拉电阻到高电平,不然就只好用NSS软件管理模式,用软件用切换NSS引脚电平。


真心感觉STM32 的SPI 硬件NSS功能太鸡肋,绝大多数场景都不适用。

进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • 家用电源无载自动断电装置的设计与制作

  • 短波AM发射器电路设计图

  • 带有短路保护系统的5V直流稳压电源电路图

  • 如何调制IC555振荡器

  • 基于ICL296的大电流开关稳压器电源电路

  • 基于TDA2003的简单低功耗汽车立体声放大器电路

    相关电子头条文章