串行通信协议_异步串行通信协议 - CSDN
精华内容
参与话题
  • 串口通信协议

    万次阅读 2013-09-09 15:55:24
    串口通讯—通信协议 所谓通信协议是指通信双方的一种约定。约定包括对数据格式、同步方式、传送速度、传送步骤、检纠错方式以及控制字符定义等问题做出统一规定,通信双方必须共同遵守。因此,也叫做通信控制规程,...

    串口通讯—通信协议

    所谓通信协议是指通信双方的一种约定。约定包括对数据格式、同步方式、传送速度、传送步骤、检纠错方式以及控制字符定义等问题做出统一规定,通信双方必须共同遵守。因此,也叫做通信控制规程,或称传输控制规程,它属于ISO'S OSI七层参考模型中的数据链路层。

    目前,采用的通信协议有两类:异步协议和同步协议。同步协议又有面向字符和面向比特以及面向字节计数三种。其中,面向字节计数的同步协议主要用于DEC公司的网络体系结构中。

    一、物理接口标准

    1.串行通信接口的基本任务

    (1)实现数据格式化:因为来自CPU的是普通的并行数据,所以,接口电路应具有实现不同串行通信方式下的数据格式化的任务。在异步通信方式下,接口自动生成起止式的帧数据格式。在面向字符的同步方式下,接口要在待传送的数据块前加上同步字符。

    (2)进行串-并转换:串行传送,数据是一位一位串行传送的,而计算机处理数据是并行数据。所以当数据由计算机送至数据发送器时,首先把串行数据转换为并行数才能送入计算机处理。因此串并转换是串行接口电路的重要任务。

    (3)控制数据传输速率:串行通信接口电路应具有对数据传输速率——波特率进行选择和控制的能力。

    (4)进行错误检测:在发送时接口电路对传送的字符数据自动生成奇偶校验位或其他校验码。在接收时,接口电路检查字符的奇偶校验或其他校验码,确定是否发生传送错误。

    (5)进行TTL与EIA电平转换:CPU和终端均采用TTL电平及正逻辑,它们与EIA采用的电平及负逻辑不兼容,需在接口电路中进行转换。

    (6)提供EIA-RS-232C接口标准所要求的信号线:远距离通信采用MODEM时,需要9根信号线;近距离零MODEM方式,只需要3根信号线。这些信号线由接口电路提供,以便与MODEM或终端进行联络与控制。

    2、串行通信接口电路的组成

    为了完成上述串行接口的任务,串行通信接口电路一般由可编程的串行接口芯片、波特率发生器、EIA与TTL电平转换器以及地址译码电路组成。其中,串行接口芯片,随着大规模继承电路技术的发展,通用的同步(USRT)和异步(UART)接口芯片种类越来越多,如下表所示。它们的基本功能是类似的,都能实现上面提出的串行通信接口基本任务的大部分工作,且都是可编程的。才用这些芯片作为串行通信接口电路的核心芯片,会使电路结构比较简单。

    芯片

    同步(USRT)

    异步(UART)(起止式)

    传输速率b/s

    面向字符

    HDLC

    同步

    异步

    INS8250

      

      

      

    56K

    MC6850

      

      

      

    1M

    MC6852

      

     

    1.5M

      

    MC6854

      

     

     

    1.5M

      

    Int8251A

     

      

    64K

    19.2K

    Int8273

      

     

    64K

      

    Z-80 SIO

      

    800K

      

    3.有关串行通信的物理标准

    为使计算机、电话以及其他通信设备互相沟通,现在,已经对串行通信建立了几个一致的概念和标准,这些概念和标准属于三个方面:传输率,电特性,信号名称和接口标准。

    1、传输率:所谓传输率就是指每秒传输多少位,传输率也常叫波特率。国际上规定了一个标准波特率系列,标准波特率也是最常用的波特率,标准波特率系列为110、300、600、1200、4800、9600和19200。大多数CRT终端都能够按110到9600范围中的任何一种波特率工作。打印机由于机械速度比较慢而使传输波特率受到限制,所以,一般的串行打印机工作在110波特率,点针式打印机由于其内部有较大的行缓冲区,所以可以按高达2400波特的速度接收打印信息。大多数接口的接收波特率和发送波特率可以分别设置,而且,可以通过编程来指定。

    2、RS-232-C标准:RS-232-C标准对两个方面作了规定,即信号电平标准和控制信号线的定义。RS-232-C采用负逻辑规定逻辑电平,信号电平与通常的TTL电平也不兼容,RS-232-C将-5V~-15V规定为“1”,+5V~+15V规定为“0”。图1是TTL标准和RS-232-C标准之间的电平转换。

    图1

    二、软件协议

    1.OSI协议和TCP/IP协议

    图2

    (1)OSI协议

    OSI七层参考模型不是通讯标准,它只给出一个不会由于技术发展而必须修改的稳定模型,使有关标准和协议能在模型定义的范围内开发和相互配合。

    一般的通讯协议只符合OSI七层模型的某几层,如: EIA-RS-232-C:实现了物理层。 IBM的SDLC(同步数据链路控制规程):数据链路层。ANSI的ADCCP(先进数据通讯规程):数据链路层IBM的BSC(二进制同步通讯协议):数据链路层。应用层的电子邮件协议SMTP只负责寄信、POP3只负责收信。

    (2)TCP/IP协议

    实现了五层协议。

    (1)物理层:对应OSI的物理层。

    (2)网络接口层:类似于OSI的数据链路层。

    (3)Internet层:OSI模型在Internet网使用前提出,未考虑网间连接。

    (4)传输层:对应OSI的传输层。

    (5)应用层:对应OSI的表示层和应用层。

    2.串行通信协议

    串行通信协议分同步协议和异步协议。

    (1)异步通信协议的实例——起止式异步协议

    图3

    特点与格式:

    起止式异步协议的特点是一个字符一个字符传输,并且传送一个字符总是以起始位开始,以停止位结束,字符之间没有固定的时间间隔要求。其格式如图3所示。每一个字符的前面都有一位起始位(低电平,逻辑值0),字符本身有5~7位数据位组成,接着字符后面是一位校验位(也可以没有校验位),最后是一位,或意味半,或二位停止位,停止位后面是不定长度的空闲位。停止位和空闲位都规定为高电平(逻辑值),这样就保证起始位开始处一定有一个下跳沿。

    从图中可以看出,这种格式是靠起始位和停止位来实现字符的界定或同步的,故称为起始式协议。传送时,数据的低位在前,高位在后,图4表示了传送一个字符E的ASCAII码的波形1010001。当把它的最低有效位写到右边时,就是E的ASCII码1000101=45H。 

    图4

    起/止位的作用:起始位实际上是作为联络信号附加进来的,当它变为低电平时,告诉收方传送开始。它的到来,表示下面接着是数据位来了,要准备接收。而停止位标志一个字符的结束,它的出现,表示一个字符传送完毕。这样就为通信双方提供了何时开始收发,何时结束的标志。传送开始前,发收双方把所采用的起止式格式(包括字符的数据位长度,停止位位数,有无校验位以及是奇校验还是偶校验等)和数据传输速率作统一规定。传送开始后,接收设备不断地检测传输线,看是否有起始位到来。当收到一系列的“1”(停止位或空闲位)之后,检测到一个下跳沿,说明起始位出现,起始位经确认后,就开始接收所规定的数据位和奇偶校验位以及停止位。经过处理将停止位去掉,把数据位拼装成一个并行字节,并且经校验后,无奇偶错才算正确的接收一个字符。一个字符接收完毕,接收设备有继续测试传输线,监视“0”电平的到来和下一个字符的开始,直到全部数据传送完毕。

    由上述工作过程可看到,异步通信是按字符传输的,每传输一个字符,就用起始位来通知收方,以此来重新核对收发双方同步。若接收设备和发送设备两者的时钟频率略有偏差,这也不会因偏差的累积而导致错位,加之字符之间的空闲位也为这种偏差提供一种缓冲,所以异步串行通信的可靠性高。但由于要在每个字符的前后加上起始位和停止位这样一些附加位,使得传输效率变低了,只有约80%。因此,起止协议一般用在数据速率较慢的场合(小于19.2kbit/s)。在高速传送时,一般要采用同步协议。

    (2)面向字符的同步协议

    特点与格式:这种协议的典型代表是IBM公司的二进制同步通信协议(BSC)。它的特点是一次传送由若干个字符组成的数据块,而不是只传送一个字符,并规定了10个字符作为这个数据块的开头与结束标志以及整个传输过程的控制信息,它们也叫做通信控制字。由于被传送的数据块是由字符组成,故被称作面向字符的协议。

    特定字符(控制字符)的定义:由上面的格式可以看出,数据块的前后都加了几个特定字符。SYN是同步字符(synchronous Character),每一帧开始处都有SYN,加一个SYN的称单同步,加两个SYN的称双同步设置同步字符是起联络作用,传送数据时,接收端不断检测,一旦出现同步字符,就知道是一帧开始了。接着的SOH是序始字符(Start Of Header),它表示标题的开始。标题中包括院地址、目的地址和路由指示等信息。STX是文始字符(Start Of Text),它标志着传送的正文(数据块)开始。数据块就是被传送的正文内容,由多个字符组成。数据块后面是组终字符ETB(End Of Transmission Block)或文终字符ETX(End Of Text),其中ETB用在正文很长、需要分成若干个分数据块、分别在不同帧中发送的场合,这时在每个分数据块后面用文终字符ETX。一帧的最后是校验码,它对从SOH开始到ETX(或ETB)字段进行校验,校验方式可以是纵横奇偶校验或CRC。另外,在面向字符协议中还采用了一些其他通信控制字,它们的名称如下表所示:

    名 称

    ASCII

    EBCDIC

    序始(SOH)

    0000001

    00000001

    文始(STX)

    0000010

    00000010

    组终(ETB)

    0010111

    00100110

    文终(ETX)

    0000011

    00000011

    同步(SYN)

    0010110

    00110010

    送毕(EOT)

    0000100

    00110111

    询问(ENQ)

    0000101

    00101101

    确认(ACK)

    0000110

    00101110

    否认(NAK)

    0010101

    00111101

    转义(DLE)

    0010000

    00010000

    数据透明的实现:面向字符的同步协议,不象异步起止协议那样,需要在每个字符前后附加起始和停止位,因此,传输效率提高了。同时,由于采用了一些传输控制字,故增强了通信控制能力和校验功能。但也存在一些问题,例如,如何区别数据字符代码和特定字符代码的问题,因为在数据块中完全有可能出现与特定字符代码相同的数据字符,这就会发生误解。比如正文有个与文终字符ETX的代码相同的数据字符,接收端就不会把它当作为普通数据处理,而误认为是正文结束,因而产生差错。因此,协议应具有将特定字符作为普通数据处理的能力,这种能力叫做“数据透明”。为此,协议中设置了转移字符DLE(Data Link Escape)。当把一个特定字符看成数据时,在它前面要加一个DLE,这样接收器收到一个DLE就可预知下一个字符是数据字符,而不会把它当作控制字符来处理了。DLE本身也是特定字符,当它出现在数据块中时,也要在它前面加上另一个DLE。这种方法叫字符填充。字符填充实现起来相当麻烦,且依赖于字符的编码。正是由于以上的缺点,故又产生了新的面向比特的同步协议。

    (3)面向比特的同步协议

    特点与格式:面向比特的协议中最具有代表性的是IBM的同步数据链路控制规程SDLC(Synchronous Data Link Control),国际标准化组织ISO(International Standard Organization)的高级数据链路控制规程HDLC(High Level Data link Control),美国国家标准协会(Americal National Standard Institute)的先进数据通信规程ADCCP(Advanced Data Communication Control Procedure)。这些协议的特点是所传输的一帧数据可以是任意位,而且它是靠约定的位组合模式,而不是靠特定字符来标志帧的开始和结束,故称“面向比特”的协议。这中协议的一般帧格式如图5所示:

    图5

    帧信息的分段:由图5可见,SDLC/HDLC的一帧信息包括以下几个场(Filed),所有场都是从有效位开始传送。

    (1)SDLC/HDLC标志字符:SDLC/HDLC协议规定,所有信息传输必须以一个标志字符开始,且以同一个字符结束。这个标志字符是 01111110,称标志场(F)。从开始标志到结束标志之间构成一个完整的信息单位,称为一帧(Frame)。所有的信息是以帧的形传输的,而标志字符提供了每一帧的边界。接收端可以通过搜索“01111110”来探知帧的开头和结束,以此建立帧同步。

    (2)地址场和控制场:在标志场之后,可以有一个地址场A(Address)和一个控制场C(Control)。地址场用来规定与之通信的次站的地址。控制场可规定若干个命令。SDLC规定A场和C场的宽度为8位或16位。接收方必须检查每个地址字节的第一位,如果为“0”,则后面跟着另一个地址字节;若为“1”,则该字节就是最后一个地址字节。同理,如果控制场第一个字节的第一位为为“0”,则还有第二个控制场字节,否则就只有一个字节。

    (3)信息场:跟在控制场之后的是信息场I(Information)。I场包含有要传送的数据,并不是每一帧都必须有信息场。即数据场可以为0,当它为0时,则这一帧主要是控制命令。

    (4)帧校验信息:紧跟在信息场之后的是两字节的争校验,帧校验场称为FC(Frame Check)场或称为帧校验序列FCS(Frame check Squence)。SDLC/HDLC均采用16位循环冗余校验码CRC(Cyclic Redundancy Code)。除了标志场和自动插入的“0”以外,所有的信息都参加CRC计算。

    实际应用时的两个技术问题:

    (1)“0”位插入/删除:如上所述,SDLC/HDLC协议规定以01111110为标志字节,但在信息场中也完全有可能有同一种模式的字符,为了把它与标志区分开来,所以采取了“0”位插入和删除技术。具体作法是发送端在发送所有信息(除标志字节外)时,只要遇到连续5个“1”,就自动插入一个“0”,当接收端在接收数据时(除标志字节)如果连续收到5个“1”,就自动将其后的一个“0”删除是,以恢复信息的原有形式。这种“0”位的插入和删除过程是由硬件自动完成的。

    (2)SDLC/HDLC异常结束:若在发送过程中出现错误,则SDLC/HDLC协议常用异常结束(Abort)字符,或称为失效序列使本帧作废。在HDLC规程中,7个连续的“1”被作为失效字符,而在SDLC中失效字符是8个连续的“1”。当然在试销序列中不使用“0”位插入/删除技术。SDLC/HDLC协议规定,在一帧之内不允许出现数据间隔。在两帧之间,发送器可以连续输出标志字符序列,也可以输出连续的高电平,它被称为空闲(Idle)信号。

    展开全文
  • 串口通讯协议

    万次阅读 多人点赞 2018-03-02 10:02:47
    文章转载自http://www.cnblogs.com/firege/p/5805753.html20.1 串口通讯协议简介串口通讯(Serial Communication)是一种设备间非常常用的串行通讯方式,因为它简单便捷,大部分电子设备都支持该通讯方式,电子工程师...

    文章转载自http://www.cnblogs.com/firege/p/5805753.html


    20.1 串口通讯协议简介

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

    在计算机科学里,大部分复杂的问题都可以通过分层来简化。如芯片被分为内核层和片上外设;STM32标准库则是在寄存器与用户代码之间的软件层。对于通讯协议,我们也以分层的方式来理解,最基本的是把它分为物理层和协议层。物理层规定通讯系统中具有机械、电子功能部分的特性,确保原始数据在物理媒体的传输。协议层主要规定通讯逻辑,统一收发双方的数据打包、解包标准。简单来说物理层规定我们用嘴巴还是用肢体来交流,协议层则规定我们用中文还是英文来交流。

    下面我们分别对串口通讯协议的物理层及协议层进行讲解。

    20.1.1 物理层

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

    使用RS-232标准的串口设备间常见的通讯结构见图 201

     201 串口通讯结构图

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

    1.    电平标准    

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

     201 TTL电平标准与RS232电平标准

    通讯标准

    电平标准(发送端)

    5V TTL

    逻辑12.4V-5V

    逻辑00~0.5V

    RS-232

    逻辑1-15V~-3V

    逻辑0+3V~+15V

    我们知道常见的电子电路中常使用TTL的电平标准,理想状态下,使用5V表示二进制逻辑1,使用0V表示逻辑0;而为了增加串口通讯的远距离传输及抗干扰能力,它使用-15V表示逻辑1+15V表示逻辑0。使用RS232TTL电平校准表示同一个信号时的对比见图 202

     202 RS-232TTL电平标准下表示同一个信号

    因为控制器一般使用TTL电平标准,所以常常会使用MA3232芯片对TTL及RS-232电平的信号进行互相转换。

    2.    RS-232信号线

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

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

     203 电脑主板上的COM口及串口线

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

    在这种应用场合下,DB9接口中的公头及母头的各个引脚的标准信号线接法见图 204及表 202。

     204 DB9标准的公头及母头接法

     202 DB9信号线说明(公头,为方便理解,可把DTE理解为计算机,DCE理解为调制调解器)

    序号

    名称

    符号

    数据方向

    说明

    1

    载波检测

    DCD

    DTEàDCE

    Data Carrier Detect,数据载波检测,用于DTE告知对方,本机是否收到对方的载波信号

    2

    接收数据

    RXD

    DTEßDCE

    Receive Data,数据接收信号,即输入

    3

    发送数据

    TXD

    DTEàDCE

    Transmit Data,数据发送信号,即输出。两个设备之间的TXDRXD应交叉相连

    4

    数据终端(DTE) 就绪

    DTR

    DTEàDCE

    Data Terminal Ready,数据终端就绪,用于DTE向对方告知本机是否已准备好

    5

    信号地

    GND

    -

    地线,两个通讯设备之间的地电位可能不一样,这会影响收发双方的电平信号,所以两个串口设备之间必须要使用地线连接,即共地。

    6

    数据设备(DCE)就绪

    DSR

    DTEßDCE

    Data Set Ready,数据发送就绪,用于DCE告知对方本机是否处于待命状态

    7

    请求发送

    RTS

    DTEàDCE

    Request To Send,请求发送, DTE 请求 DCE 本设备向DCE端发送数据

    8

    允许发送

    CTS

    DTEßDCE

    Clear To Send,允许发送,DCE回应对方的RTS发送请求,告知对方是否可以发送数据

    9

    响铃指示

    RI

    DTEßDCE

    Ring Indicator,响铃指示,表示DCE端与线路已接通

    上表中的是计算机端的DB9公头标准接法,由于两个通讯设备之间的收发信号(RXDTXD)应交叉相连,所以调制调解器端的DB9母头的收发信号接法一般与公头的相反,两个设备之间连接时,只要使用"直通型"的串口线连接起来即可,见图 205

     205 计算机与调制调解器的信号线连接

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

    在目前的其它工业控制使用的串口通讯中,一般只使用RXDTXD以及GND三条信号线,直接传输数据信号。而RTSCTSDSRDTRDCD信号都被裁剪掉了,如果您在前面被这些信号弄得晕头转向,那就直接忽略它们吧。

    20.1.2 协议层

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

     206 串口数据包的基本组成

    1.    波特率

    本章中主要讲解的是串口异步通讯,异步通讯中由于没有时钟信号(如前面讲解的DB9接口中是没有时钟信号的),所以两个通讯设备之间需要约定好波特率,即每个码元的长度,以便对信号进行解码,图 206中用虚线分开的每一格就是代表一个码元。常见的波特率为4800、9600、115200等。

    2.    通讯的起始和停止信号

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

    3.    有效数据

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

    4.    数据校验

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

        奇校验要求有效数据和校验位中"1"的个数为奇数,比如一个8位长的有效数据为:01101001,此时总共有4个"1",为达到奇校验效果,校验位为"1",最后传输的数据将是8位的有效数据加上1位的校验位总共9位。

        偶校验与奇校验要求刚好相反,要求帧数据和校验位中"1"的个数为偶数,比如数据帧:11001010,此时数据帧"1"的个数为4个,所以偶校验位为"0"。

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

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

    20.2 STM32的USART简介

    STM32芯片具有多个USART外设用于串口通讯,它是 Universal Synchronous Asynchronous Receiver and Transmitter的缩写,即通用同步异步收发器可以灵活地与外部设备进行全双工数据交换。有别于USART,它还有具有UART外设(Universal Asynchronous Receiver and Transmitter),它是在USART基础上裁剪掉了同步通信功能,只有异步通信。简单区分同步和异步就是看通信时需不需要对外提供时钟输出,我们平时用的串口通信基本都是UART

    USART满足外部设备对工业标准NRZ异步串行数据格式的要求,并且使用了小数波特率发生器,可以提供多种波特率,使得它的应用更加广泛。USART支持同步单向通信和半双工单线通信;还支持局域互连网络LIN、智能卡(SmartCard)协议与lrDA(红外线数据协会) SIR ENDEC规范。

    USART支持使用DMA,可实现高速数据通信,有关DMA具体应用将在DMA章节作具体讲解。

    USARTSTM32应用最多莫过于"打印"程序信息,一般在硬件设计时都会预留一个USART通信接口连接电脑,用于在调试程序是可以把一些调试信息"打印"在电脑端的串口调试助手工具上,从而了解程序运行是否正确、指出运行出错位置等等。

    STM32USART输出的是TTL电平信号,若需要RS-232标准的信号可使用MAX3232芯片进行转换。

    20.3 USART功能框图

    STM32USART功能框图包含了USART最核心内容,掌握了功能框图,对USART就有一个整体的把握,在编程时就思路就非常清晰,见图 207

     207 USART功能框图

    1.    ①功能引脚

    TX:发送数据输出引脚。

    RX:接收数据输入引脚。

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

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

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

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

    USART引脚在STM32F429IGT6芯片具体发布见表 203

     203 STM32F429IGT6芯片的USART引脚

      

    APB2(最高90MHz)

    APB1(最高45MHz)

    USART1

    USART6

    USART2

    USART3

    UART4

    UART5

    UART7

    UART8

    TX

    PA9/PB6

    PC6/PG14

    PA2/PD5

    PB10/PD8
    /PC10

    PA0/PC10

    PC12

    PF7/PE8

    PE1

    RX

    PA10/PB7

    PC7/PG9

    PA3/PD6

    PB11/PD9
    /PC11

    PA1/PC11

    PD2

    PF6/PE7

    PE0

    SCLK

    PA8

    PG7/PC8

    PA4/PD7

    PB12/PD10
    /PC12

      

      

      

      

    nCTS

    PA11

    PG13/PG15

    PA0/PD3

    PB13/PD11

      

      

      

      

    nRTS

    PA12

    PG8/PG12

    PA1/PD4

    PB14/PD12

      

      

      

      

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

    UART只是异步传输功能,所以没有SCLKnCTSnRTS功能引脚。

    观察表 203可发现很多USART的功能引脚有多个引脚可选,这非常方便硬件设计,只要在程序编程时软件绑定引脚即可。

    2.    ②数据寄存器

    USART数据寄存器(USART_DR)只有低9位有效,并且第9位数据是否有效要取决于USART控制寄存器1(USART_CR1)M位设置,当M位为0时表示8位数据字长,当M位为1表示9位数据字长,我们一般使用8位数据字长。

    USART_DR包含了已发送的数据或者接收到的数据。USART_DR实际是包含了两个寄存器,一个专门用于发送的可写TDR,一个专门用于接收的可读RDR。当进行发送操作时,往USART_DR写入数据会自动存储在TDR内;当进行读取操作时,向USART_DR读取数据会自动提取RDR数据。

    TDRRDR都是介于系统总线和移位寄存器之间。串行通信是一个位一个位传输的,发送时把TDR内容转移到发送移位寄存器,然后把移位寄存器数据每一位发送出去,接收时把接收到的每一位顺序保存在接收移位寄存器内然后才转移到RDR

    USART支持DMA传输,可以实现高速数据传输,具体DMA使用将在DMA章节讲解。

    3.    ③控制器

    USART有专门控制发送的发送器、控制接收的接收器,还有唤醒单元、中断控制等等。使用USART之前需要向USART_CR1寄存器的UE位置1使能USART。发送或者接收数据字长可选8位或9位,由USART_CR1M位控制。

    发送器

    USART_CR1寄存器的发送使能位TE1时,启动数据发送,发送移位寄存器的数据会在TX引脚输出,如果是同步模式SCLK也输出时钟信号。

    一个字符帧发送需要三个部分:起始位+数据帧+停止位。起始位是一个位周期的低电平,位周期就是每一位占用的时间;数据帧就是我们要发送的8位或9位数据,数据是从最低位开始传输的;停止位是一定时间周期的高电平。

    停止位时间长短是可以通过USART控制寄存器2(USART_CR2)STOP[1:0]位控制,可选0.5个、1个、1.5个和2个停止位。默认使用1个停止位。2个停止位适用于正常USART模式、单线模式和调制解调器模式。0.5个和1.5个停止位用于智能卡模式。

    当选择8位字长,使用1个停止位时,具体发送字符时序图见图 208

     208 字符发送时序图

    当发送使能位TE1之后,发送器开始会先发送一个空闲帧(一个数据帧长度的高电平),接下来就可以往USART_DR寄存器写入要发送的数据。在写入最后一个数据后,需要等待USART状态寄存器(USART_SR)TC位为1,表示数据传输完成,如果USART_CR1寄存器的TCIE位置1,将产生中断。

    在发送数据时,编程的时候有几个比较重要的标志位我们来总结下。

    名称

    描述

    TE

    发送使能

    TXE

    发送寄存器为空,发送单个字节的时候使用

    TC

    发送完成,发送多个字节数据的时候使用

    TXIE

    发送完成中断使能

     

    接收器

    如果将USART_CR1寄存器的RE位置1,使能USART接收,使得接收器在RX线开始搜索起始位。在确定到起始位后就根据RX线电平状态把数据存放在接收移位寄存器内。接收完成后就把接收移位寄存器数据移到RDR内,并把USART_SR寄存器的RXNE位置1,同时如果USART_CR2寄存器的RXNEIE1的话可以产生中断。

    在接收数据时,编程的时候有几个比较重要的标志位我们来总结下。

    名称

    描述

    RE

    接收使能

    RXNE

    读数据寄存器非空

    RXNEIE

    发送完成中断使能

     

    为得到一个信号真实情况,需要用一个比这个信号频率高的采样信号去检测,称为过采样,这个采样信号的频率大小决定最后得到源信号准确度,一般频率越高得到的准确度越高,但为了得到越高频率采样信号越也困难,运算和功耗等等也会增加,所以一般选择合适就好。

    接收器可配置为不同过采样技术,以实现从噪声中提取有效的数据。USART_CR1寄存器的OVER8位用来选择不同的采样采样方法,如果OVER8位设置为1采用8倍过采样,即用8个采样信号采样一位数据;如果OVER8位设置为0采用16倍过采样,即用16个采样信号采样一位数据。

    USART的起始位检测需要用到特定序列。如果在RX线识别到该特定序列就认为是检测到了起始位。起始位检测对使用16倍或8倍过采样的序列都是一样的。该特定序列为:1110X0X0X0000,其中X表示电平任意,10皆可。

    8倍过采样速度更快,最高速度可达fPCLK/8fPCLKUSART时钟,采样过程见图 209。使用第456次脉冲的值决定该位的电平状态。

     209 8倍过采样过程

    16倍过采样速度虽然没有8倍过采样那么快,但得到的数据更加精准,其最大速度为fPCLK/16,采样过程见图 2010。使用第8910次脉冲的值决定该位的电平状态。

     2010 16倍过采样过程

    4.    ④小数波特率生成

    波特率指数据信号对载波的调制速率,它用单位时间内载波调制状态改变次数来表示,单位为波特。比特率指单位时间内传输的比特数,单位bit/s(bps)。对于USART波特率与比特率相等,以后不区分这两个概念。波特率越大,传输速率越快。

    USART的发送器和接收器使用相同的波特率。计算公式如下:

    公式 201 波特率计算

    其中,fPLCKUSART时钟,参考表 203OVER8USART_CR1寄存器的OVER8位对应的值,USARTDIV是一个存放在波特率寄存器(USART_BRR)的一个无符号定点数。其中DIV_Mantissa[11:0]位定义USARTDIV的整数部分,DIV_Fraction[3:0]位定义USARTDIV的小数部分,DIV_Fraction[3]位只有在OVER8位为0时有效,否则必须清零。

    例如,如果OVER8=0DIV_Mantissa=24DIV_Fraction=10,此时USART_BRR值为0x18A;那么USARTDIV的小数位10/16=0.625;整数位24,最终USARTDIV的值为24.625

    如果OVER8=0并且知道USARTDIV值为27.68,那么DIV_Fraction=16*0.68=10.88,最接近的正整数为11,所以DIV_Fraction[3:0]0xBDIV_Mantissa=整数(27.68)=27,即位0x1B

    如果OVER8=1情况类似,只是把计算用到的权值由16改为8

    波特率的常用值有2400960019200115200。下面以实例讲解如何设定寄存器值得到波特率的值。

    由表 203可知USART1USART6使用APB2总线时钟,最高可达90MHz,其他USART的最高频率为45MHz。我们选取USART1作为实例讲解,即fPLCK=90MHz

    当我们使用16倍过采样时即OVER8=0,为得到115200bps的波特率,此时:

     

    解得USARTDIV=48.825125,可算得DIV_Fraction=0xDDIV_Mantissa=0x30,即应该设置USART_BRR的值为0x30D

    在计算DIV_Fraction时经常出现小数情况,经过我们取舍得到整数,这样会导致最终输出的波特率较目标值略有偏差。下面我们从USART_BRR的值为0x30D开始计算得出实际输出的波特率大小。

    USART_BRR的值为0x30D,可得DIV_Fraction=13DIV_Mantissa=48,所以USARTDIV=48+16*0.13=48.8125,所以实际波特率为:115237;这个值跟我们的目标波特率误差为0.03%,这么小的误差在正常通信的允许范围内。

    8倍过采样时计算情况原理是一样的。

    5.    校验控制

    STM32F4xx系列控制器USART支持奇偶校验。当使用校验位时,串口传输的长度将是8位的数据帧加上1位的校验位总共9位,此时USART_CR1寄存器的M位需要设置为1,即9数据位。将USART_CR1寄存器的PCE位置1就可以启动奇偶校验控制,奇偶校验由硬件自动完成。启动了奇偶校验控制之后,在发送数据帧时会自动添加校验位,接收数据时自动验证校验位。接收数据时如果出现奇偶校验位验证失败,会见USART_SR寄存器的PE位置1,并可以产生奇偶校验中断。

    使能了奇偶校验控制后,每个字符帧的格式将变成:起始位+数据帧+校验位+停止位。

    6.    中断控制

    USART有多个中断请求事件,具体见表 204

     204 USART中断请求

    中断事件

    事件标志

    使能控制位

    发送数据寄存器为空

    TXE

    TXEIE

    CTS标志

    CTS

    CTSIE

    发送完成

    TC

    TCIE

    准备好读取接收到的数据

    RXNE

    RXNEIE

    检测到上溢错误

    ORE

    检测到空闲线路

    IDLE

    IDLEIE

    奇偶校验错误

    PE

    PEIE

    断路标志

    LBD

    LBDIE

    多缓冲通信中的噪声标志、
    上溢错误和帧错误

    NF/ORE/FE

    EIE

    20.4 USART初始化结构体详解

    标准库函数对每个外设都建立了一个初始化结构体,比如USART_InitTypeDef,结构体成员用于设置外设工作参数,并由外设初始化配置函数,比如USART_Init()调用,这些设定参数将会设置外设相应的寄存器,达到配置外设工作环境的目的。

    初始化结构体和初始化库函数配合使用是标准库精髓所在,理解了初始化结构体每个成员意义基本上就可以对该外设运用自如了。初始化结构体定义在stm32f4xx_usart.h文件中,初始化库函数定义在stm32f4xx_usart.c文件中,编程时我们可以结合这两个文件内注释使用。

    USART初始化结构体

    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;

    1)    USART_BaudRate:波特率设置。一般设置为2400、9600、19200、115200。标准库函数会根据设定值计算得到USARTDIV值,见公式 201,并设置USART_BRR寄存器值。

    2)    USART_WordLength:数据帧字长,可选8位或9位。它设定USART_CR1寄存器的M位的值。如果没有使能奇偶校验控制,一般使用8数据位;如果使能了奇偶校验则一般设置为9数据位。

    3)    USART_StopBits:停止位设置,可选0.5个、1个、1.5个和2个停止位,它设定USART_CR2寄存器的STOP[1:0]位的值,一般我们选择1个停止位。

    4)    USART_Parity:奇偶校验控制选择,可选USART_Parity_No(无校验)、USART_Parity_Even(偶校验)以及USART_Parity_Odd(奇校验),它设定USART_CR1寄存器的PCE位和PS位的值。

    5)    USART_Mode:USART模式选择,有USART_Mode_Rx和USART_Mode_Tx,允许使用逻辑或运算选择两个,它设定USART_CR1寄存器的RE位和TE位。

    6)    USART_HardwareFlowControl:硬件流控制选择,只有在硬件流控制模式才有效,可选有⑴使能RTS、⑵使能CTS、⑶同时使能RTS和CTS、⑷不使能硬件流。

    当使用同步模式时需要配置SCLK引脚输出脉冲的属性,标准库使用一个时钟初始化结构体USART_ClockInitTypeDef来设置,因此该结构体内容也只有在同步模式才需要设置。

    USART时钟初始化结构体

    1 typedef struct {

    uint16_t USART_Clock; // 时钟使能控制

    uint16_t USART_CPOL; // 时钟极性

    uint16_t USART_CPHA; // 时钟相位

    uint16_t USART_LastBit; // 最尾位时钟脉冲

    } USART_ClockInitTypeDef;

    1)    USART_Clock:同步模式下SCLK引脚上时钟输出使能控制,可选禁止时钟输出(USART_Clock_Disable)或开启时钟输出(USART_Clock_Enable);如果使用同步模式发送,一般都需要开启时钟。它设定USART_CR2寄存器的CLKEN位的值。

    2)    USART_CPOL:同步模式下SCLK引脚上输出时钟极性设置,可设置在空闲时SCLK引脚为低电平(USART_CPOL_Low)或高电平(USART_CPOL_High)。它设定USART_CR2寄存器的CPOL位的值。

    3)    USART_CPHA:同步模式下SCLK引脚上输出时钟相位设置,可设置在时钟第一个变化沿捕获数据(USART_CPHA_1Edge)或在时钟第二个变化沿捕获数据。它设定USART_CR2寄存器的CPHA位的值。USART_CPHA与USART_CPOL配合使用可以获得多种模式时钟关系。

    4)    USART_LastBit:选择在发送最后一个数据位的时候时钟脉冲是否在SCLK引脚输出,可以是不输出脉冲(USART_LastBit_Disable)、输出脉冲(USART_LastBit_Enable)。它设定USART_CR2寄存器的LBCL位的值。

    20.5 USART1接发通信实验

    USART只需两根信号线即可完成双向通信,对硬件要求低,使得很多模块都预留USART接口来实现与其他模块或者控制器进行数据传输,比如GSM模块,WIFI模块、蓝牙模块等等。在硬件设计时,注意还需要一根"共地线"。

    我们经常使用USART来实现控制器与电脑之间的数据传输。这使得我们调试程序非常方便,比如我们可以把一些变量的值、函数的返回值、寄存器标志位等等通过USART发送到串口调试助手,这样我们可以非常清楚程序的运行状态,当我们正式发布程序时再把这些调试信息去除即可。

    我们不仅仅可以将数据发送到串口调试助手,我们还可以在串口调试助手发送数据给控制器,控制器程序根据接收到的数据进行下一步工作。

    首先,我们来编写一个程序实现开发板与电脑通信,在开发板上电时通过USART发送一串字符串给电脑,然后开发板进入中断接收等待状态,如果电脑有发送数据过来,开发板就会产生中断,我们在中断服务函数接收数据,并马上把数据返回发送给电脑。

    20.5.1 硬件设计

    为利用USART实现开发板与电脑通信,需要用到一个USBUSARTIC,我们选择CH340G芯片来实现这个功能,CH340G是一个USB总线的转接芯片,实现USBUSARTUSBIrDA红外或者USB转打印机接口,我们使用其USBUSART功能。具体电路设计见图 2011

    我们将CH340GTXD引脚与USART1RX引脚连接,CH340GRXD引脚与USART1TX引脚连接。CH340G芯片集成在开发板上,其地线(GND)已与控制器的GND连通。

     2011 USB转串口硬件设计

    20.5.2 软件设计

    这里只讲解核心的部分代码,有些变量的设置,头文件的包含等并没有涉及到,完整的代码请参考本章配套的工程。我们创建了两个文件:bsp_debug_usart.cbsp_debug_usart.h文件用来存放USART驱动程序及相关宏定义。

    1.    编程要点

    1)    使能RX和TX引脚GPIO时钟和USART时钟;

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

    3)    配置USART参数;

    4)    配置中断控制器并使能USART接收中断;

    5)    使能USART;

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

    2.    代码分析
    GPIO和USART宏定义

    代码清单 201 GPIOUSART宏定义

    #define DEBUG_USART USART1

    #define DEBUG_USART_CLK RCC_APB2Periph_USART1

    #define DEBUG_USART_BAUDRATE 115200 //串口波特率

    4

    #define DEBUG_USART_RX_GPIO_PORT GPIOA

    #define DEBUG_USART_RX_GPIO_CLK RCC_AHB1Periph_GPIOA

    #define DEBUG_USART_RX_PIN GPIO_Pin_10

    #define DEBUG_USART_RX_AF GPIO_AF_USART1

    #define DEBUG_USART_RX_SOURCE GPIO_PinSource10

    10

    11 #define DEBUG_USART_TX_GPIO_PORT GPIOA

    12 #define DEBUG_USART_TX_GPIO_CLK RCC_AHB1Periph_GPIOA

    13 #define DEBUG_USART_TX_PIN GPIO_Pin_9

    14 #define DEBUG_USART_TX_AF GPIO_AF_USART1

    15 #define DEBUG_USART_TX_SOURCE GPIO_PinSource9

    16

    17 #define DEBUG_USART_IRQHandler USART1_IRQHandler

    18 #define DEBUG_USART_IRQ USART1_IRQn

    使用宏定义方便程序移植和升级,根据图 2011电路,我们选择使用USART1,设定波特率为115200,一般我们会默认使用"8-N-1"参数,即8个数据位、不用校验、一位停止位。查阅表 203可知USART1TX线可对于PA9PB6引脚,RX线可对于PA10PB7引脚,这里我们选择PA9以及PA10引脚。最后定义中断相关参数。

    嵌套向量中断控制器NVIC配置

    代码清单 202 中断控制器NVIC配置

    static void NVIC_Configuration(void)

    {

    NVIC_InitTypeDef NVIC_InitStructure;

    4

    /* 嵌套向量中断控制器组选择 */

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

    7

    /* 配置USART为中断源 */

    NVIC_InitStructure.NVIC_IRQChannel = DEBUG_USART_IRQ;

    10 /* 抢断优先级为1 */

    11 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

    12 /* 子优先级为1 */

    13 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

    14 /* 使能中断 */

    15 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    16 /* 初始化配置NVIC */

    17 NVIC_Init(&NVIC_InitStructure);

    18 }

    19

    在中断章节已对嵌套向量中断控制器的工作机制做了详细的讲解,这里我们就直接使用它,配置USART作为中断源,因为本实验没有使用其他中断,对优先级什么具体要求。

    USART初始化配置

    代码清单 203 USART初始化配置

    void Debug_USART_Config(void)

    {

    GPIO_InitTypeDef GPIO_InitStructure;

    USART_InitTypeDef USART_InitStructure;

    /* 使能 USART GPIO 时钟 */

    RCC_AHB1PeriphClockCmd(DEBUG_USART_RX_GPIO_CLK |

    DEBUG_USART_TX_GPIO_CLK,

    ENABLE);

    9

    10 /* 使能 USART 时钟 */

    11 RCC_APB2PeriphClockCmd(DEBUG_USART_CLK, ENABLE);

    12

    13 /* GPIO初始化 */

    14 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

    15 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;

    16 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    17

    18 /* 配置Tx引脚为复用功能 */

    19 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

    20 GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_PIN ;

    21 GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure);

    22

    23 /* 配置Rx引脚为复用功能 */

    24 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

    25 GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_PIN;

    26 GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure);

    27

    28 /* 连接 PXx  USARTx_Tx*/

    29 GPIO_PinAFConfig(DEBUG_USART_RX_GPIO_PORT,

    30 DEBUG_USART_RX_SOURCE,

    31 DEBUG_USART_RX_AF);

    32

    33 /* 连接 PXx  USARTx__Rx*/

    34 GPIO_PinAFConfig(DEBUG_USART_TX_GPIO_PORT,

    35 DEBUG_USART_TX_SOURCE,

    36 DEBUG_USART_TX_AF);

    37

    38 /* 配置串DEBUG_USART 模式 */

    39 /* 波特率设置:DEBUG_USART_BAUDRATE */

    40 USART_InitStructure.USART_BaudRate = DEBUG_USART_BAUDRATE;

    41 /* 字长(数据位+校验位)8 */

    42 USART_InitStructure.USART_WordLength = USART_WordLength_8b;

    43 /* 停止位:1个停止位 */

    44 USART_InitStructure.USART_StopBits = USART_StopBits_1;

    45 /* 校验位选择:不使用校验 */

    46 USART_InitStructure.USART_Parity = USART_Parity_No;

    47 /* 硬件流控制:不使用硬件流 */

    48 USART_InitStructure.USART_HardwareFlowControl =

    49 USART_HardwareFlowControl_None;

    50 /* USART模式控制:同时使能接收和发送 */

    51 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

    52 /* 完成USART初始化配置 */

    53 USART_Init(DEBUG_USART, &USART_InitStructure);

    54

    55 /* 嵌套向量中断控制器NVIC配置 */

    56 NVIC_Configuration();

    57

    58 /* 使能串口接收中断 */

    59 USART_ITConfig(DEBUG_USART, USART_IT_RXNE, ENABLE);

    60

    61 /* 使能串口 */

    62 USART_Cmd(DEBUG_USART, ENABLE);

    63 }

    64

    使用GPIO_InitTypeDefUSART_InitTypeDef结构体定义一个GPIO初始化变量以及一个USART初始化变量,这两个结构体内容我们之前已经有详细讲解。

    调用RCC_AHB1PeriphClockCmd函数开启GPIO端口时钟,使用GPIO之前必须开启对应端口的时钟。使用RCC_APB2PeriphClockCmd函数开启USART时钟。

    使用GPIO之前都需要初始化配置它,并且还要添加特殊设置,因为我们使用它作为外设的引脚,一般都有特殊功能。我们在初始化时需要把它的模式设置为复用功能。

    每个GPIO都可以作为多个外设的特殊功能引脚,比如PA10这个引脚不仅仅可以作为普通的输入\输出引脚,还可以作为USART1RX线引脚(USART1_RX)、定时器1通道3引脚(TIM1_CH3)、全速OTGID引脚(OTG_FS_ID)以及DCMI的数据1引脚(DCMI_D1)这四个外设的功能引脚,我们只能从中选择一个使用,这时就通过GPIO引脚复用功能配置(GPIO_PinAFConfig)函数实现复用功能引脚的连接。

    这时我们可能会想如果程序把PA10用于TIM1_CH3,此时USART1_RX就没办法使用了,那岂不是不能使用USART1了,实际上情况没有这么糟糕的,查阅表 203我们可以看到USART1_RX不仅仅只有PA10,还可以是PB7。所以此时我们可以PB7这个引脚来实现USART1通信。那要是PB7也是被其他外设占用了呢?那就没办法了,只能使用其他USART

    GPIO_PinAFConfig函数接收三个参数,第一个参数为GPIO端口,比如GPIOA;第二个参数是指定要复用的引脚号,比如GPIO_PinSource10;第三个参数是选择复用外设,比如GPIO_AF_USART1。该函数最终操作的是GPIO复用功能寄存器GPIO_AFRHGPIO_AFRL,分高低两个。

    接下来,我们配置USART1通信参数并调用USART初始化函数完成配置。

    程序用到USART接收中断,需要配置NVIC,这里调用NVIC_Configuration函数完成配置。配置NVIC就可以调用USART_ITConfig函数使能USART接收中断。

    最后调用USART_Cmd函数使能USART

    字符发送

    代码清单 204 字符发送函数

    /***************** 发送一个字符 **********************/

    void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch)

    {

    /* 发送一个字节数据到USART */

    USART_SendData(pUSARTx,ch);

    6

    /* 等待发送数据寄存器为空 */

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

    }

    10

    11 /***************** 发送字符串 **********************/

    12 void Usart_SendString( USART_TypeDef * pUSARTx, char *str)

    13 {

    14 unsigned int k=0;

    15 do {

    16 Usart_SendByte( pUSARTx, *(str + k) );

    17 k++;

    18 while (*(str + k)!='\0');

    19

    20 /* 等待发送完成 */

    21 while (USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET) {

    22 }

    23 }

    Usart_SendByte函数用来在指定USART发送一个ASCLL码值字符,它有两个形参,第一个为USART,第二个为待发送的字符。它是通过调用库函数USART_SendData来实现的,并且增加了等待发送完成功能。通过使用USART_GetFlagStatus函数来获取USART事件标志来实现发送完成功能等待,它接收两个参数,一个是USART,一个是事件标志。这里我们循环检测发送数据寄存器为空这个标志,当跳出while循环时说明发送数据寄存器为空这个事实。

    Usart_SendString函数用来发送一个字符串,它实际是调用Usart_SendByte函数发送每个字符,直到遇到空字符才停止发送。最后使用循环检测发送完成的事件标志来实现保证数据发送完成后才退出函数。

    USART中断服务函数

    代码清单 205 USART中断服务函数

    void DEBUG_USART_IRQHandler(void)

    {

    uint8_t ucTemp;

    if (USART_GetITStatus(DEBUG_USART,USART_IT_RXNE)!=RESET) {

    ucTemp = USART_ReceiveData( DEBUG_USART );

    USART_SendData(DEBUG_USART,ucTemp);

    }

    8

    }

    这段代码是存放在stm32f4xx_it.c文件中的,该文件用来集中存放外设中断服务函数。当我们使能了中断并且中断发生时就会执行中断服务函数。

    我们在代码清单 203使能了USART接收中断,当USART有接收到数据就会执行DEBUG_USART_IRQHandler函数。USART_GetITStatus函数与USART_GetFlagStatus函数类似用来获取标志位状态,但USART_GetITStatus函数是专门用来获取中断事件标志的,并返回该标志位状态。使用if语句来判断是否是真的产生USART数据接收这个中断事件,如果是真的就使用USART数据读取函数USART_ReceiveData读取数据到指定存储区。然后再调用USART数据发送函数USART_SendData把数据又发送给源设备。

    主函数

    代码清单 206 主函数

    int main(void)

    {

    /*初始化USART 配置模式为 115200 8-N-1,中断接收*/

    Debug_USART_Config();

    5

    Usart_SendString( DEBUG_USART,"这是一个串口中断接收回显实验\n");

    7

    while (1) {

    9

    10 }

    11 }

    首先我们需要调用Debug_USART_Config函数完成USART初始化配置,包括GPIO配置,USART配置,接收中断使用等等信息。

    接下来就可以调用字符发送函数把数据发送给串口调试助手了。

    最后主函数什么都不做,只是静静地等待USART接收中断的产生,并在中断服务函数把数据回传。

    20.5.3 下载验证

    保证开发板相关硬件连接正确,用USB线连接开发板"USB TO UART"接口跟电脑,在电脑端打开串口调试助手,把编译好的程序下载到开发板,此时串口调试助手即可收到开发板发过来的数据。我们在串口调试助手发送区域输入任意字符,点击发送按钮,马上在串口调试助手接收区即可看到相同的字符。

     2012 实验现象

    20.6 USART1指令控制RGB彩灯实验

    在学习C语言时我们经常使用C语言标准函数库输入输出函数,比如printfscanfgetchar等等。为让开发板也支持这些函数需要把USART发送和接收函数添加到这些函数的内部函数内。

    正如之前所讲,可以在串口调试助手输入指令,让开发板根据这些指令执行一些任务,现在我们编写让程序接收USART数据,根据数据内容控制RGB彩灯的颜色。

    20.6.1 硬件设计

    硬件设计同第一个实验。

    20.6.2 软件设计

    这里只讲解核心的部分代码,有些变量的设置,头文件的包含等并没有涉及到,完整的代码请参考本章配套的工程。我们创建了两个文件:bsp _usart.cbsp _usart.h文件用来存放USART驱动程序及相关宏定义。

    1.    编程要点

    1)    初始化配置RGB彩色灯GPIO;

    2)    使能RX和TX引脚GPIO时钟和USART时钟;

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

    4)    配置USART参数;

    5)    使能USART;

    6)    获取指令输入,根据指令控制RGB彩色灯。

    2.    代码分析
    GPIO和USART宏定义

    代码清单 207 GPIOUSART宏定义

    
    						1 //引脚定义
    			

    /*******************************************************/

    #define USARTx USART1

    4

    /* 不同的串口挂载的总线不一样,时钟使能函数也不一样,移植时要注意

    串口16 RCC_APB2PeriphClockCmd

    串口2/3/4/5/7 RCC_APB1PeriphClockCmd

    */

    #define USARTx_CLK RCC_APB2Periph_USART1

    10 #define USARTx_CLOCKCMD RCC_APB2PeriphClockCmd

    11 #define USARTx_BAUDRATE 115200 //串口波特率

    12

    13 #define USARTx_RX_GPIO_PORT GPIOA

    14 #define USARTx_RX_GPIO_CLK RCC_AHB1Periph_GPIOA

    15 #define USARTx_RX_PIN GPIO_Pin_10

    16 #define USARTx_RX_AF GPIO_AF_USART1

    17 #define USARTx_RX_SOURCE GPIO_PinSource10

    18

    19 #define USARTx_TX_GPIO_PORT GPIOA

    20 #define USARTx_TX_GPIO_CLK RCC_AHB1Periph_GPIOA

    21 #define USARTx_TX_PIN GPIO_Pin_9

    22 #define USARTx_TX_AF GPIO_AF_USART1

    23 #define USARTx_TX_SOURCE GPIO_PinSource9

    24

    25 /************************************************************/

    使用宏定义方便程序移植和升级,这里我们可以USART1,设定波特率为115200

    USART初始化配置

    代码清单 208 USART初始化配置

    void USARTx_Config(void)

    {

    GPIO_InitTypeDef GPIO_InitStructure;

    USART_InitTypeDef USART_InitStructure;

    5

    RCC_AHB1PeriphClockCmd(USARTx_RX_GPIO_CLK|USARTx_TX_GPIO_CLK,ENABLE);

    7

    /* 使能 USART 时钟 */

    USARTx_CLOCKCMD(USARTx_CLK, ENABLE);

    10

    11 /* GPIO初始化 */

    12 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

    13 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;

    14 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    15

    16 /* 配置Tx引脚为复用功能 */

    17 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

    18 GPIO_InitStructure.GPIO_Pin = USARTx_TX_PIN ;

    19 GPIO_Init(USARTx_TX_GPIO_PORT, &GPIO_InitStructure);

    20

    21 /* 配置Rx引脚为复用功能 */

    22 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

    23 GPIO_InitStructure.GPIO_Pin = USARTx_RX_PIN;

    24 GPIO_Init(USARTx_RX_GPIO_PORT, &GPIO_InitStructure);

    25

    26 /* 连接 PXx  USARTx_Tx*/

    27 GPIO_PinAFConfig(USARTx_RX_GPIO_PORT,USARTx_RX_SOURCE,USARTx_RX_AF);

    28

    29 /* 连接 PXx  USARTx__Rx*/

    30 GPIO_PinAFConfig(USARTx_TX_GPIO_PORT,USARTx_TX_SOURCE,USARTx_TX_AF);

    31

    32 /* 配置串DEBUG_USART 模式 */

    33 /* 波特率设置:DEBUG_USART_BAUDRATE */

    34 USART_InitStructure.USART_BaudRate = USARTx_BAUDRATE;

    35 /* 字长(数据位+校验位)8 */

    36 USART_InitStructure.USART_WordLength = USART_WordLength_8b;

    37 /* 停止位:1个停止位 */

    38 USART_InitStructure.USART_StopBits = USART_StopBits_1;

    39 /* 校验位选择:偶校验 */

    40 USART_InitStructure.USART_Parity = USART_Parity_No;

    41 /* 硬件流控制:不使用硬件流 */

    42 USART_InitStructure.USART_HardwareFlowControl =

    43 USART_HardwareFlowControl_None;

    44 /* USART模式控制:同时使能接收和发送 */

    45 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

    46 /* 完成USART初始化配置 */

    47 USART_Init(USARTx, &USART_InitStructure);

    48

    49 /* 使能串口 */

    50 USART_Cmd(USARTx, ENABLE);

    51 }

    使用GPIO_InitTypeDefUSART_InitTypeDef结构体定义一个GPIO初始化变量以及一个USART初始化变量,这两个结构体内容我们之前已经有详细讲解。

    调用RCC_AHB1PeriphClockCmd函数开启GPIO端口时钟,使用GPIO之前必须开启对应端口的时钟。

    初始化配置RX线和TX线引脚为复用功能,并将指定的GPIO连接至USART1,然后配置串口的工作参数为115200-8-N-1。最后调用USART_Cmd函数使能USART

    重定向prinft和scanf函数

    代码清单 209 重定向输入输出函数

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

    int fputc(int ch, FILE *f)

    {

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

    USART_SendData(USARTx, (uint8_t) ch);

    6

    /* 等待发送完毕 */

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

    9

    10 return (ch);

    11 }

    12

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

    14 int fgetc(FILE *f)

    15 {

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

    17 while (USART_GetFlagStatus(USARTx, USART_FLAG_RXNE) == RESET);

    18

    19 return (int)USART_ReceiveData(USARTx);

    20 }

    C语言标准库中,fputc函数是printf函数内部的一个函数,功能是将字符ch写入到文件指针f所指向文件的当前写指针位置,简单理解就是把字符写入到特定文件中。我们使用USART函数重新修改fputc函数内容,达到类似"写入"的功能。

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

    还有一点需要注意的,使用fputfgetc函数达到重定向C语言标准库输入输出函数必须在MDK的工程选项把"Use MicroLIB"勾选上,MicoroLIB是缺省C库的备选库,它对标准C库进行了高度优化使代码更少,占用更少资源。

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

    输出提示信息

    代码清单 2010 输出提示信息

    static void Show_Message(void)

    {

    printf("\r\n这是一个通过串口通信指令控制RGB彩灯实验 \n");

    printf("使用 USART1 参数为:%d 8-N-1 \n",USARTx_BAUDRATE);

    printf("开发板接到指令后控制RGB彩灯颜色,指令对应如下:\n");

    printf(指令 ------ 彩灯颜色 \n");

    printf(" 1 ------  \n");

    printf(" 2 ------ 绿 \n");

    printf(" 3 ------  \n");

    10 printf(" 4 ------  \n");

    11 printf(" 5 ------  \n");

    12 printf(" 6 ------  \n");

    13 printf(" 7 ------  \n");

    14 printf(" 8 ------  \n");

    15 }

    Show_Message函数全部是调用printf函数,"打印"实验操作信息到串口调试助手。

    主函数

    代码清单 2011 主函数

    int main(void)

    {

    char ch;

    4

    /* 初始化RGB彩灯 */

    LED_GPIO_Config();

    7

    /* 初始化USART 配置模式为 115200 8-N-1 */

    USARTx_Config();

    10

    11 /* 打印指令输入提示信息 */

    12 Show_Message();

    13 while (1)

    14 {

    15 /* 获取字符指令 */

    16 ch=getchar();

    17 printf("接收到字符:%c\n",ch);

    18

    19 /* 根据字符指令控制RGB彩灯颜色 */

    20 switch (ch)

    21 {

    22 case '1':

    23 LED_RED;

    24 break;

    25 case '2':

    26 LED_GREEN;

    27 break;

    28 case '3':

    29 LED_BLUE;

    30 break;

    31 case '4':

    32 LED_YELLOW;

    33 break;

    34 case '5':

    35 LED_PURPLE;

    36 break;

    37 case '6':

    38 LED_CYAN;

    39 break;

    40 case '7':

    41 LED_WHITE;

    42 break;

    43 case '8':

    44 LED_RGBOFF;

    45 break;

    46 default:

    47 /* 如果不是指定指令字符,打印提示信息 */

    48 Show_Message();

    49 break;

    50 }

    51 }

    52 }

    首先我们定义一个字符变量来存放接收到的字符。

    接下来调用LED_GPIO_Config函数完成RGB彩色GPIO初始化配置,该函数定义在bsp_led.c文件内。

    调用USARTx_Config函完成USART初始化配置。

    Show_Message函数使用printf函数打印实验指令说明信息。

    getchar函数用于等待获取一个字符,并返回字符。我们使用ch变量保持返回的字符,接下来判断ch内容执行对应的程序了。

    我们使用switch语句判断ch变量内容,并执行对应的功能程序。

    20.6.3 下载验证

    保证开发板相关硬件连接正确,用USB线连接开发板"USB TO UART"接口跟电脑,在电脑端打开串口调试助手,把编译好的程序下载到开发板,此时串口调试助手即可收到开发板发过来的数据。我们在串口调试助手发送区域输入一个特定字符,点击发送按钮,RGB彩色灯状态随之改变。

    20.7 每课一问

    1、串口1实验中发送的数据都是8位的,如果要发送的数据是16位的话,怎么办,程序应该怎么修改?

    答案如下

    /***************** 发送一个16位数 **********************/

    void Usart_SendHalfWord( USART_TypeDef * pUSARTx, uint16_t ch)

    {

    uint8_t temp_h, temp_l;

    5

    /* 取出高八位 */

    temp_h = (ch&0XFF00)>>8;

    /* 取出低八位 */

    temp_l = ch&0XFF;

    10

    11 /* 发送高八位 */

    12 USART_SendData(pUSARTx,temp_h);

    13 while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);

    14

    15 /* 发送低八位 */

    16 USART_SendData(pUSARTx,temp_l);

    17 while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);

    18 }

    2、改写USART1指令控制RGB彩灯实验程序,把串口1换成串口2。

    开源共享,共同进步。
    展开全文
  • 几个串口通信协议的整理

    千次阅读 2019-02-18 09:55:21
    一、UART UART是一个大家族,其包括了RS232、RS499、RS423、RS422和RS485等接口标准规范和总线标准规范。它们的主要区别在于其各自的电平范围不相同。...1.2 通信协议 将传输数据的每个字符一位接一位地传输。 h...

    一、UART

    UART是一个大家族,其包括了RS232、RS499、RS423、RS422和RS485等接口标准规范和总线标准规范。它们的主要区别在于其各自的电平范围不相同。

    嵌入式设备中常常使用到的是TTL、TTL转RS232的这种方式。常用的就三根引线:发送线TX、接收线RX、电平参考地线GND。

    1.1 电路示意图

    img

    1.2 通信协议

    将传输数据的每个字符一位接一位地传输。

    https://img-blog.csdn.net/20170719232822650” alt=”串口数据传输示意图.png” title=”” />

    起始位:先发出一个逻辑”0”的信号,表示传输字符的开始。

    数据位:紧接着起始位之后。数据位的个数可以是4、5、6、7、8等,构成一个字符。通常采用ASCII码。

    奇偶校验位:数据位加上这一位后,使得“1”的位数应为偶数(偶校验)或奇数(奇校验),以此来校验资料传送的正确性。

    停止位:它是一个字符数据的结束标志。可以是1位、1.5位、2位的高电平。

    空闲位:处于逻辑“1”状态,表示当前线路上没有资料传送。

    波特率:数据传输的速率。有以下几个档位:300、600、1200、2400、4800、9600、19200、38400、43000、56000、57600、115200.当然也可以自定义。在数据传输和接收双方,需要预先统一波特率,以便正确的传输数据。

    二、I2C 总线

    2.1 电路示意图

    I²C (Inter-Integrated Circuit)。其拥有一根数据线SDA和一根时钟线SCL。其总线通过上拉电阻与电源相连接。每个接到I2C总线上的器件都有唯一的地址。其中,主动发起操作的一方为主机,另外一方为从机。

    IIC 总线

    2.2 数据传输

    当没有数据传输的时候,两根总线都为高电平;当采集IIC上的数据时,其时钟线SCL必须是高电平且SDA的数据必须保持稳定不变—将SDA的电平与SCL的高电平进行“与”操作后,以便确定SDA上是1还是0;在SCL为低电平的时候,SDA上的数据可以进行跳变。

    数据传输开始时,需要发送一个起始信号;数据传输结束后,需要发送一个终止信号;每8bit数据传输结束,都需要一个ACK。起止信号都有Master发出,而ACK则可能由Master或者SLAVE来发出。数据的传输采用大端传输。

    开始信号:SCL为高电平,SDA的电平由高跳到低表示开始信号。

    终止信号:SCL为高电平,SDA的电平由低跳到高表示终止信号。
    IIC时序

    2.3 数据协议

    IIC数据协议

    2.4 I2C读写流程

    I2C读写流程

    I2C写寄存器的标准流程.png

    I2C读寄存器的标准流程.png

    三、SPI总线

    SPI(Serial Peripheral Interface)是一种串行串行同步通讯协议,由一个主设备和一个或多个从设备组成。其拥有四根(类)硬脚引线,分别为 SDI(串行数据输入),SDO(串行数据输出),SCK(串行移位时钟),CS(片选)。因为一个主设备可以挂多个从设备,则通过片选引脚对从设备进行选择。从设备的工作时钟则是来自于主设备的SCK线。

    3.1 电路示意图

    SPI总线

    3.2 数据的传输

    SPI在数据传输的时候,需要确定两件事情:其一,数据是在时钟的上升沿采集还是下降沿采集;其二,时钟的初始(空闲)状态是为高电平还是低电平。而I2C的空闲状态,时钟线为高电平;数据采集的时候,时钟线也为高电平。但SPI给出了更自由的方式。

    CPOL:时钟极性, 表示 SPI 在空闲时, 时钟信号是高电平还是低电平。

    CPHA:时钟相位, 表示 SPI 设备是在 SCK 管脚上的时钟信号变为上升沿时触发数据采样, 还是在时钟信号变为下降沿时触发数据采样。

    那么,SPI CPOL有两种可能,CPHA有两种可能,则SPI数据传输就有四种可能—按照标准的说法,SPI数据传输就有四种模式。

    SPI数据传输就有四种模式

    SPIMode0.png

    SPIMode2.png

    这里写图片描述

    3.3 SPI读写

    SPI在硬件设计上采用的双数据线制,根据设计,在SPI通信过程中,主从设备之间会形成一个数据环形链路—也即是,主设备向从设备写一次数据,从设备就会回一次数据(至于该从设备回复的数据是否有效,则另当别论—如果有效,主设备就把它读入;如果无效,则丢弃即可)。

    SPI主从连接.png

    SPI读写.png

    展开全文
  • 什么是串口通信协议

    2020-10-10 10:25:23
    ARM体系结构-串口通信 一、什么是串口通信 1、串口通信属于基层基本性的通信规约,收发双方事先规定好通信参数。 2、它自己本身不会去协商通信参数,需要通信前通信双方事先约定好通信参数来进行通信。 3、因此,...

    ARM体系结构-串口通信

    一、什么是串口通信

    1、串口通信属于基层基本性的通信规约,收发双方事先规定好通信参数。
    2、它自己本身不会去协商通信参数,需要通信前通信双方事先约定好通信参数来进行通信。
    3、因此,若是收发方的任何一个关键参数设置错误,都会导致通信失败。譬如波特率调错了,发送方发送没问题,接收方也能接收,但是接收到全是乱码。
    4、信息以二进制流的方式在信道上传输,串口通信的发送方每隔一定时间(时间固定为1/波特率,单位是秒)将有效信息(1或者0)放到通信线上去,逐个二进制位的进行发送。
    5、接收方通过定时(起始时间由读到起始位标志开始,间隔时间由波特率决定)读取通信线上的电平高低来区分发送给我的是1还是0。依次读取数据位、奇偶校验位、停止位,停止位就表示这一个通信单元(帧)结束,然后中间是不定长短的非通信时间(发送方有可能紧接着就发送第二帧,也可能半天都不发第二帧,这就叫异步通信),下来就是第二帧·····
    6、通过串口不管发数字、还是文本还是命令还是什么,都要先对发送内容进行编码,编码成二进制再进行逐个位的发送。
    7、串口发送的一般都是字符,一般都是ASCII码编码后的字符,所以一般设置数据位都是8,方便刚好一帧发送1个字符。

    二、串口通信线

    1、任何通信都要有信息传输载体,或者是有线的或者是无线的。串口为有线的,有三根主要通信线:Rx Tx GND
    2、串口通信线最少需要2根(GND和信号线),可以实现单工通信,也可以使用3根通信线(Tx、Rx、GND)来实现全双工。

    三、串口通信协议

    1、串行接口是一种可以将接收来自CPU的并行数据字符转换为连续的串行数据流发送出去,同时可将接收的串行数据流转换为并行的数据字符供给CPU的器件。一般完成这种功能的电路,我们称为串行接口电路。
    2、串口按位(bit)发送和接收字节的通信方式。
    3、串口通信的特点:异步、电平信号、串行
    (1)异步:串口通信的发送方和接收方之间是没有统一的时钟信号的。
    (2)电平信号:串口通信出现的时间较早,速率较低,传输的距离较近,所以干扰还不太明显,因此当时使用了电平信号传输。后期出现的传输协议都改成差分信号传输了。
    (3)串行:串口通信每次同时只能传输1个二进制位。

    4、串口通信时因为是异步通信,所以通信双方必须事先约定好通信参数,这些通信参数包括:波特率、数据位、奇偶校验位、停止位(串口通信中起始位定义是唯一的,所以一般不用选择)
    (1)通信单元
    ①串口通信时,收发是一个周期一个周期进行的,每周期传输n个二进制位。这一个周期就叫做一个通信单元,一个通信单元是由:起始位+数据位+奇偶校验位+停止位组成的。
    ②起始位表示发送方要开始发送一个通信单元;数据位是一个通信单元中发送的有效信息位;奇偶校验位是用来校验数据位,以防止数据位出错的;停止位是发送方用来表示本通信单元结束标志的。

    (2)波特率(bandrate):
    ①指的是串口通信的速率,也就是串口通信时每秒钟可以传输多少个二进制位。譬如每秒种可以传输9600个二进制位(传输一个二进制位需要的时间是1/9600秒,也就是104us),波特率就是9600.
    ②串口通信的波特率不能随意设定,而应该在一些值中去选择。一般最常见的波特率是9600或者115200(低端单片机如51常用9600,高端单片机和嵌入式SoC一般用115200).
    ③为什么波特率不可以随便指定?主要是因为:第一,通信双方必须事先设定相同的波特率这样才能成功通信,如果发送方和接收方按照不同的波特率通信则根本收不到,因此波特率最好是大家熟知的而不是随意指定的。第二,常用的波特率经过长久发展,就形成了共识,大家常用就是9600或者115200.

    (3)起始位:起始位的定义是串口通信标准事先指定的,是由通信线上的电平变化来反映的。
    (4)数据位是本次通信真正要发送的有效数据,串口通信一次发送多少位有效数据是可以设定的(一般可选的有6、7、8、9,99%情况下我们都是选择8位数据位。因为我们一般通过串口发送的文字信息都是ASCII码编码的,而ASCII码中一个字符刚好编码为8位。)
    (5)奇偶校验位是用来给数据位进行奇偶校验(把待校验的有效数据逐个位的加起来,总和为奇数奇偶校验位就为1,总和为偶数奇偶校验位就为0)的,可以在一定程度上防止位反转。
    (6)停止位的定义是串口通信标准事先指定的,是由通信线上的电平变化来反映的。常见的有1位停止位,1.5位停止位,2位停止位等。99%情况下都是用1位停止位。

    四、DB9接口

    1、DB9接口是串口通信早期比较常用的一种规范化接口。
    2、串行通信在早期是计算机与外界通信的主要手段,那时候的计算机都有标准配置的串口以实现和外部通信。那时候就定义了一套标准的串口规约,DB9接口就是标准接口。
    3、DB9接口中有9根通信线,其中3根很重要,为GND、Tx、Rx,必不可少;剩余6根都是和流控有关的,现代我们使用串口都是用来做调试一般都禁用流控,所以这6根没用。
    4、流控的目的是让串口通信非常可靠,在发送方速率比接收方快的时候流控可以保证发送和接收不会漏掉东西。
    5、现在一般使用串口时要记得把流控禁止掉,不然可能发生意想不到的问题。
    6、现在计算机之间有更好更高级(usb、internet)的通讯方式,串口已经基本被废弃了。现在串口的用途更多是SoC用来输出调试信息的。由于调试信息不是关键性信息、而且由于硬件发展串口本身速度已经相对慢的要死了,所以硬件都能协调发送和接收速率,因此流控已经失去意义了,所以现在基本都废弃了。

    展开全文
  • 常见的串行通信协议

    万次阅读 2016-05-08 11:25:58
    为确保通信可靠,可以在通信两边接共地;因此,完整的UART通信只需最少3根线即可。 RxD是发送数据线,TxD是接收数据线,通信双方使用交叉互联,RxD接对方TxD,TxD接对方RxD。UART使用标准的TTL/CMOS电平(0~5V,0~...
  • 串口通信协议简介

    万次阅读 2020-01-07 13:20:03
    串口通讯(Serial Communication)是一种设备间非常常用的串行通讯方式,因为它简单便捷,大部分电子设备都支持该通讯方式,电子工程师在调试设备时也经常使用该通讯方式输出调试信息。 在计算机科学里,大部分...
  • 串口通讯—通信协议

    万次阅读 2015-10-15 09:09:47
    所谓通信协议是指通信双方的一种约定。约定包括对数据格式、同步方式、传送速度、传送步骤、检纠错方式以及控制字符定义等问题做出统一规定,通信双方必须共同遵守。因此,也叫做通信控制规程,或称传输控制规程,它...
  • 串口通讯协议介绍

    千次阅读 2019-06-26 15:07:28
    一、通信协议 是指通信双方的一种约定,包括对于同步方式、数据格式、传送速度、传送步骤、检纠错方式、控制字符的定义等,做出统一的规定,需要通信双方的共同遵守;也叫做通信控制规程、传输控制规程,它属于ISO...
  • 单片机的串口通信协议

    千次阅读 2015-03-03 14:12:14
    单片机的选择和串行通信协议的设计_高怀举
  • UART串口协议

    万次阅读 2018-02-10 18:07:53
    通用异步收发传输器(Universal Asynchronous Receiver/Transmitter),通常称作UATR,是一种异步收发传输器。将数据由串行通信与并行通信间做传输...1、UART通信协议 UART作为异步串口通信协议的一种,工作原理是...
  • 通讯的方式分类: 1.并行通信:是指数据的各位同时在多根数据线上发送或接收。如下图 并行通信的特点:控制简单,传输速度快;由于传输线较多,适用...在串行通信中,根据对数据流的分界、定时以及同步方案方法...
  • UART串口通信协议概述

    千次阅读 2018-12-12 22:05:38
    1.UART协议介绍 UART是一种通用串行数据总线,用于异步通信。UART能实现双向通信,在嵌入式设计中,常用于主机与辅助设备通信。UART包括RS232、RS449、RS423等接口标准规范和总线标准规范,即UART是异步串行通信口...
  • 串口系统简图、时序图

    千次阅读 2018-05-21 16:17:41
    串口系统简图串口线程时序
  • 串行通讯的时序分析

    千次阅读 2016-03-13 09:59:39
    通信协议按时间分为:同步通信 和异步通信,按发送数据的位宽可分为串行通信和并行通信,串行通信里按通信数据传输的方向机是否同时收发程序通信又分为:单工,半双工,全双工。 区别:同步和异步: 同步是面向...
  • SCI,SPI,UART三种串行总线协议的区别

    万次阅读 2010-08-10 13:36:00
    前前后后分别接触到了这几种串行通信。刚开始自己的理解有多么的狭隘。。。做过才知道呵呵~   SCI (串行通讯接口)模块对其进行控制。(注:“SCI”首先由Motorola微串口微控制器而得名,SCI另一...
  • 串行接口与并行接口的概念与区别

    千次阅读 2019-04-03 19:58:29
    串行接口,简称串口,也就是COM接口,是采用串行通信协议的扩展接口。串口的出现是在1980年前后,数据传输率是115kbps~230kbps,串口一般用来连接鼠标和外置Modem以及老式摄像头和写字板等设备,目前部分新主板已...
  • SPI、I2C、UART三种串行总线的原理、区别及应用

    万次阅读 多人点赞 2018-10-24 11:50:18
    SPI协议解析,链接如下 https://blog.csdn.net/weiqifa0/article/details/82765892 I2C协议解析,链接如下 ... 串口UART串行总线协议 https://blog.csdn.net/weiqifa0/article/detai...
  • 这是英文的驱动器通讯协议说明书 过几天把这一块做好以后,在把中文的介绍放上来
  • UART/RS232传输协议

    千次阅读 2019-07-17 11:07:49
    一、RS232通信协议是目前最常用的一种全双工点对点式的异步串行通信协议接口标准。RS232接口标准由于出现较早,所以其目前存在很多问题。 (1)、接口电平值较高,易损坏接口电路的芯片。 (2)、传输速率较低,大约为...
  • 串口通信一般有两种方式: 1、字符 2、字节   各方讨论: UART传输只面向二进制的字节形式。  但是,二进制的形式可以通过其他编码转换方法  转到别的应用形态,字符只是其中一种。 ASCII方式传送字符,...
1 2 3 4 5 ... 20
收藏数 70,826
精华内容 28,330
关键字:

串行通信协议