串口通讯UART

版权声明:均是学习笔记、心得,如有冒犯,请指出,会及时处理。https://blog.csdn.net/qq_27485531 https://blog.csdn.net/qq_27485531/article/details/81293188

1、串行通信的的基本知识

在实际的工业生产,或者生活中,计算机的CPU要与外部的设备之间进行信息的交流,数据的交换,所有的这些信息交换均可称为通信。

通信的方式有两种,分别为串行通信和并行通信。我们通常根据实际信息传输的距离还决定采用哪种通信方式。

并行通信:

并行通信是指数据的各位同时进行传送(发送或者接收)的通信方式。其优点是传送速度快,缺点是数据有多少位,就需要有多少根传送线。

串行通信:

串行通信是指数据 一位一位的按顺序传送的通信,他的优点是传送线少(只需要一对传输线),特别适用于远距离的数据通信,缺点是传送速度低。

其通信的原理如下图所示

串行通信的数据传输方式:

分为3种:1、单向(单工)配置,只允许数据向一个方向传送。2、半双向(半双工)配置,允许数据向两个方向中的任一方向传送,但每次只能有一个站点在发送。3、全双向(全双工)配置,允许同时双向传送数据,因此,他要求两端的通信设备都具有完整和独立的发送和接收的能力。如下图所示

串行通信的通信方式

串行通信有两种基本的通信方式:同步通信和异步通信

1、异步通信

异步通信数据格式一般为字符格式

一个字符一个字符地传输,每个字符一位一位的传输,并且传输一个字符时,总是以“起始位”开始,以“停止位”结束,字符间没有固定的间隔要求。每一个字符的前面都有一位起始位(低电平),字符本身由5-7位数据位组成,接着字符后面是一位校验位(也可以没有校验位),最后一位或一位半或两位停止位,停止位后面是不定长的空闲位。停止位和空闲位都规定为高电平,这样就保证了起始位开始处有一个下跳沿。

                                       图一异步通信的传输方式

                                       图二异步通信的数据传输格式

2、同步通信

同步通信就比如说是老师发作业本,约定学习委员来取作业本。建立发送方时钟对接收方时钟的直接控制,使双方达到完全同步,而且传输数据的位之间的距离均为“位间隔”的整数倍,同时传送的字符之间不留间隙,即保持位同步关系,也保持字符同步关系。

同步通信使用的数据格式根据采用的控制规程(通信双方就如何交换信息所建立的一些规定和过程称为通信控制规程),可分为面向字符型面向位型两种,面向字符型数据格式又有单同步,双同步,和外同步之分。三个同步方式均以2个字节的冗余检验码CRC作为一帧信息的结束。

单同步:发送方先发送一个同步字符,再传送数据块,接收方检测到同步字符后接收数据

双同步:发送方先传送2个同步字符,再传送数据块,接收方检测到同步字符后接收数据;

外同步:用一条专用线来传送同步字符,以实现收发双方同步操作。

面向字符的同步协议(IBM的BSC协议)

该协议规定了10个特殊字符(称为控制字符)作为信息传输的标志。其格式为:

SYN SOH 标题STX数据块ETB/ETX块校验

SYN:同步字符,每帧可加1个(单同步)或2个(双同步)同步字符。

SOH:标题开始。

标题:Header,包含源地址(发送方的地址)、目的地址(接收方地址)、路由指示。

STX:正文开始。

数据块:正文,由多个字符组成。

ETB:块传输结束,标识本数据块结束。

ETX:全文结束(全文分为若干块传输)

块校验:对从SOH开始,直到ETB/ETX字段的检验码。

面向位的同步协议(ISO的HDLC)

一帧信息可以是任意位,用位组合标识帧的开始和结束。帧格式为:

F场A场C场I场FC场F场

F场:标志,作为一帧的开始和结束,标志字符8位,01111110

A场:地址,规定接收方可为8的整数位。接收方检查每个地址字节的第1位,如果为0,则后面跟着一个地址字节。若为1,则该字节为最后一个地址。

C场:控制场。指示信息场的类型,8位或者16位。若第一字节的第一位为0,则还有第二个字节也是控制场。

I场:信息场,要传送的数据。

FC场:帧校验场。16位循环冗余校验码CRC。除F场和自动插入的0位外,均参加CRC计算

采用同步通信时,将许多字符组成一个信息组,这样,字符可以一个接一个地传输,但是,在每组信息(通常称为帧)的开始要加上同步字符,在没有信息要传输时,要填上空字符,因为同步传输不允许有间隙。在同步传输过程中,一个字符可以对应5~8位。当然,对同一个传输过程,所有字符对应同样的数位,比如说N位,这样,传输时按每N位划分一个时间片,发送端在一个时间片中发送一个字符,接收方则在一个时间片中接收一个字符。

同步传输时,一个信息帧中包含许多字符,每个信息帧用同步字符作为开始,一般将同步字符和空字符用同一个代码。在整个系统中,由一个统一的时钟控制发送端的发送和空字符同同一个代码。接收端当检测到有一串数位和同步字符相匹配时,就认为开始一个信息帧,就把此后的数位作为实际传输信息来处理。

