SPI(STM32学习笔记)

SPI通信简介

·SPI(Serial Peripheral Interface)是由Motorola公司开发的一种通用数据总线

·四根通信线:SCK(Serial Clock)、MOSl(Master Output Slave Input)、MISO(Master Output Slave Input)、SS(Slave Select)

·同步,全双工

·支持总线挂载多设备(一主多从)

(本节使用STM32的硬件SPI外设)


SPI时序

本节使用SPI模式0 

SCK默认低电平,当SS第一个下降沿的时候,MOSI和MISO移出数据,在SCK的上升沿移入数据,如此循环八次,便交换一个字节,所以SPI通信其实就是交换数据。

见上图,主机想要给从机发送0xAA,交换一个字节后,主机接收到的是0x55,从机则接收到0xAA,我们如果只想接收数据,就随便发送一个数据给从机;只想发送数据实现某种功能,那么从机交换过来的数据我们可以不读。


本节演示SPI读写W25Q64


SPI硬件外设


 配置SPI基本结构


初始化配置模板

void MySPI_Init(void)
{
	//配置成SPI模式0
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1,ENABLE);//SPI1是APB2的外设
	//PA4配置为推挽输出
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	//配置SCK和MOSI为复用推挽输出
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5|GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	//配置MISO为上拉输入模式
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	//初始化SPI
	SPI_InitTypeDef SPI_InitStructure;
	SPI_InitStructure.SPI_Mode=SPI_Mode_Master;//SPI模式
	SPI_InitStructure.SPI_Direction=SPI_Direction_2Lines_FullDuplex;//选择双线全双工
	SPI_InitStructure.SPI_DataSize=SPI_DataSize_8b;//8位数据帧
	SPI_InitStructure.SPI_FirstBit=SPI_FirstBit_MSB;//高位先行
	SPI_InitStructure.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_128;//波特率分频器
	SPI_InitStructure.SPI_CPOL=SPI_CPOL_Low;//SCK默认低电平
	SPI_InitStructure.SPI_CPHA=SPI_CPHA_1Edge;//相当于选择CPHA为0,第一个边缘采样(移入)
	SPI_InitStructure.SPI_NSS=SPI_NSS_Soft;//选择软件模拟NSS引脚
	SPI_InitStructure.SPI_CRCPolynomial=7;//CRC校验,默认为7
	SPI_Init(SPI1,&SPI_InitStructure);
	
	SPI_Cmd(SPI1,ENABLE);
}

SPI1的SS对应PA4,SCK对应PA5,MISO对应PA6,MOSI对应PA7

片选引脚SS用软件模拟,所以配置为通用推挽输出;

SCK和MOSI要交由片上外设控制,所以配置为复用推挽输出;

MISO是输入端,所以配置为普通的上拉输入;

配置SPI结构体一般都是按照上面的参数来配置,SPI不同的模式差别也就在于时钟的相位,是第几个边沿采样的区别,本质上没有区别,这里配置成模式0;

最后要严谨一点的话,在初始化的最后还要将SS默认设置为高电平。

最后封装常用的起始位,停止位,交换数据函数即可:

void MySPI_W_SS(uint8_t BitValue)//置SS电平高低
{
	GPIO_WriteBit(GPIOA,GPIO_Pin_4,(BitAction)BitValue);
}

void MySPI_Start(void)//起始函数
{
	MySPI_W_SS(0);
}

void MySPI_Stop(void)//终止函数
{
	MySPI_W_SS(1);
}

uint8_t MySPI_SwapByte(uint8_t ByteSend)//交换数据
{
	//TXE为1,TDR寄存器为空,表示可以发送数据
	while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)!=SET);
	SPI_I2S_SendData(SPI1,ByteSend);//写DR会清除标志位
	
	//等待RENE为1,RDR寄存器非空,表示可以读取接收到的数据
	while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE)!=SET);
	return SPI_I2S_ReceiveData(SPI1);//读DR同理
}

封装交换数据的函数时,可以参考下图

具体要怎么使用这些函数还得看SPI硬件外设的读写操作是怎么样的,不同的芯片用法也不同。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sakabu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值