[STM32]SPI通信中为什么不能ReceiveData和SendData直接读写数据

本文详细解释了STM32中使用I2C驱动W25Q128时,如何通过SwapByte函数处理SPI通信的帧数据格式,以及如何执行如ReadJEDECID命令的帧解析过程,强调了SPI通信的半双工特性。
摘要由CSDN通过智能技术生成

   问题:STM32硬件I2C驱动W25Q128时,指令的帧数据格式并不是通过ReceiveDataSendData直接读写数据,而是通过SwapByte函数实现的

SPI通信的流程

   主机发送数据的流程是->主机要发送的数据填入发送缓冲区->发送缓冲区非空,数据填入移位寄存器->主机移位寄存器的数据通过MOSI线移入从机移位寄存器,同时从机移位寄存器的数据通过MISO移入主机的移位寄存器(移位寄存器的数据交换)

   主机接收数据的流程是->从机要发送的数据填入发送缓冲区->发送缓冲区非空,数据填入移位寄存器->等待主机发送任意数据通常我们发送0xFF,因为数据手册中有些命令的帧数据格式必须发0xFF)->从机移位寄存器的数据通过MISO移入主机的移位寄存器,同时主机移位寄存器的数据通过MOSI线移入从机移位寄存器。

SPI通信的特点

   因为SPI没有读和写的概念,实际上的每一次通信都是交换数据。换句话说,你要是发一个数据必然会接收到一个数据,你要是想接收一个数据必须要发送一个数据。

   所以我们看不到ReceiveByte和SendByte直接读写数据,而是通过 先发送数据然后接受数据 封装的SwapByte(发送字节是在前面的)实现SPI通信

/**
  * 函    数:SPI交换传输一个字节,使用SPI模式0
  * 参    数:ByteSend 要发送的一个字节
  * 返 回 值:接收的一个字节
  */
uint8_t SPI_SwapByte(uint8_t ByteSend)
{
	while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) != SET);	//等待发送数据寄存器空
	
	SPI_I2S_SendData(SPI1, ByteSend);								//写入数据到发送数据寄存器,开始产生时序
	
	while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) != SET);	//等待接收数据寄存器非空
	
	return SPI_I2S_ReceiveData(SPI1);								//读取接收到的数据并返回
}

SPI命令帧的格式解析

    学习SPI通信的时候我感觉SPI通信某种意义上就是一个半双工通信,而不是全双工通信。

   发送数据时接收到的那个数据接受数据要发送的那个数据没有任何实际的意义

   下图是Read JEDEC ID (9Fh)命令的时序图

对应的SPI读取流程如下

     命令帧的数据格式我们只需要关注有效字节的发送和接收 

/**
  * 函    数:W25Q128读取ID号
  * 参    数:MID 工厂ID,使用输出参数的形式返回
  * 参    数:DID 设备ID,使用输出参数的形式返回
  * 返 回 值:无
  */
void W25Q128_ReadID(uint8_t *MID, uint16_t *DID)
{
    int MemoryID,CapacityID;
	SPI_Start();						     //SPI起始,内部就是拉低CS线
	SPI_SwapByte(0x9F);			             //交换发送读取ID的指令
	*MID = SPI_SwapByte(0xFF);	             //交换接收MID,通过输出参数返回
	MemoryID = SPI_SwapByte(0xFF);	         //交换接收DID高8位
	CapacityID = SPI_SwapByte(0XFF);	     //或上交换接收DID的低8位,通过输出参数返回
    *DID = MemoryID<<8+CapacityID
	SPI_Stop();								//SPI终止,拉高CS线
}

    注:1,为什么发送的无效字节是0xFF

数据手册中原话     11. The first dummy is M7-M0 should be set to FFh

因为数据手册上有几个命令的第一个dummy字节要求是0xFF,为了完全兼容所有命令,我们选择0xFF

   2,发送命令0X9F时我们并没有要SPI_SwapByte的返回值,也就是发送数据时接收到的那个数据,我们是把它当作无效字节丢掉的

   这样我们就完成了一个命令帧格式的解析

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值