同步通信中,在数据开始传送前用同步字符来指示(常约定1~2个),并由时钟来实现发送端与接收端的同步

我们使用QQ的文件传输功能就可以看做是一个同步通信的例子,首先传文件的双方必须说好一个传文件的时间,如果双方有一个不在线上,就不能传输。其次,发送方发送文件命令后,接收方要确认是否接收,这个就是建立文件传输的过程,一旦传输开始,所有文件数据必须连续的传输过去,任何中断都将导致传输失败。

3、波特率

波特率即数据传速率,表示每秒传送二进制代码的位数,它的单位是b/s。波特率对于CPU与外界的通信是很重要的,假设数据传送的速率是120字符/s,而每个字符格式包含10个代码位(一个起始位,一个中止位、8位数据位D0-D7),这是传送的波特率为:10bit/字符*120字符/s = 1200 b/s。波特率即为1200 b/s。每一位的时间即为1/1200。

4、串行通信接口种类

根据串行通信格式及约定(如同步方式、通信速率、数据块格式等)不同,形成了许多串行通信接口标准,如常见的:

UART(串行异步通信接口)

USB(通用串行总线接口)

I2C(集成电路间的串行总线)

SPI(串行外设总线)

485总线、CAN总线接口等。

二、89c51串行口及应用

我所采用的单片机串口通信是用一个USB接口接了一个CH340(USB转异步串口)来进行计算机与单片机双方的通信,如下图所示

下图所用硬件原理图

当开关SW1按下之后,经过USB1再连接一个USB转异步通信串口芯片CH340,使计算机通过USB来与单片机进行通信。

串行通信的工作原理如下

串行通信必须保持设备的同步性,即1、数据双方必须采用统一的编码。2、通信双方必须使用相同的传送速率

1、89c51串行口特点

※全双工串口,能同时发送和接收数据

※可编程:其帧格式可以是8位,10位,11位,并能设置各种波特率

※发送完一个数据TI标志置1,接受完一个数据RI标志置1,可以工作在中断或查询方式

※波特率可以是固定的,也可以是由定时器1的溢出率来决定

※有一个地址相同的接受(发送)缓冲器SBUF(地址99H)

2、结构与工作原理

89c51通过引脚RXD(P3.0串行数据接收端)和引脚TXD(P3.1串行数据发送端)与外界进行通信。其内部结构简化图如图所示

图中有两个物理上独立的接收、发送缓冲器SBUF,它们占用同一地址99H,可同时发送。接收数据。发送缓冲器只能写入,不能读出;接收缓冲器只能读出,不能写入。

串行发送与接收的速率与移位时钟同步。89c51用定时器1作为串行通信的波特率发生器。T1溢出率经2分频(或不分频)后又经16分频作为串行发送或接收的移位脉冲。移位脉冲的速率即波特率。

从图中可以看出,接收器是双缓冲结构,在前一个字节被从接收缓冲器SBUF读出之前,第二个字节即开始接收(串行输入至移位寄存器),但是,在第二个字节接收完毕而前一个字节CPU未读取时,会丢失前一个字节。

串行口的发送和接收都是以特殊功能寄存器SBUF的名义进行读/写的。当向SBUF发送“写”命令时(SBUF = num,假设num是我已经定义好的一个变量),即是向发送缓冲器SBUF装载并开始由TXD引脚向外发送一帧数据,发送完后发送中断标志位TI则自动置1。

在满足串行口接收中断标志位RI = 0的条件下,置允许接收位REN = 1,就会接收一帧数据进入移位寄存器,并装载到接收SBUF中,同时使RI = 1,当发读SBUF命令时(num = SBUF),便由接收缓冲器SBUF取出信息通过89c51内部总线送CPU。

对于发送缓冲器,因为发送时CPU是主动的,不会产生重叠错误,一般不需要用双缓冲结构来保持最大传送速率。

3、 串行口控制字及控制寄存器

 89c51串行口是可编程接口,对它初始化编程只用两个控制字分别写入特殊功能寄存器SCON和电源控制寄存器PCON中即可。

1)SCON

SM0、SM1工作方式控制位

SM2:多机通信控制位,1-允许、0-不允许

REN:串行接收允许位。1-允许、0-不允许

TB8:发送数据第九位

RB8:接收数据第九位

TI:发送中断标志位

RI:接收中断标志位

①SM0和SM1 :串行口工作方式选择位 ,两个选择位对应四种通信方式,如下图所示,其中fosc是振荡频率

SM2:多机通信控制位,主要用于方式2和方式3。

