STM32模拟SPI的程序
来源:个人图书馆-myallmy    时间:2023-07-31 12:33:42


(资料图片仅供参考)

最近完成的一个项目因为SPI管脚被别的资源占用了,只能通过模拟SPI对存储器进行操作。最后测试发现模拟SPI的速度也很快,和硬件SPI相比感觉不到太大的差异。现将模拟SPI的程序分享如下:

管脚定义,大家可以根据需要自行修改,任何一个GPIO都可以模拟SPI

#define  SPI_WP_PIN          GPIO_Pin_6#define  SPI_WP_PORT         GPIOC#define  SPI_CS_PIN          GPIO_Pin_15#define  SPI_CS_PORT         GPIOA#define  SPI_CLK_PIN         GPIO_Pin_3#define  SPI_CLK_PORT        GPIOB#define  SPI_MOSI_PIN        GPIO_Pin_12#define  SPI_MOSI_PORT       GPIOC#define  SPI_MISO_PIN        GPIO_Pin_4#define  SPI_MISO_PORT       GPIOB#define  SPI_BASE SPI3#define  SPI_FLASH_CS_LOW()    GPIO_ResetBits(SPI_CS_PORT, SPI_CS_PIN)  /* Select SPI MEM1: ChipSelect pin low  */#define  SPI_FLASH_CS_HIGH()   GPIO_SetBits(SPI_CS_PORT, SPI_CS_PIN)    /* Deselect SPI MEM1: ChipSelect pin high */#define  SPI_FLASH_WP_LOW()    GPIO_ResetBits(SPI_WP_PORT, SPI_WP_PIN)  //PC4#define  SPI_FLASH_WP_HIGH()   GPIO_SetBits(SPI_WP_PORT, SPI_WP_PIN)    //PC4

模拟SPI MOSI MOSI CLK

//模拟MOSIvoid SPI_MOSI(unsigned char Status){if(Status)GPIO_WriteBit(SPI_MOSI_PORT,SPI_MOSI_PIN,Bit_SET);elseGPIO_WriteBit(SPI_MOSI_PORT,SPI_MOSI_PIN,Bit_RESET);}//模拟CLKvoid SPI_CLK(unsigned char Status){if(Status)GPIO_WriteBit(SPI_CLK_PORT,SPI_CLK_PIN,Bit_SET);elseGPIO_WriteBit(SPI_CLK_PORT,SPI_CLK_PIN,Bit_RESET);}//模拟MISOunsigned char SPI_MISO(void){if(GPIO_ReadInputDataBit(SPI_MISO_PORT,SPI_MISO_PIN))return 1;else return 0;}

SPI初始化

void gd25qxxInit(void){GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = SPI_MOSI_PIN; //PA5:SCK,PA7:MOSIGPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出GPIO_Init(SPI_MOSI_PORT, &GPIO_InitStructure);SPI_MOSI(1);GPIO_InitStructure.GPIO_Pin = SPI_CLK_PIN; //PA5:SCK,PA7:MOSIGPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出GPIO_Init(SPI_CLK_PORT, &GPIO_InitStructure);SPI_CLK(1);GPIO_InitStructure.GPIO_Pin = SPI_MISO_PIN ;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(SPI_MISO_PORT, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = SPI_CS_PIN;                             GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Init(SPI_CS_PORT, &GPIO_InitStructure);SPI_FLASH_CS_HIGH();GPIO_InitStructure.GPIO_Pin = SPI_WP_PIN;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Init(SPI_WP_PORT, &GPIO_InitStructure);SPI_FLASH_WP_HIGH();}

SPI数据输入输出

uint8_t gd25qxxSendByte(uint8_t byte){unsigned char i,Result = 0;;for(i=0;i<8;i++){if(byte & 0x80)SPI_MOSI(1);else SPI_MOSI(0);byte <<= 1;SPI_CLK(0);SPI_CLK(1);Result <<= 1;if(SPI_MISO()) Result |= 0x01;}SPI_CLK(0);return(Result);}

示例:

uint32_t gd25qxxReadID(void){  uint32_t Temp = 0, Temp0 = 0, Temp1 = 0, Temp2 = 0;  /* Select the FLASH: Chip Select low */  SPI_FLASH_CS_LOW();  /* Send "RDID " instruction */  gd25qxxSendByte(0x9F);  /* Read a byte from the FLASH */  Temp0 = gd25qxxSendByte(DUMMY_BYTE);  /* Read a byte from the FLASH */  Temp1 = gd25qxxSendByte(DUMMY_BYTE);  /* Read a byte from the FLASH */  Temp2 = gd25qxxSendByte(DUMMY_BYTE);  /* Deselect the FLASH: Chip Select high */  SPI_FLASH_CS_HIGH();  Temp = (Temp0 << 16) | (Temp1 << 8) | Temp2;  return Temp;}

关键词: