STM32 SPI NSS 引脚为不能拉高问题
使用過 STM32?的SPI?的朋友可能都會(huì)發(fā)現(xiàn)一個(gè)問題,那就是其NSS引腳?在硬件模式下無法自動(dòng)拉高,可能也因?yàn)檫@個(gè)原因致使? 。大部分朋友在使用SPI時(shí)候都是優(yōu)先選用軟件?控制NSS引腳的工作模式。
最近想用 SPI?直接 DMA?對一傳感器進(jìn)行數(shù)據(jù)通信,想直接用SPI的硬件NSS控制模式來操作SPI(之前一直是軟件模式,這次對 CPU時(shí)間比要求較高,不想再用軟件去切換引腳 ):
引腳配置?及 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 );
采用以上的配置發(fā)現(xiàn),使能DMA?后,SPI有時(shí)鐘和數(shù)據(jù)輸出,說明SPI可以成功發(fā)送數(shù)據(jù),但是問題的全程N(yùn)SS引腳一直拉低( 按常理應(yīng)該是SPI在發(fā)送數(shù)據(jù)時(shí),NSS拉低,數(shù)據(jù)發(fā)送完成后NSS自動(dòng)拉高才對),檢查電路連接沒有問題后再回去看ST官方手冊發(fā)現(xiàn)其NSS的高低電平定義如下:
????? ?意思是說 SPI主模式下,啟用石硬件NSS控制模式,并且NSS輸出使能后,只要SPI模塊打開,其NSS引腳就輸出低電平,而且低電平將持續(xù)到SPI模塊關(guān)閉(注意這里并不是發(fā)送數(shù)據(jù)完成,這就尷尬了,還用要手動(dòng)去開關(guān)SPI模塊),到這里是乎找到些線索,那就手動(dòng)去關(guān)閉SPI和使能模塊吧,將會(huì)用來下面的兩個(gè)接口函數(shù)(也可以直接操作寄存器):
SPI_Cmd(SPI_MASTER, DISABLE);
SPI_Cmd(SPI_MASTER, ENABLE);
可以當(dāng)我手動(dòng)關(guān)閉SPI后,再去看NSS引腳電平時(shí),發(fā)現(xiàn)其還是處于拉低狀態(tài)(好坑呀,怎么還是低),不過這次的低電平好像還不如開啟時(shí)低的那么穩(wěn)定(用示波器看),懷疑此時(shí)NSS引腳處釋放狀態(tài)(內(nèi)部并沒有控制輸出),給它外部上拉一個(gè)10K到3.3V的上拉電阻后,發(fā)現(xiàn)NSS引腳被成功拉高,進(jìn)一步證實(shí)了前面的懷疑。這時(shí)后發(fā)現(xiàn)ST文檔也好雞賊,它并沒有說明SPI模塊關(guān)閉后NSS引腳會(huì)被拉高,只是說了在模塊并閉前 NSS引腳都是低電平。這樣一來發(fā)現(xiàn)又回到了解放前,感覺還是不能直接用硬件NSS模式。
如果非要用NSS硬件模式,電路設(shè)計(jì)時(shí)最好給NSS引腳接外部上拉電阻到高電平,不然就只好用NSS軟件管理模式,用軟件用切換NSS引腳電平。
真心感覺STM32?的SPI?硬件NSS功能太雞肋,絕大多數(shù)場景都不適用。
????? ??
總結(jié)
以上是生活随笔為你收集整理的STM32 SPI NSS 引脚为不能拉高问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Altium Designer Exc
- 下一篇: MFC EDIT控件 接收“回车”与“