STM32模拟SPI的程序

本文介绍了在STM32平台上,由于SPI硬件资源被占用,如何通过模拟SPI实现对存储器的操作。博主分享了模拟SPI的代码,包括管脚定义、初始化、数据输入输出函数,并提供了读取存储器ID的示例。测试结果显示,模拟SPI的速度接近硬件SPI,可满足高速数据传输需求。
摘要由CSDN通过智能技术生成

最近完成的一个项目因为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

//模拟MOSI
void SPI_MOSI(unsigned char Status)
{
	if(Status)
		GPIO_WriteBit(SPI_MOSI_PORT,SPI_MOSI_PIN,Bit_SET);
	else
		GPIO_WriteBit(SPI_MOSI_PORT,SPI_MOSI_PIN,Bit_RESET);
}
//模拟CLK
void SPI_CLK(unsigned char Status)
{
	if(Status)
		GPIO_WriteBit(SPI_CLK_PORT,SPI_CLK_PIN,Bit_SET);
	else
		GPIO_WriteBit(SPI_CLK_PORT,SPI_CLK_PIN,Bit_RESET);
}
//模拟MISO
unsigned 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:MOSI
	GPIO_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:MOSI
	GPIO_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;
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值