STM32 SPI通信协议1——协议基本原理及管脚定义

发布时间:2024年01月12日

? SPI介绍? ? ?

????????SPI全称为Serial Peripheral interface,译为串行外围设备接口。SPI主要应用在EEPROM,FLASH,实时时钟,AD转换器,还有数字信号处理器和数字信号编码器之间。

? ? ? ? SPI是一种高速,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便。STM32也有SPI接口,SPI时钟最大可达18MHz支撑DMA,可以配置为SPI协议或者I2S(音频通信)协议。

SPI的内部简明图
  • MISO:

    • M(master)主机,S(slave)从机,I(input),O(output)由此可以看出,MISO就是从机Output,主机Input。
  • MOSI:

    • 由此类推,我们可以知道,MOSI就是主机Output,从机Input。
  • SCLK:

    • 因为SPI是同步通信,所以需要有个时钟线保证同步。
  • CS:

    • chip select片选信号线。

片选:动词,单片机学科词汇,可以理解成选片。举个例子,有很多芯片挂在同一总线上(像电脑里很多外设都是挂在总线上),但我们有时候需要对其中特定的某个芯片进行数据、地址或命令的独立传输,此时,我们需要有一个信号来告诉挂在总线上的芯片们,这些数据、地址是传给哪个芯片的。那这样的话,其他芯片就会对这些信号“漠不关心”,而目标芯片就知道这些数据是传给自己的从而做出反应。这个信号就叫做片选信号CS(chip select)或SS(slave?select)。片选这个词即由此而来,指通过设置跳线,利用与门或门非门的组合来决定到底是哪几部分进入工作状态。?

?由上图可以看出一个主机可以连接多个从机,并且通过SS(这里的SS就是刚刚所说的CS)来确认,我们使用的是哪个从机。

?SPI模式

? ? ? ?根据SPI时钟极性(CPOL)时钟相位(CPHA)配置的不同,分为四种SPI模式。

? ? ? ?时钟极性(CPOL)

????????时钟极性是指SPI通讯设备处于空闲状态时(也可以认为SPI通讯开始时,即CS线为低电平时),SCK信号线的电平信号。CPOL==0时,SCK在空闲状态时为低电平,CPOL==1时,则相反。

? ? ? ?时钟相位(CPHA)

????????时钟相位是指数据的采样的时刻,当CPHA==0时,MOSI或MISO数据线上的型号将会在SCK时钟线的第一个跳变沿(奇数,上升或下降)沿被采样。当CPHA==1时,数据线在SCK的第二个跳变沿(偶数,上升或下降)沿采样。

????????当CPHA==0时,MOSI或MISO数据线上的型号将会在SCK时钟线的第一个跳变沿(奇数,上升或下降)沿被采样。从上图可以看出,1,3,5,7为SCK的第一个跳变沿,看图就能分直观的看出为什么是“奇数,上升或下降”。即触发上升沿1,3,5,7。

同理:

????????当CPHA==1时,数据线在SCK的第二个跳变沿(偶数,上升或下降)沿采样。2,4,6,8为SCK的第二个跳变沿,即为“偶数,上升或下降”。即触发下降沿2,4,6,8。

同理:

????????当CPHA==0时触发下降沿1,3。

????????当CPHA==1时触发上升沿2,4。?

????????一般情况下我们使用32时会直接通过SPI配置SCK,MISO,MOSI,而不会去用SPI去配置NSS,因为常使用一主多从的模式(一个主机多个从机),为了更好的选择从机,会用GPIO去配置NSS,通过软件起到选择从机的作用。?

#include "bsp_spi.h"
void SPI1_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_SPI1,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
	//PA4:CS片选
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	//PA5:SCK时钟信号线
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	//PA6:MISO
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	//PA7:MOSI
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
}

文章来源:https://blog.csdn.net/m0_73671341/article/details/134755311
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。