基于STM32的模拟SPI通讯

1.SPI协议介绍

SPI协议是由摩托罗拉公式提出的通讯协议(Serial Peripheral Interface串行外设接口),是一种高速全双工的通信总线。
SPI通讯系统
SPI通讯使用3条总线(SCK、MOSI、MISO)和片选线CS。

  1. CS:片选线也叫NSS,当有多个SPI设备与SPI主机相连时,设备的其他信号线SCK、MOSI、MISO同时并联到相同的SPI总线上(无论由多少个从设备,都共用这3条总线),而每个从设备都有独立的CS片选线,有多少个从设备就有多少个CS线。SPI通讯无设备地址,当主机要选择从设备时,把该从设备的CS线拉低该从设备就会被选中,片选有效,主机就可以开始和从设备进行SPI通讯。于是SPI通讯以CS低电平为起始信号,高电平为结束信号
  2. SCK:时钟线,由主机产生并决定通讯速率。
  3. MOSI ( Master Output , Slave Input):主机输出从机输入
  4. MISO ( Master Input, Slave Output ):主机输入从机输出

2.SPI通讯时序

SPI通讯时序
NSS、SCK、MOSI由主机产生,MISO由从机产生,在SCK每个时钟周期MOSI、MISO传输一位数据,数据的输入输出是同时进行的。MSB先行或LSB先行无硬性规定。
MOSI和MISO在SCK上升沿期间变换,在SCK下降沿采样,SPI每次数据传输可以8位或16位为单位,每次传输的单位不受限制。

3.通讯模式

SPI通讯模式CPOLCPHA空闲时SCK时钟采样时刻
000低电平奇数边沿
101低电平偶数边沿
210高电平奇数边沿
311高电平偶数边沿

主机需要与从机工作在相同模式下才可以正常通讯。
SPI通讯模式
SPI通讯模式

代码

模拟SPI

模式0

为什么读写函数写在一起:SPI必须生成时钟脉冲才能将数据移出。产生时钟脉冲的唯一方式是发送字节。产生时钟脉冲,才能读取数据。

u8 Software_SPI_Write_Read(u8 data)
{
	u8 i;
	u8 redata;
	for(i=0;i<8;i++)
	{
		SPI_SCK_0();
		SysTick_Delay_Us(10);
		if(data & 0x80)
		{
			SPI_MOSI_1();
		}
		else
		{
			SPI_MOSI_0();
		}
		data <<= 1;
		SPI_SCK_1();
		SysTick_Delay_Us(10);		
		redata<<=1;
		if(SPI_MISO())
		{
			redata++;
		}
	}
	
	return redata;
}

代码要点:因为模式0是上升沿进行读取数据。所以在出现上升沿时MISO会出现有效数据,只需要连续8个周期将数据保存下来就能得到8位输入数据。

模式1

u8 Software_SPI_Write_Read(u8 data)
{
	u8 i;
	u8 redata;
	for(i=0;i<8;i++)
	{
		SPI_SCK_1();
		SysTick_Delay_Us(10);
		if(data & 0x80)
		{
			SPI_MOSI_1();
		}
		else
		{
			SPI_MOSI_0();
		}
		data <<= 1;
		SPI_SCK_0();
		SysTick_Delay_Us(10);		
		redata<<=1;
		if(SPI_MISO())
		{
			redata++;
		}
	}
	
	return redata;
}

模式2

u8 Software_SPI_Write_Read(u8 data)
{
	u8 i;
	u8 redata;
	for(i=0;i<8;i++)
	{
		SPI_SCK_1();
		SysTick_Delay_Us(10);
		if(data & 0x80)
		{
			SPI_MOSI_1();
		}
		else
		{
			SPI_MOSI_0();
		}
		data <<= 1;
		SPI_SCK_0();
		SysTick_Delay_Us(10);		
		redata<<=1;
		if(SPI_MISO())
		{
			redata++;
		}
	}
	
	return redata;
}

模式3

u8 Software_SPI_Write_Read(u8 data)
{
	u8 i;
	u8 redata;
	SPI_SCK_1();
	SysTick_Delay_Us(10);
	for(i=0;i<8;i++)
	{
		SPI_SCK_0();
		SysTick_Delay_Us(10);	
		if(data & 0x80)
		{
			SPI_MOSI_1();
		}
		else
		{
			SPI_MOSI_0();
		}
		data <<= 1;
		SPI_SCK_1();
		SysTick_Delay_Us(10);	
		redata<<=1;
		if(SPI_MISO())
		{
			redata++;
		}
	}
	return redata;
}

模式0和模式3经过实际验证读取W25Q64的Device ID读取成功,模式1和模式2等遇到支持这两种模式的设备时再进行验证,不过我认为应该是写对了的,毕竟几种模式的区别只有有效电平和读取时间不同,框架都一样。

W25Q64ID

串口调试助手
Github代码下载
完整工程下载
如有错误请提出

  • 27
    点赞
  • 104
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
### 回答1: STM32是一种由意法半导体公司生产的高性能微控制器,它可以通过模拟SPI协议与其他设备通信。SPI是串行外设接口协议,用于在微控制器和其他设备之间传输数据。 使用STM32模拟SPI协议,需要首先了解SPI协议的工作原理。SPI协议通过一个主设备和至少一个从设备之间进行通信。通信的数据是在时钟和数据线上同步传输的。在STM32中,模拟SPI协议的实现需要通过一些特定的寄存器和GPIO口进行配置。 通常情况下,STM32作为主设备时需要产生一个时钟信号来驱动从设备传输数据。在STM32的GPIO口中,需要将Clock、Master-out-slave-in、Master-in-slave-out、Slave-select四个口与从设备相连。每个GPIO口需要进行相应的配置,包括时钟极性、相位、主从模式、时钟速率等参数。 使用STM32模拟SPI协议通信的流程如下:首先,主设备通过拉低Slave-select口来选择一个从设备;然后,主设备生成时钟信号,并在时钟上上升沿或下降沿发送数据;从设备接收到时钟信号后,通过Master-in-slave-out口传送相应的数据;在传输完成后,主设备释放Slave-select口,通信结束。 总的来说,使用STM32模拟SPI协议进行通信需要进行一系列的配置和操作,但是可以实现快速、可靠的数据传输。 ### 回答2: STM32是一款高性能微控制器,支持多种通信协议,其中包括SPI协议。SPI协议是一种基于“主从”架构的串行通信协议,可以用于外设与主控器之间的通讯STM32模拟SPI协议使用GPIO模拟SPI通信,具有简单、快速、灵活等特点。在模拟SPI协议时,需要将不同GPIO端口设置为SPI通信引脚,包括如下四个信号线: 1. SCLK:时钟信号,由主控器产生,控制数据传输速度。 2. MOSI:数据输出信号,由主控器向从设备输出数据。 3. MISO:数据输入信号,从设备向主控器返回数据。 4. CS:片选信号,由主控器产生,选择与其通信的从设备。 在模拟SPI协议时,先拉低CS信号,向从设备发送命令和数据,等待从设备的响应,并读取从设备返回的数据通讯完成后释放CS信号。 模拟SPI协议需要通过软件编写SPI接口程序来实现,主控器需要控制时钟脉冲的频率和传输字节的数量等参数。可以通过编写SPI接口类库,使用STM32内部的SPI外设来实现模拟SPI协议,或者通过GPIO口位操作实现。 总之,STM32模拟SPI协议是一种简单易用、灵活、仅依赖于GPIO模拟SPI协议,可以快速实现与各种从设备的通信。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值