1. SPI#
- 高速
- 全双工
- 同步
- 串行总线
-
SPI有4条线,分别是SCLK(时钟信号),MOSI(主设备输出,从设备输入),MISO(主设备输入,从设备输出),CS(片选信号)。由这四条线路可以看出来,是同步的全双工
-
四种工作模式
- Mode0:CPOL=0, CPHA=0,SCLK=0时处于空闲态,即低电平。数据采样在第一个边沿,数据发送在第二个边沿
- Mode1:CPOL=0,CPHA=1,SCLK=0时处于空闲态,即低电平。数据采样在第二个边沿,数据发送在第一个边沿
- Mode2:CPOL=1,CPHA=0,SCLK=1时处于空闲态,即高电平。数据采样在第一个边沿,数据发送在第二个边沿
- Mode3:CPOL=1,CPHA=1,SCLK=1时处于空闲态,即高电平,数据采样在第二个边沿,数据发送在第一个边沿
从机和主机必须工作在相同的模式,也就是说在SCLK时序同步时,二者可能同时发送数据,然后同时接受数据。
-
CS片选信号
SPI不需要指定从机地址,主机只需要拉低指定的片选信号就可以指定从机。
2. IIC#
同步半双工,带数据应答,支持总线挂载多设备,两条总线:SCL(时序总线),SDA(数据总线)
硬件I2C:STM32如果有I2C硬件模块可以直接使用,查手册找一下I2C挂载在何处,然后初始化I2C的各种属性。直接往数据寄存器中写入值发送然后直接从数据寄存器中读取数据。
软件I2C:可以使用软件函数的方式模拟I2C协议,初始化GPIO口,将一个口的输出作为SCL另一个作为SDA,然后根据I2C的时序特点在不同的时序阶段将数据放在SDA总线上,定时上拉和上拉SCL。
所有设备的SCL和SDA都接在一起,挂载在同一条总线上,SCL由主设备进行控制,SDA可以由主设备释放给从设备使用。设备的SCL和SDA都需要使用开漏输出模式加上拉电阻。在一主多从模式中也可以使用推挽输出模式,但是在多主多从有可能会造成多个主设备短路,所以在任何情况下都需要使用开漏输出模式。
时序特点:
1)基本时序单元
-
**产生起始条件:**SCL高电平期间,SDA从高电平切换到低电平
-
**产生终止条件:**SCL高电平期间,SDA从低电平切换到高电平
-
产生起始条件和终止条件都是由主机决定的。
-
**主机发送数据:**SCL低电平期间将一位数据放到SDA上后,主机将SCL提到高电平,此时SDA不允许有变化,从而让从机接收数据,高位先行。
-
**主机接收数据:**主机释放SDA将控制权交给从机,主机控制SCL,在低电平期间从机发送数据,在高电平期间主机接收数据
-
**发送应答:**在主机接收完一个字节后,在下一个时钟发送一位数据,数据0表示应答
-
**接收应答:**在主机发送给从机一个字节后,在下一个时钟发送一位数据给主机,主机此时要接受这个数据,数据0表示应答,数据1表示非应答
2)通信时序
- **指定地址写:**对于指定设备的指定寄存器写入数据。
第一个数据帧,七位地址**+一位读写位(0写1读),紧跟着就是应答位,从机此时应该给主机接受应答。第二个数据帧,可以是设备的内部寄存器地址,紧跟着应答位。接下来的帧就可以发送要写入的数据,每写入一个字节,设备的内部寄存器地址指针就会自动递增**。
再往后主机可以产生终止条件。
- **指定地址读:**对指定设备的指定寄存器写入数据。
第一个数据帧,七位地址**+一位读写位(此时写入),然后从机数据应答,第二个数据帧,指定设备的内部寄存器地址,然后从机应答,此时重新产生起始条件,第三个数据帧指定七位地址+**一个读写位(此时读入),第四个数据帧就是从机返回给主机的数据。每读取一个字节,设备内部寄存器地址的指针会自动递增。
最后主机产生终止条件。
10bit地址读写#
如果是10bit的从机地址,需要两个字节确定从机地址,第一个字节为11110 XX X,前面的11110是IIC协议中保留的特殊地址指令,后面XX是从机地址的前两位,(剩下的八位要在下一个字节中给出),最后一位依然是读写位。在第一个字节后前两位地址满足的从机都需要进行ACK应答。
主设备指定地址写,确定从机地址之后就可以接着发送其他数据进行写入。
主设备指定地址读,确定从机地址之后,接着发送寄存器地址,然后重新发送第一个字节重复起始信号并且改成读。
3. USART#
异步全双工,点对点通信,两个引脚TX和RX,分别用来发送数据和接收数据,点对点发送数据也就是TX接RX,RX接TX。
波特率是串口通信的速率。
时序特点:
空闲状态是高电平,每个时序单元的起始位是低电平来表示开始传输一个数据帧,停止位是一个高电平,也就是重新回到空闲状态。数据帧低位先行。在停止位之前,数据帧之后,可以选择性的添加一个校验位。
UART可以有奇偶校验。如果设置的是奇校验,并且原来的实际数据中有4个1,那么需要校验位也设置为1,从而有奇数个1。
如果数据出错了,那么校验位就能够看出来,1的数量是不正确的。但是这个奇偶校验只能检测出单个位的错误,如果同时有两个位错了,就无法进行检测了。而且没有纠错功能,因为不知道具体是哪个位置错了。
4. CAN#
CAN总线内容过多,暂时搁置。