历史上的今天
今天是:2024年12月12日(星期四)
2018年12月12日 | 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功能太鸡肋,绝大多数场景都不适用。
史海拾趣
|
基于51单片机的汉字LCD智能显示模块设计 引言 在电子产品设计中,人机交互显示界面是必不可少的工作,目前一般使用的液晶显示器均为七段笔划式,只能显示数字和少量字符,功能往往受到局限,对于较复杂的字符或图形则无能为力。而LCD智能型显示 ...… 查看全部问答> |
|
//########################################################################### // // 文件名: Example_281xEvPwm.c // // 说明: // 设置事件管理器的定时器(TIMER1, TIMER2, TIMER3 and TIMER4) // 来产生 T1PWM, T2PWM, T3PWM, T4PWM ...… 查看全部问答> |
|
我用LoadMenu载入菜单,可是得到的句柄好像不对的,不能禁用菜单,但是用GetMenu可以实现,可是这个函数在WIncE下不能用的。请教各位,急急… 查看全部问答> |
|
在C语言中,如果程序由多个源文件组成,那么在一个文件B中想引用另一个文件A中已经定义的外部变量(例如 :char v),只需在文件B中写: extern v; (1) 就可以了,不知道C430中可不可以这样用?我试了一下,debug后报了一个warning: W ...… 查看全部问答> |
|
上个月申请了富士通半导体公司的通变频方案项目开发和支持FAE职位,主要针对180度无传感器矢量变频的控制方案,负责整个变频项目设计周期中技术相关工作支持,包括软硬件调试和系统调试。目前一面通过,大家觉得这个offer如何?第二面需要准备什么 ...… 查看全部问答> |
|
转让天嵌科技ARM9开发板/s3c2440+4.3寸LCD 14张DVD资料 转让天嵌科技arm9开发板 s3c2440 +4.3寸LCD 14DVD资料/ U转串 本人买来后,测试一下板子 ,对应用程序做了些修改。 刚买来的时候 ,用了几天, 因为工作了,后来就没有使用。95%成以上新。我在淘宝上买的 620元 附带 jlink V8 仿 ...… 查看全部问答> |
|
可能我原来做的电源太丑了,SOSO送了个PCB,现在装起来,简单调了一下,感觉挺好,只用示波器看了下,没有详细测试 有些原件没有找到,如零点几欧的电阻等,所以没有调整限流部分。 PCB中的三极管的引脚与现在国产流行封装(E、B、C)不一致, ...… 查看全部问答> |
|
以下是网上的一个程序,感觉最低位D0没有读到,因为MAX6675是在下降沿读取数据的,不知道我说的对不对? void delay_us(uchar m) { while(m--); } uint Read_6675() { uchar i=0; uint temp=0; &nbs ...… 查看全部问答> |




