STM32 軟件模擬SPI時(shí)序驅(qū)動(dòng)NRF24L01
掃描二維碼
隨時(shí)隨地手機(jī)看文章
其實(shí)stm32本身的硬件SPI也很好用,但是還是想用軟件來模擬一下PSI的時(shí)序。SPI是一種高速的,全雙工,同步串行的通信總線。SPI通信方式相當(dāng)于是一個(gè)環(huán)形結(jié)構(gòu),由CSN、MISO、MOSI、SCLK四線組成,主要是在SCLK時(shí)鐘線的驅(qū)動(dòng)下,進(jìn)行數(shù)據(jù)轉(zhuǎn)換。接下來直接上程序配置:使用32模擬SPI時(shí)序的IO口配置,應(yīng)該注意的是MISO應(yīng)該選擇模擬輸入方式GPIO_Mode_IN_FLOATING。以下是我的初始化部分:
/*用于軟件模擬SPIIO口宏定義區(qū)*/#defineSPI_CS_PORTGPIOB#defineSPI_CS_PINGPIO_Pin_11#defineSPI_CS_LOW(SPI_CS_PORT->BRR|=SPI_CS_PIN)#defineSPI_CS_HIGH(SPI_CS_PORT->BSRR|=SPI_CS_PIN)#defineSPI_SCK_PORTGPIOA#defineSPI_SCK_PINGPIO_Pin_12#defineSPI_SCK_LOW(SPI_SCK_PORT->BRR|=SPI_SCK_PIN)#defineSPI_SCK_HIGH(SPI_SCK_PORT->BSRR|=SPI_SCK_PIN)#defineSPI_MISO_PORTGPIOA#defineSPI_MISO_PINGPIO_Pin_8#defineSPI_MISO_LOW(SPI_MISO_PORT->BRR|=SPI_MISO_PIN)#defineSPI_MISO_HIGH(SPI_MISO_PORT->BSRR|=SPI_MISO_PIN)#defineSPI_MISO_READ(SPI_MISO_PORT->IDR&SPI_MISO_PIN)#defineSPI_MOSI_PORTGPIOA#defineSPI_MOSI_PINGPIO_Pin_11#defineSPI_MOSI_LOW(SPI_MOSI_PORT->BRR|=SPI_MOSI_PIN)#defineSPI_MOSI_HIGH(SPI_MOSI_PORT->BSRR|=SPI_MOSI_PIN)voidSPI_GPIO_Config(void){GPIO_InitTypeDefGPIO_InitStruct;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE);//CSGPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;GPIO_InitStruct.GPIO_Pin=SPI_CS_PIN;GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(SPI_CS_PORT,&GPIO_InitStruct);//SCKGPIO_InitStruct.GPIO_Pin=SPI_SCK_PIN;GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;GPIO_Init(SPI_SCK_PORT,&GPIO_InitStruct);//MISOGPIO_InitStruct.GPIO_Pin=SPI_MISO_PIN;GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;GPIO_Init(SPI_MISO_PORT,&GPIO_InitStruct);//MOSIGPIO_InitStruct.GPIO_Pin=SPI_MOSI_PIN;GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;GPIO_Init(SPI_MOSI_PORT,&GPIO_InitStruct);SPI_CS_HIGH;SPI_SCK_LOW;}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
模擬SPI時(shí)序
u8SPI_RW(u8data){u8i;SPI_SCK_LOW;//先將時(shí)鐘線拉低for(i=0;i<8;i++){if((data&0x80)==0x80)//從高位發(fā)送{SPI_MOSI_HIGH;}else{SPI_MOSI_LOW;}SPI_SCK_HIGH;//將時(shí)鐘線拉高,在時(shí)鐘上升沿,數(shù)據(jù)發(fā)送到從設(shè)備data<<=1;if(SPI_MISO_READ)//讀取從設(shè)備發(fā)射的數(shù)據(jù){data"=0x01;}SPI_SCK_LOW;//在下降沿?cái)?shù)據(jù)被讀取到主機(jī)}returndata;//返回讀取到的數(shù)據(jù)}1234567891011121314151617181920212223242526272829
寫寄存器操作:`
u8 SPI_Moni_Write_Reg(u8 Reg,u8 data)
{
u8 states;
SPI_CS_LOW;//先將CSN拉低states=SPI_RW(Reg);//寫入寄存器的地址,即圖中的Cn位,并讀取狀態(tài)位SPI_RW(data);//要寫入的數(shù)據(jù)SPI_CS_HIGH;returnstates;
}
讀寄存器操作:u8SPI_Moni_Read_Reg(u8Reg){u8data;SPI_CS_LOW;SPI_RW(Reg);//先寫入寄存器的地址data=SPI_RW(0);//通過寫入無效數(shù)據(jù)0,將從設(shè)備上的數(shù)據(jù)擠出來SPI_CS_HIGH;returndata;}接下來就是寫緩沖區(qū)、讀緩沖區(qū)函數(shù)了:u8SPI_Moni_Write_Buf(u8Reg,u8*Buf,u8len){u8states;SPI_CS_LOW;states=SPI_RW(Reg);while(len>0){SPI_RW(*Buf);Buf++;len--;}SPI_CS_HIGH;returnstates;}u8SPI_Moni_Read_Buf(u8Reg,u8*Buf,u8len){u8states;SPI_CS_LOW;states=SPI_RW(Reg);while(len>0){*Buf=SPI_RW(0);Buf++;len--;}SPI_CS_HIGH;returnstates;}