嵌入式经典通信协议
USART/UART、IIC、SPI是嵌入式开发常用的几种通信协议,下面将对这几种协议做详细的介绍。
1.USART/UART
USART/UART均为常见的串口通信协议,前者(Universal synchronous asynchronous receiver transmitter 简称)是同步和异步收发器 ,后者(Universal asynchronous receiver transmitter 简称)是异步收发器。所以这里需要简单介绍一下同步通信与异步通信的区别,下图是一个8位字长,1个停止位的一个帧数据,其实每个数据帧之间存在“空闲位”。何为“空闲位”呢?即连续的高电平,而同步和异步是根据高电平持续的时长进行区分,若每个数据帧之间的空闲位时长相同则为同步,反之则为异步。根据上面的介绍,主机设备与从设备的收发同步方式也有区别,异步通信通过传送字符内的起始位来进行同步,而同步通信采用共用外部时钟来进行同步。
根据上图可知道串口通信的数据帧,包含起始位、数据位、校验位、以及停止位,在进行串口通信驱动程序编写时,需要了解这几个参数:波特率、停止位、数据位和校验位。
波特率:在串口通信中表示每秒钟传送的二进制码元的个数,单位是波特(Baud,symbol/s),例如波特率为115200时,表示串口每秒传送115200个bit的数据量。所以传送1个bit的时间等于1/115200秒,大约8.68us
起始位:起始位一般为1位,即维持一个比特的低电平。
数据位:可以设置为5至9位,根据传输数据决定,如果传输的内容为ASCII码,无校验位时,数据位设为8位。。
校验位:有无校验、偶检验和奇校验。主要统计数位比特为1的个数,这个只能进行一定范围内的检错,不能纠错。
停止位:支持多种停止位的配置:0.5、1、1.5和2个停止位。1个停止位:停止位位数的默认值;2个停止位:可用于常规USART模式、单线模式以及调制解调器模式;0.5个停止位:在智能卡模式下接收数据时使用;1.5个停止位:在智能卡模式下发送和接收数据时使用。
void uart_init(u32 bound){
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_InitStructure.USART_BaudRate = bound;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
USART_Cmd(USART1, ENABLE);
}
void USART1_IRQHandler(void)
{
unsigned char USART1_Res;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
USART1_Res =USART_ReceiveData(USART1);
}
2.IIC
IIC总线(Inter-Integrated Circuit)即集成电路总线,包含SDA(数据线)和SCL(时钟线),是一种简单、双向、二线制、同步串行总线。IIC总线是一个多向控制总线,多个器件(从机)可以同时挂载到一个主机控制的一条总线上。每个连接在总线上的设备都是通过唯一的地址和其他器件通信,主机和从机的角色可互换,可以根据谁控制时钟线(即控制SCL的电平高低变换)谁就是主设备 。主机就是负责整个系统的任务协调与分配,从机一般是通过接收主机的指令从而完成某些特定的任务,主机和从机之间通过总线连接,进行数据通讯。IIC的时序简化图如下,主要包含空闲段、启动信号(START)、数据位传输(DATA)、应答信号(ACK)、非应答信号(NACK)和停止信号(STOP),接下将进一步说明这几种信号。
启动信号(START):在SCL保持高电平期间,SDA由高电平被拉低。由主机发出。
void MPU_IIC_Start(void)
{
MPU_SDA_OUT();
MPU_IIC_SDA=1;
MPU_IIC_SCL=1;
MPU_IIC_Delay();
MPU_IIC_SDA=0;
MPU_IIC_Delay();
MPU_IIC_SCL=0;
}
数据位传输(DATA):在SCL保持高电平期间,SDA上的电平保持稳定,低电平为数据0、高电平为数据1。数据信号可由主机或从机发出。
void MPU_IIC_Send_Byte(u8 txd)
{
u8 t;
MPU_SDA_OUT();
MPU_IIC_SCL=0;
for(t=0;t<8;t++)
{
MPU_IIC_SDA=(txd&0x80)>>7;
txd<<=1;
MPU_IIC_SCL=1;
MPU_IIC_Delay();
MPU_IIC_SCL=0;
MPU_IIC_Delay();
}
}
应答信号(ACK):在SCL保持高电平期间,SDA保持低电平。IIC总线上所有数据都是以8位字节传送的,发送器每发送一个字节,就在第9个时钟脉冲期间释放SDA(高电平),由接收机机反馈一个应答信号(ACK)。
void MPU_IIC_Ack(void)
{
MPU_IIC_SCL=0;
MPU_SDA_OUT();
MPU_IIC_SDA=0;
MPU_IIC_Delay();
MPU_IIC_SCL=1;
MPU_IIC_Delay();
MPU_IIC_SCL=0;
}
非应答信号(NACK):在SCL保持高电平期间,SDA保持高电平。如果接收器是主机,则它在收到最后一个字节后,发送一个NACK,通知被控器结束数据发送,并释放SDA(高电平),以便主控器发送一个STOP。
void MPU_IIC_NAck(void)
{
MPU_IIC_SCL=0;
MPU_SDA_OUT();
MPU_IIC_SDA=1;
MPU_IIC_Delay();
MPU_IIC_SCL=1;
MPU_IIC_Delay();
MPU_IIC_SCL=0;
}
停止信号(STOP):在SCL保持高电平时间,SDA由低电平被释放(拉高)。由主机发出。
void MPU_IIC_Stop(void)
{
MPU_SDA_OUT();
MPU_IIC_SCL=0;
MPU_IIC_SDA=0;
MPU_IIC_Delay();
MPU_IIC_SCL=1;
MPU_IIC_SDA=1;
MPU_IIC_Delay();
}
IIC是半双工的通信,在介绍完时序之后,接下就是向从机读数据和写数据的步骤了。
主机向从机写数据步骤
- 主机发起一个启动信号(START)。
- 主机发送7bit从机地址+1bit读写选择位,1表示读、0表示写。
- 从机产生应答信号(ACK)。
- 主机发送8bit从机寄存器地址。
- 从机产生应答信号(ACK)。
- 主机发送一个字节数据。
- 从机产生应答信号(ACK)。
- 主机发送一个停止信号(STOP)。
主机从从机读数据步骤
- 主机发送一个启动信号(START)。
- 主机发送7bit从机地址+1bit读写选择位,1表示读、0表示写。
- 从机产生一个应答信号(ACK)。
- 主机发送8bit从机寄存器地址。
- 从机产生一个应答信号。
- 主机再次发送一个启动信号(START)。
- 主机再次发送7bit从机地址+1bit读写选择位,1表示读、0表示写。
- 从机产生一个应答信号(START)。
- 主机读取一个字节数据。
- 主机产生一个非应答信号(NACK)。
- 主机产生一个停止信号(STOP)。
3.SPI
SPI是一种高速的,全双工,同步的通信总线,占用芯片的四个管脚:
与IIC总线协议比较,SPI总线没有应答机制确认是否接收到数据,可靠性存在一定的缺陷,通信过程相较简单,如下图所示,首先主机将片选信号线拉低,在模式3工作条件下,如果主机需要向从机发送数据,主机会从SCK第一下降沿开始在每个下降沿将数据在MOSI信号线上一位一位的发送给从机;如果主机需要从从机接收数据,主机会生成预定数量的时钟信号,从SCK第一个上升沿开始在每一个上升沿将数据从MISO信号线上一位一位的读取。
SPI有四种工作模式,可以由CPOL(时钟极性)和CPHA(时钟相位)配置
①CPOL = 0,CPHA = 0:空闲时SCLK为低电平,在第一个边沿开始采样。
②CPOL = 0,CPHA = 1:空闲时SCLK为低电平,在第二个边沿开始采样。
③CPOL = 1,CPHA = 0:空闲时SCLK为高电平,在第一个边沿开始采样。
④CPOL = 1,CPHA = 1:空闲时SCLK为高电平,在第二个边沿开始采样。
|