一、串行与并行通信介绍
并行通讯:同一时刻,可以传输多个bit位的信号,有多少个信号位就需要多少根信号线。
串行通讯:同一时刻,只能传输一个bit位的信号,只需要一根信号线。
二、串口介绍
串口(Serial Port)是一种用于计算机和其他设备之间进行通信的接口标准。它通过串行数据传输,将数据一位一位地依次传送。串口主要应用在连接鼠标、键盘、通信设备和其他计算机组件上。常见的串口标准包括RS-232、RS-485、USB-to-Serial转换器等。
例如:RS-232
三、串口通信电平标准
串口通信电平标准是指在串行通信中,数据传输所使用的电压电平的规定。这些标准定义了逻辑“0”和逻辑“1”所对应的电压范围,以及信号的传输方式。
1、TTL标准
TTL是Transistor-Transistor Logic,即晶体管-晶体管逻辑的简称,全双工工作模式,它是计算机处理器控制的设备内部各部分之间通信的标准技术。TTL电平信号应用广泛,+5V等价于逻辑"1",0V等价于逻辑"0"。数字电路中,由TTL电子元器件组成电路的电平是个电压范围,规定:
输出高电平>=2.4V,输出低电平<=0.4V;
输入高电平>=2.0V,输入低电平<=0.8V。
TTL电平示意图
2、RS232标准
RS-232是美国电子工业协会EIA(Electronic Industry Association)制定的一种串行物理接口标准。RS是英文“推荐标准(Recommend standard)”的缩写,232为标识号。RS-232是对电气特性以及物理特性的规定,只作用于数据的传输通路上,它并不内含对数据的处理方式。
RS232电平定义:它采用负逻辑,-15V~-3V代表逻辑"1",+3V~+15V代表逻辑"0",全双工工作模式
3、RS485标准
RS-485是美国电子工业协会(EIA)在1983年批准了一个新的平衡传输标准(balanced transmission standard)EIA一开始将RS(Recommended standard)做为标准的前缀,不过后来为了便于识别标准的来源,已将RS改为EIA/TIA。目前标准名称为TIA-485,但工程师及应用指南仍继续使用RS-485来称呼此标准。
RS485是一种串口接口标准,为了长距离传输采用差分方式传输,传输的是差分信号,即通过AB两根线的电压差作为电平信号。差分信号能有效地抵御外界因素的干扰,因为干扰对两根线影响是一样的,两根线的电压差不变,信号传递也就不会受干扰。
RS485电平定义:逻辑1:AB两根线压差:+2V ~+6V,逻辑0:AB两根线压差-6V~-2V,半双工工作模式
RS485与TTL、RS232只能一对一连接不同,RS-485可以一对多,在总线上是允许连接多达128个收发器。
4、RS422标准
RS-422和RS-485电路原理基本相同,都是以差分方式发送和接收,不需要数字地线。差分模式使得同速率条件传输距离更远,这正是二者与RS232的根本区别。
RS-422通过两对双绞线可以全双工工作收发互不影响,RS485采用一对双绞线故只能半双工工作,发收不能同时进行,RS-422不允许出现多个发送端而只能有多个接受端。因为有两对双绞线实现全双工,故有四条信号线T/R+,T/R-,以及一条GND线。
5、对比
四、串口通信协议
1、波特率
串口波特率(Baud Rate)是指串口通信中每秒传输的符号数。它是串口通信的重要参数之一,影响数据传输的速度和稳定性。常见的波特率有:
- 9600 bps
- 19200 bps
- 38400 bps
- 57600 bps
- 115200 bps
选择合适的波特率需要考虑设备的支持情况和通信距离。波特率越高,数据传输速度越快,但在长距离传输时可能会导致信号衰减和错误率增加。
2、通讯起始位和停止位
在串口通讯中,起始位和停止位是数据帧的重要组成部分,用于确保数据的正确传输和接收。
-
起始位:
- 起始位用于标识数据帧的开始。它通常是一个低电平信号(逻辑0),持续时间为一个比特周期。
- 当接收设备检测到起始位时,它会开始读取后续的数据位。
-
停止位:
- 停止位用于标识数据帧的结束。它通常是一个高电平信号(逻辑1),可以有一个或多个比特周期。
- 停止位的存在使接收设备能够确认数据帧的结束,并准备接收下一个数据帧。
- 数据帧结构示例
一个典型的串口数据帧结构如下:
- 起始位(1位)
- 数据位(通常为5到8位)
- 校验位(可选,1位)
- 停止位(1或2位)
这种结构确保了数据的完整性和同步性。
3、有效数据
在串口通讯中,有效数据是指在数据帧中实际传输的信息部分。有效数据通常由数据位组成。
4、数据校验
在有效数据之后,有一个可选的数据校验位。由于数据通信相对更容易受到外部干扰导致传输数据出现偏差,可以在传输过程加上校验位来解决这个问题。校验方法有奇校验(odd)、偶校验(even)、0校验、无校验。
奇校验要求有效数据和校验位中"“的个数为奇数,比如一个8位长的有效数据为:01101001,此时总共有4个"1",为达到奇校验效果,校验位为"1",最后传输的数据将是8位的有效数据加上1位的校验位总共9位。
偶校验与奇校验要求刚好相反,要求帧数据和校验位中"1"的个数为偶数,比如数据帧:11001010,此时数据帧"1"的个数为4个,所以偶校验位为"0"。
0校验是不管有效数据中的内容是什么,校验位总为"0",1校验是校验位总为"1"。
在无校验的情况下,数据包中不包含校验位。
五、UART介绍
UART(通用异步收发传输器)是一种广泛使用的串行通信协议,主要用于微控制器和计算机之间的通信。以下是UART的一些关键特点和功能:
-
异步通信:UART不需要时钟信号来同步发送和接收数据。相反,它使用起始位、数据位、校验位和停止位来标识数据的开始和结束。
-
数据格式:UART数据帧通常包括:
- 起始位:标识数据传输的开始。
- 数据位:通常为5到9位,表示实际传输的数据。
- 校验位(可选):用于错误检测。
- 停止位:标识数据传输的结束。
-
波特率:UART通信的速度以波特率(Baud Rate)表示,常见的波特率有9600、115200等。发送和接收设备必须设置相同的波特率以确保正确通信。
-
全双工通信:UART支持全双工通信,这意味着数据可以同时在两个方向上传输。
-
简单性和成本效益:UART的硬件实现相对简单,通常只需要少量的外部组件,因此在许多嵌入式系统中被广泛使用。
-
应用场景:UART常用于计算机串口通信、GPS模块、蓝牙模块、传感器等设备的连接。
UART是一种灵活且易于实现的通信协议,适合于多种应用场景。
- 问题:同步与异步有什么区别?
同步方式指的是,在数据传输的过程中,需要一根时钟线同步。例如IIC,SPI总线,通过他们进行数据传输的时候必须有一根时钟线,用来同步。
异步方式指的是,数据传输的过程中,不需要时钟线,直接发送数据就可以了。例如我们常说的串口采用的就是异步方式,发送方和接收方之间是没有时钟信号线的,他们各自使用自己的时钟。
在STM32芯片中除了有UART外,还有个叫做 USART 。USART 的全称是通用同步异步收发传输器”(Universal Synchronous/Asynchronous Receiver/Transmitter),也就是同步/异步串行收发器。相比 UART 多了一个同步的功能,在硬件上体现出来的就是多了一条时钟线。
六、imx6ull UART介绍
1、特点介绍
通用异步收发器(UART)概述
介绍
通用异步收发器(UART)是一种硬件通信协议,允许与外部设备进行串行通信。它在与各种通信技术(如RS-232和红外线)接口中发挥着重要作用。
通信接口
- RS-232接口:
- 使用电平转换器和RS-232电缆进行通信。
- 红外通信:
- 使用外部电路将红外信号转换为电信号以进行接收。
- 对于传输,它将电信号转换为驱动红外LED的信号。
- 提供低速IrDA兼容性。
支持的格式
- NRZ编码:UART支持非归零(NRZ)编码格式,这是一种用于串行通信的信号方案。
- RS485兼容的9位数据格式:UART可以容纳与RS485信号兼容的9位数据格式。
- IrDA兼容的SIR格式:支持红外数据协会(IrDA)标准的慢速数据率通信。
时钟信号
- 模块时钟:称为
UART_CLK
,该时钟信号来自时钟控制模块(CCM)。 - 外设时钟:称为
IPG_CLK
,同样来源于CCM。
结论
UART是嵌入式系统中串行通信的重要组成部分,提供了与各种数据格式的接口和兼容性。
UART框图
The UART includes the following features:
- High-speed TIA/EIA-232-F compatible,up to 5.0 Mbit/s
高速TIA/EIA-232-F兼容,高达5.0Mbit/s
- Serial IR interface low-speed, IrDA-compatible (up to 115.2 Kbit/s)
串行红外接口低速,IrDA兼容(高达115.2 Kbit/s)
- 9-bit or Multidrop mode (RS-485) support (automatic slave address detection)
9位或多点模式(RS-485)支持(自动从属地址检测)
- 7 or 8 data bits for RS-232 characters, or 9 bit RS-485 format
7或8位RS-232字符数据,或9位RS-485格式
- 1 or 2 stop bits
1或2个停止位
- Programmable parity (even, odd, and no parity)
可编程奇偶校验(偶数、奇数和无奇偶校验)
- Hardware flow control support for request to send (RTS B) and clear to send
硬件流控制支持请求发送(RTS_B)和清除发送
- RS-485 driver direction control via CTS B signal
通过CTS B信号控制RS-485驱动器方向
- Auto baud rate detection (up to 115.2 Kbit/s)
自动波特率检测(高达115.2 Kbit/s)
2、重点寄存器介绍
(1)数据接收寄存器
(2)数据发送寄存器
(3)UART控制寄存器1
打开串口,串口使能
(4)UART控制寄存器2
流控控制位 1
奇偶校验位0
停止位0
数据位1
发送使能位1
接收使能位1
(5)UART控制寄存器3
默认设置为1
(6)UART缓冲控制寄存器
设置1分频
补充:可以在u_boot中输入clocks获取时钟频率
(7)UART状态寄存器2
接收和发送状态寄存器
(8)波特率计算寄存器
例1:
例2:
七、imx6ull UART编程
1、原理图识别
2、编程思想
(1)配置并使能UART1时钟
(2)将GPIO设置为UART1功能
(3)设置UART1串口通信协议参数
流控控制位 1
奇偶校验位0
停止位0
数据位1
发送使能位1
接收使能位1
默认设置为1
设置1分频
(4)使能UART1
打开串口,串口使能
(5)实现UART1收发功能
接收和发送状态寄存器
八、实验代码
main.c
void uart1_test(void);
void uart_printf_test(void);
int main(void)
{
uart_printf_test();
uart1_test();
return 0;
}
uart.c
#include "imx6ull.h"
#include <stdio.h>
/*串口1初始化*/
void uart1_init(void)
{
/*Enable Uart1 Clock*/
CCM_CCGR5 |= (0x3 << 24);
/*PIN to Uart1 function*/
IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO16 &= ~(0xf << 0);//TX
IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO17 &= ~(0xf << 0);//RX
/*
8bit data,1bit stop,no even/odd,115200bit/s
*/
UART1->UCR2 = (1 << 1) | (1 << 2) | (1 << 5) | (0 << 6) | (0 << 8) | (1 << 14);
/*波特率*/
UART1->UCR3 = (1 << 2);
UART1->UFCR = (5 << 7); //不分频
UART1->UBIR = 9;
UART1->UBMR = 433;
/*Enable UART*/
UART1->UCR1 |= (1<< 0);
return ;
}
/*发送数据*/
void uart1_send(uint8_t data)
{
int flag;
UART1->UTXD = data;
//wait transmit complete
do
{
flag = UART1->USR2 & (1 << 3);
} while (!flag);
return ;
}
/*接收数据*/
uint8_t uart1_recv(void)
{
int flag;
//wait data ready
do
{
flag = UART1->USR2 & (1 << 0);
} while (!flag);
return UART1->URXD & 0xff;
}
/*输出字符串*/
void uart1_puts(const char *str)
{
const char *p = NULL ;
uart1_init();
for(p = str; *p ;p++)
{
uart1_send(*p);
}
return;
}
/*测试代码*/
void uart1_test(void)
{
uint8_t data;
uart1_init();//串口初始化
uart1_puts("hell world\r\n");//发送字符串
/*收到立即回发*/
while (1)
{
data = uart1_recv();
uart1_send(data);
}
return ;
}
uart_printf.c
#include "imx6ull.h"
#include <stdarg.h>
#include <stdio.h>
// uart printf("data = %d\r\n",data);
uart_printf(const char *fmt, ...)
{
va_list args;
char printbuffer[124];
va_start(args, fmt);
/*
For this to work, printbuffer must be larger thananything we ever want to print.
*/
vsprintf(printbuffer, fmt, args);
va_end(args);
uart1_puts(printbuffer);
return;
}
void uart_printf_test(void)
{
uint32_t data = 100;
const char *str = "hello uart printf";
uart_printf("data = %d\r\n",data);
uart_printf("str = %s\r\n",str);
return ;
}