首页 > 编程知识 正文

总线,spi总线和i2c总线的区别

时间:2023-05-03 16:17:58 阅读:148271 作者:4459

摘要串行外设接口(SPI )串行外设接口是一种高速、全双工、同步的通信总线。

SPI接口主要应用于EEPROM、FLASH、实时时钟、AD转换器、以及数字信号处理器和数字信号解码器之间。

硬件链路SPI的通信原理很简单,是主从工作模式,该模式一般有一个主机+一个从机 或者 一个主机+多个从机,一般采用四条线进行通信。 (实际上即使有3个也可以进行单向传输时)、MOSI )、MISO )、SCK )、CS )芯片选择)。

MOSI:主输出、从输入(master output slave input );MISO:主机输入、从站输出(master input slave output );SCLK:时钟信号,由主机设备产生; 3358www.Sina.com/:芯片选择信号是从主机发送的,控制与哪个从机通信(CS); 其他制造商可能遵循其他命名约定,但最终都指向同一个意思。 以下是常用术语;

miSO:SIMO、DOUT、DO、SDO或so (主机端); MOSI:xfdxy、DIN、DI、SDI或SI (主机端); cs :可以是ce、NSS或SSEL; sclk :也可以是sck;通常是低电平有效信号

根据谁输出SCLK同步时钟和SS片,输出目标被定义为主机;

总线上只有一个从站时,从站的CS (芯片选择)脚可以直接接地。 这样,从站始终处于选中状态,可以节省一个IO。

SPI协议分析数据交换通信方式

主机和从机都有串行移位寄存器,主机通过向其SPI串行寄存器写入字节来开始一次传输。 寄存器通过MOSI信号线向从站传输字节,从站也将自己的移位寄存器的内容通过MISO信号线返回主机。 这样就交换了两个移位寄存器的内容。如何区分主机还是从机

如果外设的写操作和读操作是同步完成的。

如果主机请求只进行写操作,主机只需忽略接收到的字节,则必须在读取从机的一个字节上开始从设备传输。

时钟频率SPI总线上的主机必须在通信开始时配置和生成适当的时钟信号。

主设备配置SPI接口时钟必须位于发送一个空字节

主设备端的从设备的时钟要求

在正确设置时钟的极性和相位之前,数据不会正确发送和接收。 因此,必须根据从属设备的SPI接口定时或Spec文档中的说明,正确设置主设备的时钟。

时钟极性CKP/CPOL时钟极性,在时钟为空闲状态时,用于设定时钟总线是高还是低;

CKP=0:时钟空闲IDLE为低电平0;

CKP=1:时钟空闲IDLE为高电平1;

时钟相位CKE/CPHA时钟相位/边沿,即数据收集时时钟信号的最初的转变边沿或者第2个转变边沿;

CKE=0)在时钟信号SCK第一个跳跃沿(上升沿或者下降沿)被采样;

CKE=1)在时钟信号SCK第2个跳跃沿(上升沿或者下降沿)被采样;

SPI两种工作模式SPI MODE极性CPOL相位cpha0[ 00 ] 001 [ 01 ] 012 [ 10 ] 103 [ 11 ] 11示意图:

蓝线是SCK时钟信号,黑线是对数据进行采样的时刻

