嵌入式SPI与IIC

SPI通信

 判断同步异步:有时钟线---->同步

判断串并:一个方向上的数据线只有一条---->串

判断方向:有一根用于收,有一根用于发---->全双工

 1.SPI总线介绍

SPI(Serial Peripheral Interface, 串行外设接口 )是一种 同步串行通信技术 ,Motorola 首先提出的 全双工三线/四线同步串行外围接口 采用 主从模式架构
  • 时钟由Master控制(也就是用的谁的时钟谁就是主人),在时钟移位脉冲下,数据按传输,高位在前,低位在后
  • SPI接口有2根单向数据线,为全双工通信。
  • 注意:串口默认低位先行,SPI默认高位先行
  • SPI总线被广泛地使用在FLASH、ADC、LCD等设备与MCU间,要求通讯速率较高的场合。

SPI通信特点:

(1)一主多从

(2)每一个从设备都有一个独立的片选线

(3)主设备与从设备之间是全双工通信

(4)只有主机能发送时钟信号

 2、SPI总线物理(拓扑结构)

SPI总共有4根总线,分别是:

设备选择线、时钟线、串行输出数据线、串行输入数据线。

M : Master     O : Output    S : Slave    I : Input

(1)MOSI:主器件数据输出,从器件数据输入

(2)MISO:主器件数据输入,从器件数据输出

(3)SCLK :时钟信号,由主器件产生

(4)/SS:从器件使能信号,由主器件控制(片选)

三线制:SCK、MOSI、MISO (一主一从)

四线制:SS、SCK、MOSI、MISO (一主多从)

 3、通信协议

片选:选中---->高电平被拉为低电平        取消选中----->低电平拉高为高电平

总结:对于输出:

主机:设置成推挽输出

被选中的从机:设置成推挽输出

未被选中的从机:设置成高阻态

起始信号: NSS信号线由高变低 ( NSS是片选信号,使能信号 )

结束信号:NSS信号由低变高,是SPI通讯的停止信号

数据传输:SPI通信以字节为单位进行数据传输,每个字节的最高有效位(MSB)先传输,然后是次高有效位,依此类推,直到最低有效位(LSB)传输完毕(高位优先传输)。在数据传输过程中,每次接收到的数据必须在下次数据传输前被采样,否则可能会导致数据丢失或SPI模块失效。

触发:是主机把信号发送到MOSI的信号线上;(也就是数据线上信号发生跳变的地方)

采样:是从机从MOSI的信号线上去获取数据。(数据线上信号平稳段)

通信流程:

通信开始时,

(1)主设备先选择要进行通信的从设备,将SS(或CS)信号置为低电平,表示选择该从设备。

(2)主设备开始发送时钟信号(SCK),从设备根据时钟信号来接收和发送数据。

(3)主设备通过MOSI线向从设备发送数据,同时通过MISO线接收从设备发送的数据。(4)数据传输结束后,主设备将SS(或CS)信号置为高电平,表示通信结束。

字节交换原理

基于位交换,位交换分为两部分:移出 -->移位寄存器内整体前移一位 -->移入

移出:就是把当前移位寄存器的最高位写到信号线上,然后整体往左移动一位

移入(采样):读取信号线的状态,然后把读到的状态放到寄存器的最低位

移入 主机和从机同时进行

移出 主机和从机同时进行

移入和移出的时机是由时钟线控制约定的,约定好第几个边沿一起移出,第几个边沿一起移入。

4、SPI四种通信模式

时钟极性CPOL : 设置时钟空闲时的电平

当CPOL = 0 ,SCK引脚在空闲状态保持低电平;

当CPOL = 1 ,SCK引脚在空闲状态保持高电平。

时钟相位CPHA :设置数据采样(移入)时的时钟沿

当 CPHA=0 时,MOSI或 MISO 数据线上的信号将会在 SCK时钟线的奇数边沿被采样

当 CPHA=1时, MOSI或 MISO 数据线上的信号将会在 SCK时钟线的偶数边沿被采样

注意:边沿编号是从1开始

 模式0:


模式1:


模式2:


模式3:

注意:对模式0和模式2而言,由于要在奇数边沿进行数据移入,也就是SCLK第一个边沿到来时就要进行数据的移入了,因此,要在被选中之后(SS变低电平后),立刻就进行数据的移出,这样才能保证SCLK第一个边沿到来时,可以进行数据的移入。

例:

SPI的使用:

(1)使用硬件SPI(即使用STM32提供的SPI外设)

实验器具:

共阴极数码管

        


74HC595芯片:

74HC595是一款 8位 串行输入 并行输出的位移寄存器,在本次项目中,使用其将SPI串行传递过来的数据并行发送给对应数码管与显示位。SER为数据输入引脚

引脚介绍:

14脚:DS(SER),串行数据输入引脚

13脚:OE,输出使能控制脚,它是低电才使能输出,所以接GND

12脚:RCK(STCP),存储寄存器时钟输入引脚。上升沿时,数据从移位寄存器转存到存储寄存器

                                                

11脚:SCK(SHCP),移位寄存器时钟引脚,上升沿时,移位寄存器中的bit 数据整体后移,并接受新的bit(从SER输入)。注意:高位先行(也就是最高位会在最底下,最低位在最上面)

10脚:MR,低电平时,清空移位寄存器中已有的bit数据,一般不用,接 高电平即可。

9 脚 :串行数据出口引脚。当移位寄存器中的数据多于8bit时,会把已有的bit“挤出去”,就是从这里出去的。用于595的级联。

Q0~Q7:并行输出引脚

引用:  ​​​​​​一文搞懂74HC595芯片(附使用方法)-CSDN博客


MX配置:

实验代码:

(2)使用软件SPI(不使用SPI外设)

那么SPI外设都帮我做了什么工作呢?也就是说比起使用SPI外设时,我们要多做哪些操作呢?

        

   使用SPI外设时,我们要做的操作:
    
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_12,0);	
    uint8_t buf[2]={0x01,0x66};
	HAL_SPI_Transmit(&hspi2,buf,2,10);	
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_12,1);	

  -----起别名---->      

不使用SPI外设时:

    HAL_GPIO_WritePin(GPIOB, SPI2_NSS_Pin, 0);

    uint8_t Bit=0x01;
    uint8_t Seg=0x66;
	for(int i=0;i<8;i++)
	{
		HAL_GPIO_WritePin(GPIOB,SPI2_SCK_Pin,0);
		HAL_GPIO_WritePin(GPIOB, SPI2_MOSI_Pin, (Bit & 0x80) ? 1 : 0);
		HAL_GPIO_WritePin(GPIOB,SPI2_SCK_Pin,1);
	     Bit<<=1;  
		HAL_Delay(1);
	}	
	for(int i=0;i<8;i++)
	{
		HAL_GPIO_WritePin(GPIOB,SPI2_SCK_Pin,0);
		HAL_GPIO_WritePin(GPIOB, SPI2_MOSI_Pin, (Seg & 0x80) ? 1 : 0);
		HAL_GPIO_WritePin(GPIOB,SPI2_SCK_Pin,1);
	  Seg<<=1;
		HAL_Delay(1);
	}		
 
        HAL_Delay(1);
		HAL_GPIO_WritePin(GPIOB, SPI2_NSS_Pin, 1);

 对比:

总结:我们需要自己控制时钟信号

需要自己一位一位写入数据(让哪个数码管显示以及显示什么,也就是红框框里的部分)

硬件资源充足且对性能要求较高的情况下,推荐使用硬件SPI

硬件资源有限或需要特殊配置时,可以考虑使用软件SPI

IIC通信

1.介绍

IIC(Inter-Integrated Circuit)是一个 多主从 串行 总线,又叫I2C,是由 飞利浦 公司发明的通讯总线,属于 半双工同步 传输类型总线。IIC总线是非常常见的数据总线,仅仅使用两条线就能完成多机通讯,一条SCL时钟线,另外一条双向数据线SDA。不同的器件,都是并联接在这两条线上,I2C总线上的每个设备都自己一个唯一的地址,来确保不同设备之间访问的准确性。

SDA(Serial data)是数据线,D代表Data也就是数据,Send Data 也就是用来传输数据的

SCL(Serial clock line)是时钟线,C代表Clock 也就是时钟 也就是控制数据发送的时序的

多主从的同步串行半双工

  1. 当主机没有选择任何从机时,每个从机的SDA口都是输入模式
  2. 当主机选择完从机,即发送完了地址和操作位时,此时所有未被选中的从机的SDA口配置为高阻态,被选择的从机在读取数据时为输入模式,在发送确认位或者数据时SDA口为输出模式。也就是说,只要是输出,那就要配置为开漏。(与SPI不同,SPI主机要输出时始终是推挽,从机平常是开漏的高阻态,要输出时会变为推挽)IIC省去了推挽和开漏高阻态不断转换的麻烦
  3. 当主机结束通信,所有的从机的SDA口配置为输入模式