若SM2 = 1;则允许多机通信。多机通信协议规定,第9位数据(D8)为1,说明本帧数据为地址帧;若第9位数据为0,则本帧数据为数据帧。当一个89c51(主机)与多个89c51(从机)通信时,所有从机的SM2位都置1,主机首先发送的一帧数据为地址,即某从机号,其中第9位为1,所有的从机接收数据后,将其中第9位数据装入RB8中。各个从机根据接收到的第9位数据(RB8中)的值来决定从机是否再接收主机的信息、若(RB8)= 0,说明是数据帧,则使接收中断标志位RI = 0,信息丢失,若RB8 = 1,说明是地址帧,数据装入SBUF并置RI = 1,中断所有从机,被寻址的目标从机清除SM2,以接收主机发来的一帧数据,其它从机仍然保持SM2 = 1。

若SM2 = 0,即不属于多机通信情况,则接收完一帧数据后,不管第9位数据是0还是1,都置RI = 1,接收到的数据装入SBUF中。在方式0时SM2必须置0。在方式1时,若SM2 = 1,则只有接收到有效停止位时,RI才置1,以便接收下一帧数据。

REN:允许接收控制位,由软件置1或清0

REN = 1时,允许接收,相当于串行接收的开关

REN = 0时,禁止接收

在串行通信接收控制过程中,如果满足RI = 0和REN = 1的条件,就允许接收。

TB8:发送数据的第9位(D8)装入TB8中。在方式2或方式3中,根据发送数据的需求由软件置位或复位。在许多通信协议中可用作奇偶校验位,也可以在多机通信中作为发送地址帧或者数据帧的标志位。

RB8:接收数据的第9位,原理同TB8

TI:发送中断标志位,在一帧数据发送完时被置位。在串行发送到停止位的开始时由硬件置位,可用软件查询。它同时也申请中断。TI置位意味着向CPU提供“发送缓冲器SBUF已空”的信息,CPU可以准备发送下一帧数据。串行口发送中断被响应后,TI不会自动清0,必须软件清0.

RI:接收中断标志,在接收到一帧数据后由硬件置位。当RI = 1时,申请中断,表示一帧数据接收结束,并已装入接收SBUF中,要求CPU取走数据,CPU响应中断,取走数据。RI位也必须由软件来清0,。

串行发送中断标志TI和接收中断标志RI是同一个中断源,CPU事先不知道是发送中断TI还是接收中断RI产生的中断请求,所以,在全双工通信时,必须由软件来判别。复位时SCON所有位都清0.

2)PCON

电源控制位寄存器PCON中只有SMOD位与串口工作有关,如下图所示

SMOD:波特率倍增位。在方式1、2、3中,当SMOD = 1时,波特率提高一倍。

4、串行通信工作方式

根据实际需要,89c51串口可以设置四种工作方式,可有8位、10位或11位帧格式

方式0:8位同步移位寄存器,以8位数据为一帧,不设起始位和停止位,先发送或接收最低位(用于I/O口扩展)。

 ※RXD:数据输入/输出端

※TXD:同步脉冲输出端,每个脉冲对应一个数据位

基本很少用到方式0,一般都是用到方式0是通过串口扩展8位并行I/O输出口,如下图所示

方式1:10位异步通信模式

一帧10位:起始位+8位数据位+停止位

波特率:定时器1作为波特率发生器,公式为

方式2和方式3:11位异步通讯方式

一帧11位:起始位+9位数据位+停止位

第九位数据位在TB8/RB8中,常用作校验位或者多机通信地址标识位或者数据标识位

波特率分别为:

发送:先填写TB8,写入SBUF(启动发送),发送完TI = 1.

接收:REN = 1,RI = 0且第9位为1(或SM2 = 0),将接收数据装入SBUF,第9位装入RB8,使RI = 1,否则丢弃接收数据,不置位RI。

接下来我用串口通信来实现计算机与51单片机之间的串口通信,计算机给单片机发送一个数,单片机接收后把这个数加1再发送给计算机,具体操作如下

#include<reg52.h>
#define uint unsigned int
void UART_Init();
uint num ;
/*
******************************************
**函数名称:主函数
*******************************************
*/
int main()
{
        UART_Init();
        while(1);
}
/*
*****************************************
**函数功能:串口初始化函数
*****************************************
*/
void UART_Init()
{
     
            TMOD = 0x20; //定时器0工作模式2,自动重装8位计数器
            TH1 = 0xfd;
            TL1 = 0xfd;//定时器溢出时,会自动将高8位中的值赋值给低8位.比特率9600
            TR1 = 1;
            SM0 = 0;
            SM1 = 1;
            REN = 1;
            EA = 1;
            ES = 1;
}
/*
********************************************
**函数名称:串口中断函数
********************************************
*/
void UART() interrupt 4
{
    if(RI == 1)        //如果接收到计算机发的数据
        {
            num = SBUF;  //取出数据
            num++;       
            RI = 0;       //清除标志位
            SBUF = num;  //把数据加1后再发送给计算机
        }
        if(TI == 1)    //如果发送完毕
        {
            TI = 0;       //清除标志位
        }
}
    
我用串口助手循环发送从1-8,单片机会返回2-9,实现现象如下:

猜你喜欢

转载自blog.csdn.net/qq_27485531/article/details/81293188