嵌入式学习随笔二:基础通信协议——SPI协议

一.SPI简介

SPI协议(Serial Peripheral Interface)是摩托罗拉公司提出的通讯协议,即串行外围设备接口,是一种高速全双工的通信总线。它被广泛地使用在ADC、LCD 、Flash等设备与MCU之间的通讯,适用于要求通讯速率较高的场合。

1.SPI的物理层

SPI总线通常由4条总线组成,分别为SCK(时钟信号线),MOSI(主机发送从机接收线),MISO(主机接收从机发送线)和CS(从设备使能信号,有的地方叫NSS)。SPI不同于IIC,在协议层中没有从机设备寻址的功能,所以需要通过CS信号去控制从设备的选择。数据传输时也是采用小端模式

MOSI:主机输出从机输入,用于主设备向从设备发送数据;

MISO:主机输入从机输出,用于主设备接收来自从设备发送的数据;

SCK:数据时钟线,用于产生时钟信号

CS:设备使能信号,用于使能数据传输(一般为低电平有效)

2.SPI通信模式

通常对于从设备而言,其出厂时就已经配置好相应的通信模式,无法被改变,所以我们必须通过修改主机的程序对其通信模式进行配置,使而知一致才能进行通信,通过CPOL(时钟极性)和CPHA(时钟相位)来控制我们主设备的通信模式。四种模式分别为:

CPOL=0,表示当SCK=0时处于空闲态,所以有效状态就是SCK处于高电平时;

CPOL=1,表示当SCK=1时处于空闲态,所以有效状态就是SCK处于低电平时;

CPHA=0,表示数据采样是在第1个边沿,数据发送在第2个边沿;

CPHA=1,表示数据采样是在第2个边沿,数据发送在第1个边沿。

 CPOL表示,时钟线处于空闲态时的电平;CPHA表示,在时钟的哪一个状态进行数据采样和发送

以实际的写Flash的波形为例

主机写数据到从机

 

主机从从机读取数据

第一条为MOSI(输出态),第二条为MISO(输入态),第三条为SCK(输出态),第四条为CS(输出态)

从图中可以看出,和IIC协议不一样,SPI协议没有起始信号而停止信号,只有当CS处于低电平时,数据才能开始传输,配置为CPOL=0,CPHA=0,所以在空闲时SCK为低电平,在第一个边沿进行数据采集,时钟高电平时期数据保持稳定,第二个边沿发送数据

3.代码示例

/******************************************************//**
*  @brief		写一个字节数据
*  @param[in] 	wByte 写入的数据
*  @return 		NULL
*  @note
*********************************************************/
void WriteByte(u8 wByte)
{
	u8 i;

	FLASH_SI_OUT;        //MOSI设置为输出态
	FLASH_SCK_OUT;        //SCK设置为输出态

	for(i = 0; i < 8; i++)
	{
		FLASH_SCK_LOW;        //SCK变低,进行数据采样

		if(wByte & 0x80)
		{
			FLASH_SI_HIGH;      //改变SI数据线数据,写入从机
		}
		else
		{
			FLASH_SI_LOW;
		}

		wByte <<= 1;
		FLASH_SCK_HIGH;         //SCK变高,进行数据发送
	}

	FLASH_SCK_LOW;        //发送完一个字节,SCK处于空闲态
}
/******************************************************//**
*  @brief		读一个字节
*  @return 		NULL
*  @note
*********************************************************/
u8 ReadByte(void)
{
	u8 i, data = 0;

	FLASH_SO_IN;                //SO配置为输入用于接收数据
	FLASH_SCK_OUT;

	for(i = 0; i < 8; i++)
	{
		FLASH_SCK_LOW;            //准备采集数据
		data <<= 1;

		if(FLASH_SO)                //采集SO的数据
		{
			data |= 1;
		}

		FLASH_SCK_HIGH;            //接收数据
	}

	FLASH_SCK_LOW;            //SCK至于空闲态
	return data;
}

程序中没有加延时的原因是因为在11MHz的MCU主频下 执行多条汇编语句进行的延时,所以不用在额外使用延时函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值