SPI 访问从设备通讯流(字节流设置与一般化方法)

概述

本文通过分析SPI主从通讯的特点,总结出一套访问从设备的一般化方法。

了解更多SPI可访问S32K1专栏:
NXP S32K1 SPI模块
NXP S32K1 SPI模块Driver使用
SPI时钟极性、相位设置
SPI实例之C++实现EEPROM访问

常见的SPI从设备有EEPROM、FLASH、收发器、转换器、通讯模块等,在片选信号有效后,在主机时钟线的驱使下,主机输出数据或者主机接收至从机。

Master Write

对于主机输出数据,亦从机接收数据(配置从机、写数据到从机的场景),主机需指明写数据到从机的哪里(地址、寄存器),写入的数据,甚至在“地址”区域需要搭配命令来指明这是一个写操作,或者像IIC一样,通过LSB的两种状态来指定操作。

Master Read

对于主机接收数据,亦从机输出数据,主机在本次通讯六中指明在从机的哪里(地址)去读取数据,只有主机告诉从机了这个地址,从机协议解析(处理器)模块才能将该位置的数据通过SPI数据流的方式输出。

一般化

由此从主机角度来看,SPI通讯流(字节流)有两部分组成:hdr+buff。
hdr: 头部,可能是Cmd和/或Reg+Addr,其割断的长度在不同的从机中也各不相同,可能是1Byte,也可能是2Bytes。
buff:数据缓冲区,rxBuf和txBuf,即使在主机输出数据的情况下,从机同样会移位输出输出到从机的接受线,反之亦然。

示例代码

bool EEPROM::ReadBytes(uint16_t addr, uint8_t *data, uint16_t len)
{
	bool rtv = false;
	if(data && (len>0))
	{
        uint8_t *pTx = new uint8_t[len+EE_LEN_HDR];
		uint8_t *pRx = new uint8_t[len+EE_LEN_HDR];

		if(pTx && pRx)
		{
			*(pTx+0) = EE_CMD_READ;
			*(pTx+1) = EE_GET_ADD_H(addr);
			*(pTx+2) = EE_GET_ADD_L(addr);

			if(STATUS_SUCCESS == LPSPI_DRV_MasterTransferBlocking(EE_SPI, pTx, pRx, len+EE_LEN_HDR, EE_TIME_OUT))
			{
				memcpy((uint8_t*)data,(uint8_t*)(pRx+EE_LEN_HDR),len);
				rtv = true;
			}
			else
			{
				rtv = false;
			}
		}
		else
		{
			rtv = false;
		}
		
		delete pTx;pTx = NULL;
		delete pRx;pRx = NULL;
	}

	return rtv;
}

结语

了解更多SPI可访问S32K1专栏:
NXP S32K1 SPI模块
NXP S32K1 SPI模块Driver使用
SPI时钟极性、相位设置
SPI实例之C++实现EEPROM访问

上一篇:2022.2.19测试考核


下一篇:Servlet 入门 (第一章)