秉火429笔记之十四 USART--串口通信

发布者:GoldenEclipse最新更新时间:2019-09-12 来源: eefocus关键字:秉火  USART  串口通信 手机看文章 扫描二维码
随时随地手机看文章

1. 串口通讯协议简介

串口通讯(Serial Communication)是一种设备间常用的串行通讯方式,因为简单便捷,大部分电子设备都支持该通讯方式,电子工程师在调试设备时也经常使用该通讯方式输出调试信息。


对于通讯协议,我们也以分层的方式来理解,最基本的是把它分为物理层和协议层。物理层规定通讯系统中具有机械、电子功能部分的特性,确保原始数据在物理媒体的传输。协议层主要规定通讯逻辑,统一收发双方的数据打包、解包标准。


1.1 物理层

串口通讯的物理层有很多标准及变种,我们主要讲解RS-232标准 ,RS-232标准主要规定了信号的用途、通讯接口以及信号的电平标准。


两个通讯设备的“DB9接口”之间通过串口信号线建立起连接,串口信号线中使用“RS-232标准”传输数据信号。由于RS-232电平标准的信号不能直接被控制器直接识别,所以这些信号会经过一个“电平转换芯片”转换成控制器能识别的“TTL校准”的电平信号,才能实现通讯。

电平标准

根据通讯使用的电平标准不同,串口通讯可分为TTL标准及RS-232标准

常见的电子电路中常使用TTL的电平标准,理想状态下,使用5V表示二进制逻辑1,使用0V表示逻辑0;而为了增加串口通讯的远距离传输及抗干扰能力,它使用-15V表示逻辑1,+15V表示逻辑0。因为控制器一般使用TTL电平标准,所以常常会使用MA3232芯片对TTL及RS-232电平的信号进行互相转换。


RS-232信号线

在最初的应用中,RS-232串口标准常用于计算机、路由与调制调解器(MODEN,俗称“猫”)之间的通讯 ,在这种通讯系统中,设备被分为数据终端设备DTE(计算机、路由)和数据通讯设备DCE(调制调解器)。我们以这种通讯模型讲解它们的信号线连接方式及各个信号线的作用。


在旧式的台式计算机中一般会有RS-232标准的COM口(也称DB9接口)

接线口以针式引出信号线的称为公头,以孔式引出信号线的称为母头。在计算机中一般引出公头接口,而在调制调解器设备中引出的一般为母头,使用上图中的串口线即可把它与计算机连接起来。通讯时,串口线中传输的信号就是使用前面讲解的RS-232标准调制的。

信号线说明

image.png


串口线中的RTS、CTS、DSR、DTR及DCD信号,使用逻辑 1表示信号有效,逻辑0表示信号无效。例如,当计算机端控制DTR信号线表示为逻辑1时,它是为了告知远端的调制调解器,本机已准备好接收数据,0则表示还没准备就绪。


在目前的其它工业控制使用的串口通讯中,一般只使用RXD、TXD以及GND三条信号线,直接传输数据信号。


1.2 协议层

串口通讯的数据包由发送设备通过自身的TXD接口传输到接收设备的RXD接口。在串口通讯的协议层中,规定了数据包的内容,它由启始位、主体数据、校验位以及停止位组成,通讯双方的数据包格式要约定一致才能正常收发数据。


波特率

两个通讯设备之间需要约定好波特率,即每个码元的长度,以便对信号进行解码,图 中用虚线分开的每一格就是代表一个码元。常见的波特率为4800、9600、115200等。


通讯的起始和停止信号

串口通讯的一个数据包从起始信号开始,直到停止信号结束。数据包的起始信号由一个逻辑0的数据位表示,而数据包的停止信号可由0.5、1、1.5或2个逻辑1的数据位表示,只要双方约定一致即可


有效数据

在数据包的起始位之后紧接着的就是要传输的主体数据内容,也称为有效数据,有效数据的长度常被约定为5、6、7或8位长。


数据校验

在有效数据之后,有一个可选的数据校验位。由于数据通信相对更容易受到外部干扰导致传输数据出现偏差,可以在传输过程加上校验位来解决这个问题。校验方法有奇校验(odd)、偶校验(even)、0校验(space)、1校验(mark)以及无校验(noparity)


奇校验要求有效数据和校验位中“1”的个数为奇数

偶校验与奇校验要求刚好相反,要求帧数据和校验位中“1”的个数为偶数

0校验是不管有效数据中的内容是什么,校验位总为“0”,1校验是校验位总为“1”。

在无校验的情况下,数据包中不包含校验位

2  ST USART

2.1 功能引脚

TX:发送数据输出引脚。

RX:接收数据输入引脚。

SW_RX:数据接收引脚,只用于单线和智能卡模式,属于内部引脚,没有具体外部引脚。

nRTS:请求以发送(Request To Send),n表示低电平有效。如果使能RTS流控制,当USART接收器准备好接收新数据时就会将nRTS变成低电平;当接收寄存器已满时,nRTS将被设置为高电平。该引脚只适用于硬件流控制。