stm32 spi初始化过程设置SPI的模式(主模式或从模式)。 设置SPI的数据大小(8位或16位帧格式); 时钟极性设置:串行同步时钟空闲(高电平或低电平); 时钟相位设置:数据采样定时(第一个跳跃沿或第二个跳跃沿); 时钟频率的设定:波特率预分频值(STM32F429 SPI5初始化代码示例//SPI.h # ifndef _ SPI _ h # define _ _ SPI _ h # include ' sys.h ' extextef ) void SPI5_ set speed (u8spi _ baudrate prescaler; u8SPI5_readwritebyte(u8txdata; # endif//SPI.c # include ' SPI.h ' SPI _ handletypedefspi5_ handler; //SPI句柄//以下是SPI模块的初始化代码:主机模式//SPI端口初始化//此处为SPI5初始化voidSPI5_init(void ) { sp i5 _ handler.instance //sp5 SPI5_ handler.init.mode=SPI _ mode _ master;

//设置SPI工作模式,设置为主模式 SPI5_Handler.Init.Direction=SPI_DIRECTION_2LINES; //设置SPI单向或者双向的数据模式:SPI设置为双线模式 SPI5_Handler.Init.DataSize=SPI_DATASIZE_8BIT; //设置SPI的数据大小:SPI发送接收8位帧结构 SPI5_Handler.Init.CLKPolarity=SPI_POLARITY_HIGH; //串行同步时钟的空闲状态为高电平 SPI5_Handler.Init.CLKPhase=SPI_PHASE_2EDGE; //串行同步时钟的第二个跳变沿(上升或下降)数据被采样 SPI5_Handler.Init.NSS=SPI_NSS_SOFT; //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制 SPI5_Handler.Init.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_256;//定义波特率预分频的值:波特率预分频值为256 SPI5_Handler.Init.FirstBit=SPI_FIRSTBIT_MSB; //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始 SPI5_Handler.Init.TIMode=SPI_TIMODE_DISABLE; //关闭TI模式 SPI5_Handler.Init.CRCCalculation=SPI_CRCCALCULATION_DISABLE;//关闭硬件CRC校验 SPI5_Handler.Init.CRCPolynomial=7; //CRC值计算的多项式 HAL_SPI_Init(&SPI5_Handler);//初始化 __HAL_SPI_ENABLE(&SPI5_Handler); //使能SPI5 SPI5_ReadWriteByte(0Xff); //启动传输}//SPI5底层驱动,时钟使能,引脚配置//此函数会被HAL_SPI_Init()调用//hspi:SPI句柄void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi){ GPIO_InitTypeDef GPIO_Initure; __HAL_RCC_GPIOF_CLK_ENABLE(); //使能GPIOF时钟__HAL_RCC_GPIOH_CLK_ENABLE(); //使能GPIOH时钟 __HAL_RCC_SPI5_CLK_ENABLE(); //使能SPI5时钟 //PF8,9 GPIO_Initure.Pin=GPIO_PIN_8|GPIO_PIN_9; GPIO_Initure.Mode=GPIO_MODE_AF_PP; //复用推挽输出 GPIO_Initure.Pull=GPIO_PULLUP; //上拉 GPIO_Initure.Speed=GPIO_SPEED_FAST; //快速 GPIO_Initure.Alternate=GPIO_AF5_SPI5; //复用为SPI5 HAL_GPIO_Init(GPIOF,&GPIO_Initure);GPIO_Initure.Pin=GPIO_PIN_6;GPIO_Initure.Mode=GPIO_MODE_AF_PP; //复用推挽输出 GPIO_Initure.Pull=GPIO_PULLUP; //上拉 GPIO_Initure.Speed=GPIO_SPEED_FAST; //快速 GPIO_Initure.Alternate=GPIO_AF5_SPI5; //复用为SPI5 HAL_GPIO_Init(GPIOH,&GPIO_Initure);GPIO_Initure.Pin=GPIO_PIN_5;GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP; //推挽输出 GPIO_Initure.Pull=GPIO_PULLUP; //上拉 GPIO_Initure.Speed=GPIO_SPEED_FAST; //快速 HAL_GPIO_Init(GPIOH,&GPIO_Initure);}//SPI速度设置函数//SPI速度=fAPB1/分频系数//@ref SPI_BaudRate_Prescaler:SPI_BAUDRATEPRESCALER_2~SPI_BAUDRATEPRESCALER_2 256//fAPB1时钟一般为45Mhz:void SPI5_SetSpeed(u8 SPI_BaudRatePrescaler){ assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));//判断有效性 __HAL_SPI_DISABLE(&SPI5_Handler); //关闭SPI SPI5_Handler.Instance->CR1&=0XFFC7; //位3-5清零,用来设置波特率 SPI5_Handler.Instance->CR1|=SPI_BaudRatePrescaler;//设置SPI速度 __HAL_SPI_ENABLE(&SPI5_Handler); //使能SPI }//SPI5 读写一个字节//TxData:要写入的字节//返回值:读取到的字节u8 SPI5_ReadWriteByte(u8 TxData){ u8 Rxdata; HAL_SPI_TransmitReceive(&SPI5_Handler,&TxData,&Rxdata,1, 1000); return Rxdata; //返回收到的数据}

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。