为什么I2C需要使用上拉电阻?

  1. 总线空闲的时候,SDA和SCL都是高电平。当其中一个设备拉低总线,整条线就全是低电平,器件与器件之间变为"与"关系。
  2. 为了避免总线信号收到从设备的干扰,各设备连接到总线的输出端时必须是漏极开路(OD)输出,即高阻态,无法主动输出高电平,需要外部上拉电阻才可以获得高电平。

2、IIC特点

通常我们为了方便把IIC设备分为主设备和从设备,基本上谁控制时钟线(控制SCL的电平高低变换)谁就是主设备

  • IIC主设备功能:主要产生时钟,产生起始信号和停止信号
  • IIC从设备功能:可编程的IIC地址检测,停止位检测
  • IIC的一个优点是它支持多主控(multimastering),其中任何一个能够进行发送和接收的设备都可以成为主总线。一个主控能够控制信号的传输和时钟频率。当然,在任何时间点上只能有一个主控。
  • 支持不同速率的通讯速度,标准速度(最高速度100kHZ), 快速(最高400kHZ),比uart高,比spi低
  • SCL和SDA都需要接上拉电阻 (大小由速度和容性负载决定一般在3.3K-10K之间) 保证数据的稳定性,减少干扰。
  • IIC是半双工,而不是全双工 ,同一时间只可以单向通信,IIC协议首先是发送从机硬件地址,然后发送命令,再发送数据/寄存器编号或者读取数据。IIC协议可以多字节连续读写数据。
  • 各设备连接到总线的输出端时必须是漏极开路(OD)输出或集电极开路(OC)输出。

2.1 时序图分析

起始信号与终止信号

  1. SCL线为高电平期间,SDA线由高电平向低电平的变化表示起始信号;
  2. SCL线为高电平期间,SDA线由低电平向高电平的变化表示终止信号;
  3. 起始和终止信号都是由主机发出,起始信号产生后,总线就处于占用的态;
  4. 终止信号产生后,总线就处于空闲态。

数据传输时序

  1. I2C总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定; 只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。
  2. SCL低电平期间,发送器向数据线上写入数据,因此SDA高低电平转换

      在SCL高电平期间,接收器从数据线上读取数据,因此必须保持SDA上的电平稳定

     3.最终完成一个时钟周期内,发送器发生一个bit位数据,接收器接收一个bit位数据。

        总结:SCL是高电平时,若SDA发生变化,必定是起始信号或者终止信号;若SDA保持稳定,是在读数据,此时不允许SDA发生变化;SCL为低电平时,是发送数据,允许SDA有变化


字节传输和应答信号

  1. “8+1”   每一个字节必须保证是8位长度。数据传送时,先传送最高位(MSB),每一个被传送的字节后面都必须跟随一位应答位(即一帧共有9位)。
  2. 在第9个时钟周期的低电平期间,接收器向数据线上写入数据。
  3. 在第9个时钟周期的高电平期间,发送器从数据线上读取数据。
  4. 如果读到的是低电平信号,表示应答信号。
  5. 如果读到的是高电平信号,表示非应答信号。

IIC寻址

  1. I2C总线上传送的数据信号是广义的,既包括地址信号,又包括真正的数据信号。
  2. 主机在起始信号后必须传送一个从机的地址(7位)第8位是数据的传送方向位(R/W),用“0”表示主机发送数据(W),“1”表示主机接收数据(R)。                    补充:因为从机地址只有7位,那么最大寻址范围是0~2^7-1(127),也就是说,最多可接入的从机数量为128个。
  3. 总线上的每个从机都将这7位地址码与自己的地址进行比较,如果相同,则认为自己被主机寻址,根据R/W位将自己定为发送器或接收器。

主机给从机发送一个字节

问题1:为什么要发送寄存器地址?

因为不论是读还是写,我们都需要明确告诉从机是要对哪个地址的数据进行操作。写操作会让从机产生一个指针指向主机发来的寄存器地址。

主机给从机发送多个字节

问题2:主机连续向从机发多个数据,从机会做出怎样的操作?

从机会将数据存入指针指向的地址,并将指针+1,然后给主机回复一个ACK,不断重复此操作,直到收到主机的停止信号。

主机从从机接收一个字节

问题3:为什么主机读数据之前还要发一次写信号??

因为只有写操作才会产生指针。

问题4:为什么发从机地址+R之前还要发一次开始信号(S)呢 ??

