串行外設(shè)接口(SPI)是一種同步串行數(shù)據(jù)通信接口,常用于 MCU 與外部設(shè)備之間進(jìn)行同步串行通信。SPI是一種高速的,全雙工,同步的通信總線,并且在芯片的管腳上只占用四根線,節(jié)約了芯片的管腳,同時(shí)為PCB的布局上節(jié)省空間。CW32L083 內(nèi)部集成 2 個(gè)串行外設(shè) SPI 接口,支持雙向全雙工、單線半雙工和單工通信模式,可配置 MCU 作為 主機(jī)或從機(jī),支持多主機(jī)通信模式,支持直接內(nèi)存訪問(wèn)(DMA)。
單工通信模式
SPI 支持單工通信模式,主機(jī)和從機(jī)通過(guò)一根單向數(shù)據(jù)線進(jìn)行單發(fā)或單收通信。主機(jī)使用 MOSI 信號(hào)線進(jìn)行單發(fā)通信,使用 MISO 信號(hào)線進(jìn)行單收通信;從機(jī)使用 MOSI 信號(hào)線進(jìn)行單收通信, 使用 MISO 信號(hào)線進(jìn)行單發(fā)通信,未使用的信號(hào)線可供其它功能使用。
主機(jī)單發(fā),從機(jī)單收應(yīng)用場(chǎng)景下,連接框圖如下:
主機(jī)單發(fā)配置:
設(shè)置 SPIx_CR1.MODE 為 0x1,SPI 工作于單工單發(fā)通信模式;
設(shè)置 SPIx_CR1.MSTR 為 1,SPI 工作于主機(jī)模式。
設(shè)置 SPIx_SSI.SSI 為 0,在從機(jī)選擇 CS 引腳輸出低電平,作為通信起始信號(hào)。
當(dāng)發(fā)送緩沖器為空時(shí),即 SPIx_ISR.TXE 標(biāo)志位為 1,將待發(fā)送的一幀數(shù)據(jù)寫(xiě)入 SPIx_DR 寄存器,數(shù)據(jù)在同步移位時(shí)鐘信號(hào)的控制下從 MOSI 引腳輸出。
當(dāng)寫(xiě)入最后一幀數(shù)據(jù)后,必須等待發(fā)送緩沖空標(biāo)志位 SPIx_ISR.TXE 變?yōu)?1,同時(shí) SPI 總線忙標(biāo)志位 SPIx_ISR. BUSY 變?yōu)?0,以確保數(shù)據(jù)發(fā)送完畢。然后設(shè)置 SPIx_SSI.SSI 為 1,使從機(jī)選擇 CS 引腳輸出高電平,結(jié)束本次通信。
從機(jī)單收配置:
設(shè)置 SPIx_CR1.MODE 為 0x2,SPI 工作于單工單收通信模式;
設(shè)置 SPIx_CR1.MSTR 為 0,SPI 工作于從機(jī)模式。
當(dāng)檢測(cè)到 CS 引腳變?yōu)榈碗娖綍r(shí),從機(jī)開(kāi)始與主機(jī)通信。當(dāng)接收緩沖器非空時(shí),即 SPIx_ISR.RXNE 標(biāo)志位為 1,表示已經(jīng)接收完成一幀數(shù)據(jù),此時(shí)可以讀取 SPIx_DR 寄存器。當(dāng)檢測(cè)到 CS 引腳變?yōu)楦唠娖綍r(shí),本次通信結(jié)束。
主機(jī)單收,從機(jī)單發(fā)應(yīng)用場(chǎng)景下,連接框圖如下:
具體設(shè)置與主機(jī)單發(fā)和從機(jī)單收類似,詳情可查看用戶手冊(cè)。
SPI中斷
SPI 控制器支持 8 個(gè)中斷源,當(dāng) SPI 中斷觸發(fā)事件發(fā)生時(shí),中斷標(biāo)志位會(huì)被硬件置位,如果設(shè)置了對(duì)應(yīng)的中斷使能控制位,將產(chǎn)生中斷請(qǐng)求。
在用戶 SPI 中斷服務(wù)程序中,應(yīng)查詢相關(guān) SPI 中斷標(biāo)志位,以進(jìn)行相應(yīng)的處理,在退出中斷服務(wù)程序之前,要清除該中斷標(biāo)志位,避免重復(fù)進(jìn)入中斷程序。
實(shí)例演示:SPI單工模式進(jìn)行主從機(jī)通信,主機(jī)單發(fā),從機(jī)單收。
SPIy(主機(jī))采用中斷方式發(fā)送TxBuffer緩沖區(qū)中的數(shù)據(jù),SPIz(從機(jī))采用中斷方式接收數(shù)據(jù)并存儲(chǔ)到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);//外設(shè)時(shí)鐘使能 SPIy_APBClkENx(SPIy_CLK,ENABLE); SPIz_APBClkENx(SPIz_CLK,ENABLE); }?
2. 配置GPIO
voidGPIO_Configuration(void) { GPIO_InitTypeDefGPIO_InitStructure={0}; SPIy_AF_SCK;//SPISCKMOSI復(fù)用 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;//主機(jī)模式 SPI_InitStructure.SPI_DataSize=SPI_DataSize_8b;//幀數(shù)據(jù)長(zhǎng)度為8bit SPI_InitStructure.SPI_CPOL=SPI_CPOL_Low;//時(shí)鐘空閑電平為低 SPI_InitStructure.SPI_CPHA=SPI_CPHA_1Edge;//第一個(gè)邊沿采樣 SPI_InitStructure.SPI_NSS=SPI_NSS_Soft;//片選信號(hào)由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;//從機(jī)模式 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)先級(jí),無(wú)優(yōu)先級(jí)分組 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. 比較兩個(gè)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.實(shí)驗(yàn)結(jié)果顯示:LED1亮起,buffers區(qū)數(shù)據(jù)相等,SPI單工模式主從通訊(中斷方式)功能實(shí)現(xiàn)。
來(lái)源:武漢芯源半導(dǎo)體
免責(zé)聲明:本文為轉(zhuǎn)載文章,轉(zhuǎn)載此文目的在于傳遞更多信息,版權(quán)歸原作者所有。本文所用視頻、圖片、文字如涉及作品版權(quán)問(wèn)題,請(qǐng)聯(lián)系小編進(jìn)行處理
審核編輯 黃宇
-
mcu
+關(guān)注
關(guān)注
146文章
16802瀏覽量
349370 -
通信
+關(guān)注
關(guān)注
18文章
5926瀏覽量
135703 -
SPI
+關(guān)注
關(guān)注
17文章
1681瀏覽量
91059
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論