嵌入式开发中,UART串口是最常见的一种通信接口,你知道为啥串口这么常见吗?本文就带你深入了解串口最底层的本质内容。
一、什么是串口通讯?
串行通讯是指仅用一根接收线和一根发送线就能将数据以位进行传输的一种通讯方式。尽管串行通讯的比按字节传输的并行通信慢,但是串口可以在仅仅使用两根线的情况下就能实现数据的传输。
典型的串口通信使用3根线完成,分别是地线、发送、接收。由于串口通信是异步的,所以端口能够在一根线上发送数据同时在另一根线上接收数据。串口通信最重要的参数是波特率、数据位、停止位和奇偶的校验。对于两个需要进行串口通信的端口,这些参数必须匹配,这也是能够实现串口通讯的前提。
图1:串行通讯示数据传输意图
二、串口通讯的通讯协议?
最初数据是模拟信号输出简单过程量,后来仪表接口出现了RS232接口,这种接口可以实现点对点的通信方式,但这种方式不能实现联网功能,这就促生了RS485。
我们知道串口通信的数据传输都是0和1,在单总线、I2C、UART中都是通过一根线的高低电平来判断逻辑1或者逻辑0,但这种信号线的GND再与其他设备形成共地模式的通信,这种共地模式传输容易产生干扰,并且抗干扰性能也比较弱。所以差分通信、支持多机通信、抗干扰强的RS485就被广泛的使用了。
RS485通信最大特点就是传输速度可以达到10Mb/s以上,传输距离可以达到3000米左右。大家需要注意的是虽然485最大速度和最大传输距离都很大,但是传输的速度是会随距离的增加而变慢的,所以两者是不可以兼得的。
三、串口通讯的物理层
串口通讯的物理层有很多标准,例如上面提到的,我们主要讲解RS-232标准,RS-232标准主要规定了信号的用途、通讯接口以及信号的电平标准。
在上面的通讯方式中,两个通讯设备的"DB9接口"之间通过串口信号线建立起连接,串口信号线中使用"RS-232标准"传输数据信号。由于RS-232电平标准的信号不能直接被控制器直接识别,所以这些信号会经过一个"电平转换芯片"转换成控制器能识别的"TTL校准"的电平信号,才能实现通讯。
下图为DB9标准串口通讯接口:
DB9引脚说明:
上表中的是计算机端的DB9公头标准接法,由于两个通讯设备之间的收发信号(RXD与TXD)应交叉相连,所以调制调解器端的DB9母头的收发信号接法一般与公头的相反,两个设备之间连接时,只要使用"直通型"的串口线连接起来即可。
串口线中的RTS、CTS、DSR、DTR及DCD信号,使用逻辑 1表示信号有效,逻辑0表示信号无效。例如,当计算机端控制DTR信号线表示为逻辑1时,它是为了告知远端的调制调解器,本机已准备好接收数据,0则表示还没准备就绪。
四、波特率
波特率是指数据信号对载波的调制速率,它用单位时间内载波调制状态改变的次数来表示;
比如波特率为9600bps;代表的就是每秒中传输9600bit,也就是相当于每一秒中划分成了9600等份。
因此,那么每1bit的时间就是1/9600秒=104.1666...us。约0.1ms。既然是9600等份,即每1bit紧接着下一个比特,不存在额外的间隔。两台设备要想实现串口通讯,这收发端设置的波特率必须相同,否则是没办法实现通讯的。
收发波特率一致可以实现通讯:
收发波特率不一致,导致RX端不能正常接收:
五、串口通讯的数据结构
起始位: 起始位必须是持续一个比特时间的逻辑0电平,标志传输一个字符的开始,接收方可用起始位使自己的接收时钟与发送方的数据同步。
数据位: 数据位紧跟在起始位之后,是通信中的真正有效信息。数据位的位数可以由通信双方共同约定。传输数据时先传送字符的低位,后传送字符的高位。
奇偶校验位: 奇偶校验位仅占一位,用于进行奇校验或偶校验,奇偶检验位不是必须有的。如果是奇校验,需要保证传输的数据总共有奇数个逻辑高位;如果是偶校验,需要保证传输的数据总共有偶数个逻辑高位。
停止位: 停止位可以是是1位、1.5位或2位,可以由软件设定。它一定是逻辑1电平,标志着传输一个字符的结束。
空闲位: 空闲位是指从一个字符的停止位结束到下一个字符的起始位开始,表示线路处于空闲状态,必须由高电平来填充。
六、单双工通讯
单工: 数据传输只支持数据在一个方向上传输;
半双工: 允许数据在两个方向上传输,但某一时刻只允许数据在一个方向上传输,实际上是一种切换方向的单工通信,不需要独立的接收端和发送端,两者可合并为一个端口;
全双工: 允许数据同时在两个方向上传输,因此全双工通信是两个单工方式的结合,需要独立的接收端和发送端。
七、STM32中的串口通讯
STM32串口通信接口有两种,分别是:UART(通用异步收发器)、USART(通用同步异步收发器),对于大容量STM32F10x系列芯片,分别由3个USART和两个UART。
TXD:数据发送引脚;RXD:数据输入引脚
对于两芯片的间的连接,两个芯片GND共地,同时TXD和RXD交叉连接,这样两个芯片间可进行TTL电平通信。
但如果对于芯片和PC机相连,除了共地条件外,不能使用如上的直接交叉连接,虽然两者都有TXD和RXD引脚,但通常PC机使用的是RS232接口(9针),通常是TXC和RXD经过电平转换得到,故如果要使芯片与PC机的RS232接口直接通信,需要将芯片的输入输出端口也电平转换为RS232类型,再交叉连接,二者的电平标准不同:
单片机的点评标准(TTL电平):+5V表示1,0V表示0;
RS232电平标准:+15/+13V表示0,-15/-13表示1。
因此单片机与PC机进行串口通信应该遵循:在单片机串口与上位机给出的RS232口之间,通过电平转换电路实现TTL电平与RS232电平间的转换.
如果使用USB转串口也可以实现串口通讯,USB转串口电路图如下所示
STM32串口通讯代码
STM32中串口通讯已经给大家建好了相应的库函数,大家在使用和配置串口的时候直接进行调用库函数和配置就行了,请大家参照一下代码:
1、初始化结构体代码
typedef struct {
uint32_t USART_BaudRate; // 波特率
uint16_t USART_WordLength; // 字长
uint16_t USART_StopBits; // 停止位
uint16_t USART_Parity; // 校验位
uint16_t USART_Mode; // USART 模式
uint16_t USART_HardwareFlowControl; // 硬件流控制
} USART_InitTypeDef;
2、NVIC配置中断优先级
NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* 嵌套向量中断控制器组选择 */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
/* 配置USART为中断源 */
NVIC_InitStructure.NVIC_IRQChannel = DEBUG_USART_IRQ;
/* 抢断优先级*/
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
/* 子优先级 */
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
/* 使能中断 */
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
/* 初始化配置NVIC */
NVIC_Init(&NVIC_InitStructure);
}
3、USART配置函数
void DEBUG_USART_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
/* 第一步:初始化GPIO */
// 打开串口GPIO的时钟
DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK, ENABLE);
// 将USART Tx的GPIO配置为推挽复用模式
GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure);
// 将USART Rx的GPIO配置为浮空输入模式
GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure);
/* 第二步:配置串口的初始化结构体 */
// 打开串口外设的时钟
DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK, ENABLE);
// 配置串口的工作参数
// 配置波特率
USART_InitStructure.USART_BaudRate = DEBUG_USART_BAUDRATE;
// 配置 针数据字长
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(DEBUG_USARTx, &USART_InitStructure);
/*--------------------------------------------------------*/
// 串口中断优先级配置
NVIC_Configuration();
// 使能串口接收中断
USART_ITConfig(DEBUG_USARTx, USART_IT_RXNE, ENABLE);
/*--------------------------------------------------------*/
/* 第三步:使能串口 */
// 使能串口
USART_Cmd(DEBUG_USARTx, ENABLE);
}
上一篇:EEPROM驱动代码常见操作
下一篇:如何利用单片机设计一款产品
推荐帖子
- 在 PyPortal 上用 CircuitPython 运行 PyBasic
- 本帖隐藏的内容说明:https://hackaday.com/2021/10/08/python-provides-classic-basic/代码:https://github.com/richpl/PyBasic在PyPortal上用CircuitPython运行PyBasichello,
- dcexpert MicroPython开源版块
- 用C#如何封装函数生成dll文件
- ARM的程序基本写完了,现在要跟上位机通讯,需要封装一个dll文件,供上位机调用,用网口连接的!没做过,不会写啊,请高手赐教!感激不尽!本人QQ:656691002,会的加我,教教我吧!谢谢了!用C#如何封装函数生成dll文件没用过这个C#,顶一下吧。回复楼主amy_shen的帖子在项目-》属性里面,应用程序-输出类型,选择类库回复楼主amy_shen的帖子原帖由qinshi1208于2012-5-1411:01发表在项目-》属性里面,应
- amy_shen 微控制器 MCU
- 【TI毫米波雷达测评】_5_实测结果
- 软硬件调试完成之后,完成了两次测试,一次是测试车载雷达的盲区,选择的距离很近,大概20厘米;还有一次在室内。测试的环境均是在室内,所以有很多的旁瓣,室内的多径效应严重,算法可以作进一步改进;没有在室外环境测试。【TI毫米波雷达测评】_5_实测结果你好,我QQ1142291205可以问你一些问题嘛,我也是在做这个IWR?另外看你的USB接了2个网线端口一个电源你是分别接的?上面下面都接了? 你好,我也正在使用这块板子,申请加你QQ好友了,方便的话可以交流
- wangran_95 TI技术论坛
- 温度校准怎么做啊?
- 来自eeworld合作群:49900581温度校准怎么做啊?利用恒温水槽,单点、双点、或三点调校一般精度单点调校即可利用调校的结果,修改温度查表的数值这个,针对的是个例啊也就是说,每个传感器都要去调整,如果这样调整的话,就是在表上设定修改参数就是了我是想,看看有没有自动校准的方法,也就是说不用做试验校准的那种我想过一招,就是电流的方式配对法我知道将工作量推给供应商,只要你有量我就是供应商那就分呗这样就太麻烦了,我想知道有没有更优秀的东西将同一型号的热敏电阻
- 舍我其谁 测试/测量
- 美国国家半导体开关稳压调整器技术问答精选
- 美国国家半导体开关稳压调整器技术问答精选问:在待机状态,能耗的降低会不会将系统稳定性降低?n0##WRR答:待机时有两种方法:1.高电压绕组降低到MCU低电压电源,系统进入突发模式,输出电压有更多波纹,但依然在反馈回路;至于某些临界的应用,线性调整器如7805适合这方面的应用,例如NCP1209或MC44608。2.对于NCP1200,它的输出波纹会很小,如2.5%,直接驱动MCU会很安全。我们确信,在待机时,上面的任一种方法依然在控制回路。(1m_JBF66zB
- fighting PCB设计
- 51单片机,keil,汇编问题
- 我是新手,求大神赐教keil编写51汇编很简单的程序,可能是我不怎么会用keil软件ORGOOOOHMOVA,#FOHMOVP1,AJMP$END这程序有问题吗?为什么我运行时,寄存器A和P1,没任何变化啊?我的keil,我不管怎么写乱起八糟的代码,都能编译通过,文件扩展名没问题,简历工程也没问题,用C写了,烧到芯片里,也运行成功了51单片机,keil,汇编问题网上先找一下keil的教程吧,论坛里应该也有,可以到下载中心看一下。你的汇编有问题!把第二
- ciwei0277 51单片机
设计资源 培训 开发板 精华推荐
- AM6TW-2418DH35Z ±18V 6 瓦单路输出 DC/DC 转换器的典型应用
- LT1634BIS8-1.25 超准确 ±4.096V 输出电压基准的典型应用
- LTC1594L、4/8 通道、3V 微功率采样、12 位串行 I/O A/D 转换器的典型应用
- LT3669/LT3669-2 的典型应用 - 具有集成降压稳压器和 LDO 的 IO-Link 收发器
- 用于手机的 6-LED 白光 LED 驱动器
- SCV431B 低压精密可调并联稳压器的典型应用
- 【物联网】鸿蒙智能WiFi开关+4239667A
- 具有终端和 3.3V 数字接口的 LTC2847 软件可选多协议收发器的典型应用电路
- 带 Type-C 插座的 PTN5110 USB PD 接收器(消费者)的典型应用
- LTC3630AMPMSE 5V 至 76V 输入至 5V 输出、150mA 稳压器和 20kHz 最小突发频率的典型应用电路