因为若过不加S,从机会认为主机发来的  从机地址+R  是要写入寄存器的数据,而不是一个命令,所以需要一个S来提醒从机,这不是数据,而是主机要进行读操作

主机从从机接收多个字节

总结:不管是读还是写操作,都需要产生指针,而只有写操作才能产生指针。

3、IIC寄存器

 接收数据寄存器:

发送数据寄存器:

4、温湿度传感器SHT20

4.1 简介

SHT20 温湿度传感器是一种数字式温湿度传感器,它采用超薄膜式湿度传感器和热敏电阻式温度传感器,在测量环境温度和湿度方面具有高精度和可靠性。

SHT20 传感器使用 I2C 总线接口进行数据通信,它能够快速、准确地测量环境的温度和相对湿度。

4.2 接口介绍

推荐电压:

4.3 通信流程

(1) 起始和终止时序
SHT20 采用标准的 I2C 协议进行通讯,每个传输序列都以 Start 状态作为开始并以 Stop 状态作为结束。

启动传输状态: 当 SCL 为高电平时,SDA 由高电平转换为低电平:

停止传输状态: 当 SCL 高电平时,SDA 线上从低电平转换为高电平:

(2)找IIC设备地址

(3)两种工作模式下的通信时序
保持主机模式(hold master)
SHT20会拿到SCL控制权并将SCL接地(拉成低电平),即此时无时钟信号的驱动,又由于IIC是同步通信,想通信必须依赖时钟信号的驱动,所以,此时主机无法实现与其他主机的通信。

非保持主机模式(no hold master)

主机仍可以与其他从机通信

注意:
 由正常的通信时序可知,发送完从机地址后,还需要发送寄存器地址,在SHT20时序图中,它发送完从机地址后,发送的是指令,也就是说,这一个字节的数据,既是寄存器地址也是指令,即执行完指令后获得的数据放到这个地址中。

UART与 SPI 与IIC对比

UART

SPI

IIC

同步异步

异步

同步

同步

串行并行

串行

串行

串行

方向

全双工

全双工

半双工

对应关系

一对一

一主多从

多主从

速率

    最慢

取决于波特率,常用的有9600bps(1.2KB/s)和115200bps(14.4KB/s)

  最快

约5.9MB/s,高于IIC

    中间

最快525KB/s

接线

接线简单

接线复杂

三线或四线制

接线较复杂

两线制

哪位先行

低位先行

高位先行

高位先行

应用场景

需要点对点通信,数据传输速率要求较低的场合

串口调试

需要高速数据传输、要求实时响应的场合

屏幕刷新高速ADC

常用于连接多个低速外设的场合

温湿度

 1)三线或四线制

        三线:MOSI、MISO、 SCLK

        四线:MOSI、MISO SCLK、 SS

      两线制    

       SCL、SDA

2)快慢原因

UART最慢因为异步异步往往同步;SPIIIC都是同步IIC原因是它的通信协议要求“8+1”模式需要ACK

 LCD屏幕

屏幕显示原理:

ILI9341(显示驱动芯片)

  1. ILI9341是一个支持分辨率为240RGBx320点阵的a-TFT LCD 的262144(2^18)色单片驱动器。这个单片驱动器包含了一个720通道的源极驱动器(source driver),一个320通道的栅极驱动器(gate driver),172800字节的GRAM用于显示240RGB x 320分辨率的图片数据,一套电源支持电路。
  2. ILI9341提供8位/9位/16位/18位的并行MCU数据总线,6位/16位/18位RGB接口数据总线以及3或4线SPI接口(serial peripheral interface)。通过窗口地址函数,显示区域被指定在GRAM内。这个指定的窗口区域可以被有选择地更新,因此显示区域能够同时被显示在静态图像的区域内。
  3. ILI9341的IO接口电压工作于1.65V-3.3V。一种合并的电压跟随电路,用以产生驱动液晶显示器的电压电平。ILI9341支持full color ,8-color显示模式,支持由软件控制的精确电源睡眠模式。这些功能使ILI9341成为类似于移动电话,小电话,MP3需要电池长效工作的中等或小尺寸便携产品的理想驱动器。
配置CubeMX

时钟速度调高,保证SPI速度为几十M

引脚输出速度调到最高

注意:LCD要加驱动文件

 图片显示:

void LCD_Picture(unsigned char *image);

功能:显示图片

参数为一个数组,通过来获取存有数组的.h文件

字符显示:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值