串行外設接口(SPI)是一種同步串行數(shù)據(jù)通信接口,常用于 MCU 與外部設備之間進行同步串行通信。SPI是一種高速的,全雙工,同步的通信總線,并且在芯片的管腳上只占用四根線,節(jié)約了芯片的管腳,同時為PCB的布局上節(jié)省空間。CW32L083 內(nèi)部集成 2 個串行外設 SPI 接口,支持雙向全雙工、單線半雙工和單工通信模式,可配置 MCU 作為 主機或從機,支持多主機通信模式,支持直接內(nèi)存訪問(DMA)。
單工通信模式
SPI 支持單工通信模式,主機和從機通過一根單向數(shù)據(jù)線進行單發(fā)或單收通信。主機使用 MOSI 信號線進行單發(fā)通信,使用 MISO 信號線進行單收通信;從機使用 MOSI 信號線進行單收通信, 使用 MISO 信號線進行單發(fā)通信,未使用的信號線可供其它功能使用。
主機單發(fā),從機單收應用場景下,連接框圖如下:
主機單發(fā)配置:
設置 SPIx_CR1.MODE 為 0x1,SPI 工作于單工單發(fā)通信模式;
設置 SPIx_CR1.MSTR 為 1,SPI 工作于主機模式。
設置 SPIx_SSI.SSI 為 0,在從機選擇 CS 引腳輸出低電平,作為通信起始信號。
當發(fā)送緩沖器為空時,即 SPIx_ISR.TXE 標志位為 1,將待發(fā)送的一幀數(shù)據(jù)寫入 SPIx_DR 寄存器,數(shù)據(jù)在同步移位時鐘信號的控制下從 MOSI 引腳輸出。
當寫入最后一幀數(shù)據(jù)后,必須等待發(fā)送緩沖空標志位 SPIx_ISR.TXE 變?yōu)?1,同時 SPI 總線忙標志位 SPIx_ISR. BUSY 變?yōu)?0,以確保數(shù)據(jù)發(fā)送完畢。然后設置 SPIx_SSI.SSI 為 1,使從機選擇 CS 引腳輸出高電平,結(jié)束本次通信。
從機單收配置:
設置 SPIx_CR1.MODE 為 0x2,SPI 工作于單工單收通信模式;
設置 SPIx_CR1.MSTR 為 0,SPI 工作于從機模式。
當檢測到 CS 引腳變?yōu)榈碗娖綍r,從機開始與主機通信。當接收緩沖器非空時,即 SPIx_ISR.RXNE 標志位為 1,表示已經(jīng)接收完成一幀數(shù)據(jù),此時可以讀取 SPIx_DR 寄存器。當檢測到 CS 引腳變?yōu)楦唠娖綍r,本次通信結(jié)束。
主機單收,從機單發(fā)應用場景下,連接框圖如下:
具體設置與主機單發(fā)和從機單收類似,詳情可查看用戶手冊。
SPI中斷
SPI 控制器支持 8 個中斷源,當 SPI 中斷觸發(fā)事件發(fā)生時,中斷標志位會被硬件置位,如果設置了對應的中斷使能控制位,將產(chǎn)生中斷請求。
在用戶 SPI 中斷服務程序中,應查詢相關 SPI 中斷標志位,以進行相應的處理,在退出中斷服務程序之前,要清除該中斷標志位,避免重復進入中斷程序。
實例演示:SPI單工模式進行主從機通信,主機單發(fā),從機單收。
SPIy(主機)采用中斷方式發(fā)送TxBuffer緩沖區(qū)中的數(shù)據(jù),SPIz(從機)采用中斷方式接收數(shù)據(jù)并存儲到RxBuffer緩沖區(qū),比較TxBuffer和RxBuffer,如果數(shù)據(jù)一致LED1亮,否則LED2亮。
1. 配置RCC
voidRCC_Configuration(void) { RCC_HSI_Enable(RCC_HSIOSC_DIV2);//SYSCLK=HSI=24MHz=HCLK=PCLK RCC_AHBPeriphClk_Enable(SPIy_GPIO_CLK|SPIz_GPIO_CLK|RCC_AHB_PERIPH_GPIOC,ENABLE);//外設時鐘使能 SPIy_APBClkENx(SPIy_CLK,ENABLE); SPIz_APBClkENx(SPIz_CLK,ENABLE); }?
2. 配置GPIO
voidGPIO_Configuration(void) { GPIO_InitTypeDefGPIO_InitStructure={0}; SPIy_AF_SCK;//SPISCKMOSI復用 SPIy_AF_MOSI; SPIz_AF_SCK; SPIz_AF_MOSI; GPIO_InitStructure.Pins=SPIy_SCK_PIN;//推挽輸出 GPIO_InitStructure.Mode=GPIO_MODE_OUTPUT_PP; GPIO_Init(SPIy_GPIO, GPIO_InitStructure); GPIO_InitStructure.Pins=SPIy_MOSI_PIN; GPIO_Init(SPIy_GPIO, GPIO_InitStructure); GPIO_InitStructure.Pins=SPIz_SCK_PIN;//浮空輸入 GPIO_InitStructure.Mode=GPIO_MODE_INPUT; GPIO_Init(SPIz_GPIO, GPIO_InitStructure); GPIO_InitStructure.Pins=SPIz_MOSI_PIN; GPIO_Init(SPIz_GPIO, GPIO_InitStructure); GPIO_InitStructure.Pins=GPIO_PIN_3|GPIO_PIN_2;//PC3LED1/PC2LED2 GPIO_InitStructure.Mode=GPIO_MODE_OUTPUT_PP; GPIO_Init(CW_GPIOC, GPIO_InitStructure); PC03_SETLOW();//LED滅 PC02_SETLOW(); }?
3. 配置SPI
voidSPI_Configuration() { SPI_InitTypeDefSPI_InitStructure={0}; SPI_InitStructure.SPI_Direction=SPI_Direction_1Line_TxOnly;//單工單發(fā) SPI_InitStructure.SPI_Mode=SPI_Mode_Master;//主機模式 SPI_InitStructure.SPI_DataSize=SPI_DataSize_8b;//幀數(shù)據(jù)長度為8bit SPI_InitStructure.SPI_CPOL=SPI_CPOL_Low;//時鐘空閑電平為低 SPI_InitStructure.SPI_CPHA=SPI_CPHA_1Edge;//第一個邊沿采樣 SPI_InitStructure.SPI_NSS=SPI_NSS_Soft;//片選信號由SSI寄存器控制 SPI_InitStructure.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_8;//波特率為PCLK的8分頻 SPI_InitStructure.SPI_FirstBit=SPI_FirstBit_MSB;//最高有效位MSB收發(fā)在前 SPI_InitStructure.SPI_Speed=SPI_Speed_Low;//低速SPI SPI_Init(SPIy, SPI_InitStructure); SPI_InitStructure.SPI_Direction=SPI_Direction_1Line_RxOnly;//單工單收 SPI_InitStructure.SPI_Mode=SPI_Mode_Slave;//從機模式 SPI_Init(SPIz, SPI_InitStructure); SPI_Cmd(SPIy,ENABLE); SPI_Cmd(SPIz,ENABLE); }?
4. 配置NVIC中斷函數(shù)
voidNVIC_Configuration(void) { NVIC_SetPriority(SPIy_IRQ,1);//優(yōu)先級,無優(yōu)先級分組 NVIC_SetPriority(SPIz_IRQ,0); NVIC_EnableIRQ(SPIy_IRQ);//SPI中斷使能 NVIC_EnableIRQ(SPIz_IRQ); } voidSPI1_IRQHandler(void)//SPI1中斷函數(shù) { if(SPI_GetITStatus(CW_SPI1,SPI_IT_TXE)!=RESET) { if(TxCounter==BufferSize-1) { SPI_ITConfig(CW_SPI1,SPI_IT_TXE,DISABLE); } SPI_SendData(CW_SPI1,TxBuffer[TxCounter++]); } } voidSPI2_IRQHandler(void)//SPI2中斷函數(shù) { if(SPI_GetITStatus(CW_SPI2,SPI_IT_RXNE)!=RESET) { RxBuffer[RxCounter++]=SPI_ReceiveData(CW_SPI2); } }?
5. 比較兩個buffers區(qū)
TestStatusBuffercmp(uint8_t*pBuffer1,uint8_t*pBuffer2,uint16_tBufferLength) { while(BufferLength--) { if(*pBuffer1!=*pBuffer2) { returnFAILED; } pBuffer1++; pBuffer2++; } returnPASSED; }?
6. 主程序
int32_tmain(void) { RCC_Configuration();//配置RCC GPIO_Configuration();//配置GPIO SPI_Configuration();//配置SPI NVIC_Configuration();//配置NVIC SPI_ITConfig(SPIz,SPI_IT_RXNE,ENABLE);//使能SPIzRXNE中斷 SPI_NSSInternalSoftwareConfig(SPIz,SPI_NSSInternalSoft_Reset);//軟件NSS,選中SPIz SPI_ITConfig(SPIy,SPI_IT_TXE,ENABLE);//使能SPIyTXE中斷 while(RxCounter
7.實驗結(jié)果顯示:LED1亮起,buffers區(qū)數(shù)據(jù)相等,SPI單工模式主從通訊(中斷方式)功能實現(xiàn)。
來源:武漢芯源半導體
免責聲明:本文為轉(zhuǎn)載文章,轉(zhuǎn)載此文目的在于傳遞更多信息,版權(quán)歸原作者所有。本文所用視頻、圖片、文字如涉及作品版權(quán)問題,請聯(lián)系小編進行處理
審核編輯 黃宇
-
mcu
+關注
關注
146文章
17317瀏覽量
352640 -
通信
+關注
關注
18文章
6070瀏覽量
136424 -
SPI
+關注
關注
17文章
1721瀏覽量
92124
發(fā)布評論請先 登錄
相關推薦
![](https://file.elecfans.com/web2/M00/A7/62/poYBAGRt0PGAVvN8AAjVPVGnCD8727.jpg)
評論