×
单片机 > 单片机程序设计 > 详情

51单片机之寄存器-3.3单片机串口通信之发送与接收

发布时间:2020-08-31 发布时间:
|
本节主要讲解单片机的通信。通信主要是指单片机与外界设备交流,也就是通过导线传送或者接收信息。举个例子来说明,你想把仓库A中的货物通过货车配送到仓库B,一共有8个箱子,每辆货车一次只能运送1个箱子。显然,如果只用一辆货车,那么需要8次运送完毕,如果使用8辆货车,那么一次就运送完了。同样,在单片机通信中也是如此。这个货车就是信息传输通道。货车数量越多,传输越快。如果只有一辆货车那么就是串行通信,如果是八辆货车就是并行通信。很明显,货车数量越多,运送的速度越快,但是成本越高。因此根据CPU与外设之间连线结构和数据传送方式的不同,可将通信分为并行通信和串行通信两种基本方式。很容易可以看出并行通信的特点是数据同时传送,速度快,效率高,但成本也高。串行通信的特点是传输线少,成本低,但传送速度慢。现在很多电脑没有并口接口了,这里我们只讲串行通行。
图1 串行通信示意图

由于现在很多笔记本已经没有串口,我们通常采用USB转串口。先来看图1中的一个例子,现在想让P1把在A地点的D3,D5,D8,D9,D11组球通过P2的帮忙一个一个传递到B点,要求按顺序传递,而且传递完成后不能打乱顺序。如果不做任何处理,只要P1在某一组中如D3组,有一个球传错或者漏传,那么将导致后面的传递全部错位。改进的方法就是在传每组第一个球时,先传个红色的标签,告诉P2接下来要传的是这一组的第一个球。当这一组传递完成后,再给一个绿色的标签,告诉P2,这一组的球传递完毕。这样即使某一组传错了,也不会影响下一组的传递。现在我们详细看看这个过程。(1) P1需要选择传哪一组的球。(2) 准备好标记 (3) 通知P2现在要开始工作. 同时在传递过程要保证P1和P2的速度一致,否则传递也会出问题。知道了这个例子,现在我们详细的来讨论一下串口异步通信。

图2 单片机串行通信示意图

如图所示,两个单片机的串行通信,传送一根线TXD,接收一根线RXD,现在我们只讨论传送这部分。设定单片机1为我们开发板上的型号STC89C52RC. 既然是传送,那么传送什么内容。现在假设我要传送0111000B(38H)这个数据。那么怎么让单片机知道我要传这个数据呢?如上图所示,只需要使用图中SBUF=dataTXD(即SBUF=0x38)这个语句。当单片机看到这条指令后,把0x38写入SBUF,就启动串行通信的发送。也就是说,这条语句告诉了单片机两个信息,1.发送什么内容,2.现在就开始发送。单片机就开始以0和1的方式开始发送了。那么这样又出现问题了,单片机2怎么知道单片机1要给我传数据了?最简单的方法的就是给需要传送的数据前后加个标签,这样两个标签之间的内容就是单片机1要传送的信息了。当然也可以在8位数据后添加其他标签,这个就是串口的传送方式了。这个由SCON串行控制器来设置:

这里我们选择工作方式1,SM0/SM1设置为0/1。8位数据位加起始位和停止位,一共10位,也称为一帧。那么这个起始位和停止位什么加入呢?当单片机TXD发送信息时,单片机就自动加入了。因此,这里我们总结一下,SBUF=dataTXD当执行到这条指令时,告诉了单片机三个重要信息,1. 要传送什么信息,2. 什么时候开始传, 3. 自动在这个数据前添加开始位和停止位。但是又有个问题,传多快呢?这里需要引入一个概念,波特率。波特率定义为每秒传输的码元个数,单位是波特(Baud),简写为B。而每秒钟传送的二进制数码的位数则定义为比特率,单位是比特每秒,b/s或bps。在串行通信系统中,传送的信号可能是二进制,八进制,十进制等,只有在二进制通信系统中波特率和比特率在数值上才是相等。本教程所描述的串行通信传输信号都是采用二进制信号传送的,故比特率和波特率相等。例如,通信双方每秒所传送的信息量是480字节,每一字节包含10位(1个起始位,8个数据位,1个停止位),则波特率为:

480×10=4800b/s=4800B

这里需要注意相互通信的甲乙双方必须具有相同的波特率,否则无法成功完成串行数据通信。如上图所示,给出了串行通信工作方式1的波特率。

现在来总结一下,串口通信的发送步骤

(1)选择工作方式

(2)设置速度

(3)发送什么信息,打上标记,开始传送

以上3个步骤中,第三步中三个任务通过SBUF=0x38(假设我要传这个数据)这句代码就全部完成了。因此在此之前我们要先设置好工作方式和传送速度(波特率).

这些步骤不需要记忆,只需要打开串口助手就一目了然了,

 

参考代码如下:

#include "reg52.h"

void delayUs(unsigned char t);

void delayMs(unsigned char t);

void main(void)

{

                SM0=0;

                SM1=1;//串口工作模式

                TMOD=0X20;

                TH1=TL1=253;  //波特率9600

                TR1=1;

                while(1)

                {

                         SBUF=0x38;

                        delayMs(250);

                        delayMs(250);

                }

}

void delayUs(unsigned char t)

{

        while(--t);

}

void delayMs(unsigned char t)

{

        while(--t)

        {

                delayUs(245);

                delayUs(245);

        }

}

既然知道如何操作串口通信如何发送,我们按照同样的思路看看如何操作串口接收。首先接收到的信息在哪里?将SBUF=dataTXD替换为dataRXD=SBUF. 前者表示把数据写进SBUF,发送;后者表示把SBUF中的数据读出了,接收。注意接收缓冲器SBUF和发送缓冲器SBUF名字一样,地址也一样,但是是两个独立的物理空间。工作方式的选择与速度设置与前面一样。那么,怎么让单片机知道开始接收呢?需要满足两个条件,TI=0和REN=1. REN表示串口接收允许。另外,当接收完成一帧数据(8位)后,控制信号复位,中断标志RI被置"1",呈中断申请状态。在工作方式1下,同时满足SM2=0,RI=0接收数据有效。我们可以整理一下串口接收的过程如下,

(1)选择工作方式(工作方式1)

(2)设置速度

(3)开始接收(TI=0,REN=1)

(4)接收的信息在哪里。(dataRXD=SBUF)

(5)接收的数据有效(SM2=0,RI=0)

串行通信接收的参考代码如下:

#include "reg52.h"

#define uchar unsigned char

void delayUs(unsigned char t);

void delayMs(unsigned char t);

void main(void)

{

                uchar MyRevData;

                SM0=0;

                SM1=1;//串口工作模式1

                REN=1;

                TMOD=0X20;

                TH1=TL1=253;  //波特率9600

                TR1=1;

                while(1)

                {

                        MyRevData=SBUF;

                        delayMs(250);

                        P1=MyRevData;

                        delayMs(250);

                        RI=0; //当接收完成一帧数据(8位)后,控制信号复位,中断标志RI被置"1",呈中断申请状态。在工作方式1下,SM2=0,RI=0数据有效

                }

}

void delayUs(unsigned char t)

{

        while(--t);

}

void delayMs(unsigned char t)

{

        while(--t)

        {

                delayUs(245);

                delayUs(245);

        }

}

将代码编译烧写后进行测试,打开STC-ISP烧写软件,选中串口助手,设置COM端口,波特率等参数,打开串口,然后输入要传送的内容,如下图所示。

在发送区内输入FF后点击"发送字符/数据",LED全部熄灭,输入00,点击发送,LED全部点亮

关键字:51单片机  寄存器  串口通信  发送与接收 

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多