nCTS:清除以发送(Clear To Send),n表示低电平有效。如果使能CTS流控制,发送器在发送下一帧数据之前会检测nCTS引脚,如果为低电平,表示可以发送数据,如果为高电平则在发送完当前数据帧之后停止发送。该引脚只适用于硬件流控制。

SCLK:发送器时钟输出引脚。这个引脚仅适用于同步模式。

STM32F42xxx系统控制器有四个USART和四个UART,其中USART1和USART6的时钟来源于APB2总线时钟,其最大频率为90MHz,其他六个的时钟来源于APB1总线时钟,其最大频率为45MHz。


UART只是异步传输功能,所以没有SCLK、nCTS和nRTS功能引脚。


2.2 重要状态

编程重要状态

image.png

空闲字符 可理解为整个帧周期内电平均为“1”(停止位的电平也是“1”),该字符后是下一个数据帧的起始位。

停止字符 可理解为在一个帧周期内接收到的电平均为“0”。发送器在中断帧的末尾插入 1 或 2 个停止位(逻辑“1”位)以确认起始位。


2.3 编程要点

常规中断方式:


使能RX和TX引脚GPIO时钟和USART时钟

初始化GPIO,并将GPIO复用到USART上

配置USART参数;

配置中断控制器并使能USART收发中断;

使能USART;

在USART接收中断服务函数实现数据接收和发送

DMA中断方式:


使能RX和TX引脚GPIO时钟和USART时钟

初始化GPIO,并将GPIO复用到USART上

配置USART参数;

配置中断控制器并使能USART DMA 收发中断

配置DMA参数及关联数据BUF并配置传输完成中断

使能USART

通过IDLE空闲中断来标识单帧传输完成,计数数据大小,并配合DMA缓存满中断完成数据接收判断

通过重置DMA计数和使能DMA发送

注意考虑接收超过缓存大小时,关闭DMA传输,进入等待IDLE,然后,处理数据,超出直接丢掉

2.4 代码实例

重定向prinft和scanf函数


在C语言标准库中,fputc函数是printf函数内部的一个函数,功能是将字符ch写入到文件指针f所指向文件的当前写指针位置,简单理解就是把字符写入到特定文件中。我们使用USART函数重新修改fputc函数内容,达到类似“写入”的功能。介于某些情况下,硬件并不一定有UART,亦可以类似方法重定义到RAM来方便调试,后续专门介绍。


fgetc函数与fputc函数非常相似,实现字符读取功能。在使用scanf函数时需要注意字符输入格式。

还有一点需要注意的,使用fput和fgetc函数达到重定向C语言标准库输入输出函数必须在MDK的工程选项把“Use MicroLIB”勾选上,MicoroLIB是缺省C库的备选库,它对标准C库进行了高度优化使代码更少,占用更少资源。当然,维库在某些特殊条件下并不需要,比如RL_FLASH,通过其他方式来实现重定向。


为使用printf、scanf函数需要在文件中包含stdio.h头文件。


///重定向c库函数printf到串口,重定向后可使用printf函数

int fputc(int ch, FILE *f)

{

/* 发送一个字节数据到串口 */

USART_SendData(DEBUG_USART, (uint8_t) ch);

/* 等待发送完毕 */

while (USART_GetFlagStatus(DEBUG_USART, USART_FLAG_TXE) == RESET);

return (ch);

}

 

///重定向c库函数scanf到串口,重写向后可使用scanf、getchar等函数

int fgetc(FILE *f)

{

/* 等待串口输入数据 */

while (USART_GetFlagStatus(DEBUG_USART, USART_FLAG_RXNE) == RESET);

 

return (int)USART_ReceiveData(DEBUG_USART);

}

关键字:秉火  USART  串口通信 引用地址:秉火429笔记之十四 USART--串口通信

上一篇:秉火429笔记之九 中断应用概述
下一篇:秉火429笔记之十五 DMA--直接存储区访问

推荐阅读最新更新时间:2024-11-13 07:32

STM32的串口通信
STM32的串口通信 在基础实验成功的基础上,对串口的调试方法进行实践。硬件代码顺利完成之后,对日后调试需要用到的printf重定义进行调试,固定在自己的库函数中。 b) 初始化函数定义: void USART_Configuration(void); //定义串口初始化函数 c) 初始化函数调用: void UART_Configuration(void); //串口初始化函数调用 初始化代码: void USART_Configuration(void) //串口初始化函数 { //串口参数初始化 USART_InitTypeDef USART_InitStructure
[单片机]
串口通信的单片机程序
beep bit p3.7 ;蜂鸣器定义 org 00h jmp main org 23h ;串行中断入口地址 jmp com_int ;串行中断服务程序 ;*********** 主程序开始 ******************* org 30h main: mov sp,#30h ;设置堆栈 lcall rest ;初始化 lcall comm ;串口初始化 jmp $ ;原地等待 ; ************* 初始化 **
[单片机]
STM32串口通信校验问题
这里以串口作为传输媒介,介绍下怎样来发送接收一个完整的数据包。过程涉及到封包与解包。设计一个良好的包传输机制很有利于数据传输的稳定性以及正确性。串口只是一种传输媒介,这种包机制同时也可以用于SPI,I2C的总线下的数据传输。在单片机通信系统(多机通信以及PC与单片机通信)中,是很常见的问题。 一、根据帧头帧尾或者帧长检测一个数据帧 1、帧头+数据+校验+帧尾 这是一个典型的方案,但是对帧头与帧尾在设计的时候都要注意,也就是说帧头、帧尾不能在所传输的数据域中出现,一旦出现可能就被误判。如果用中断来接收的话,程序基本可以这么实现: unsigned char recstatu;//表示是否处于一个正在接收数据包的状态 unsign
[单片机]
STM32<font color='red'>串口通信</font>校验问题
STM32串口通信详解
一.数据通信方式 1.串行与并行通信 按数据传送的方式,通讯可分为串行通讯与并行通讯。 串行通讯:是指设备之间通过一根数据信号线,地线以及控制信号线,按数据位形式一位一位地传输数据的通讯方式,同一时刻只能传输一位(bit)数据。 并行通讯:是指使用 8、16、32 及 64 根或更多的数据线(有多少信号为就需要多少信号位)进行传输的通讯方式,可以同一时刻传输多个数据位的数据。 串行通讯与并行通讯的特性对比: 并行可以同时发送多位数据所以速度比串行的速度要快很多,但并行要的数据线也更多相对成本会更高,而且并行传输对同步要求较高,且随着通讯速率的提高,信号干扰的问题会显著影响通讯性能。 2.全双工、半双工及单工通讯 单工通信:
[单片机]
STM32<font color='red'>串口通信</font>详解
STM32学习之使用库函数编写串口通信
注:使用的芯片是STM32F103ZET6 一、串口初始化部分的程序 1.初始化时钟   因为要使用串口1这个外设,因此在使用之前就需要开启串口1的时钟,并且之后还需要设置IO输入输出的模式,在这里我们也需要开启GPIO的时钟。程序如下: //初始化串口时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); //初始化GPIO时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);   可是为什么要初始化时钟呢在《STM32中文参考手册_V10》的RCC中有这样一句话“当外设时钟没有启用时,软件不能读出
[单片机]
STM32学习之使用库函数编写<font color='red'>串口通信</font>
stm32专题十一:USART(二)结构框图
USART的结构框图 引脚: TX RX 发送和接收 SW-_RX 用于智能卡模式(很少用) IRDA_OUT IRDA_IN 红外通信数据的输出和输入 nRTS nCTS 硬件流控,很少用 SCLK 同步时钟(同步模式下使用) USART的引脚分配如下表,注意,只有USART1挂载到APB2高速总线上,其他的串口都是在APB1总线。 数据寄存器:USART_DR,是一个对应两个寄存器(USART_TDR和USART_RDR),寄存器的低9位 位数据有效,由USART_CR1的M位设置,当M = 0时,表示8个数据位(最常用),M = 1时表示9个数据位(很少用)。因为有两个寄存器,所以TX和RX可
[单片机]
stm32专题十一:<font color='red'>USART</font>(二)结构框图
stm32串口通信困扰我两天的一个问题
问题描述:程序“一样”,编译没有问题,但是功能不能实现,不能回显。 说明USART1波特率设置不成功 但USART1初始化程序“没问题”。 1. 朋友认为我的工程建立有问题,但我以前用同一模板建的工程都没有问题。 2. 确认是USART1配置肯定有问题。就把例程中正确的函数USART1_config()中的程序段复制到我写函数相同的位置。把原先我的程序屏蔽掉,再编译--- 下载---- 功能正常。 然后就是将两个程序段逐句主逐字地排除。 反思:为什么会出现这样的程序。 我的编程思想是 例如GPIO口的使用 第一步 定义结构体 第二步 打开相应的时钟线 第三步 对打开的GPIOx输入输出功能配置 第四步 打开该GPIO
[单片机]
stm32<font color='red'>串口通信</font>困扰我两天的一个问题
AVR ATMEGA8 串口USART
avr串口配置很简单,配置就几个寄存器就可以进收发; 但有几点要搞明白的是: 1、串口一但被配置成功IO功能自动被占用,这点与LPC或STM8/32不同(需要寄存配置); 2、没有专门的串口开起或闭关功位(整个串口); 3、读写控制寄存器C需要把URSEL位写成1,而读写UBRRH寄存器时须要URSEL写成0; 1: //晶振频率 2: #define F_CPU 6000000UL 3: //波特率 4: #define BAUD 9600 5: 6: //M8串口1初始化 7: void UsartInit(void) 8: { 9: unsigned int
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved