0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于单片机的串口通信实验 串口通信基础知识

CHANBAEK 来源:RYMCU 作者:RYMCU 2023-07-26 18:25 次阅读

10.1 串口通信基础知识

前面讲解的都是单片机自身的一些功能,并未涉及单片机与其它单片机或者计算机之间通信。那么单片机与其它设备之间又是怎么通信的呢?通常来讲有两种通信方式,即并行通信与串行通信。

两个单片机之间的并口通信,以 8 位为例,直接将单片机 1 的 8 位 I/O 口 P0 与单片机 2 的 P1 相连接,在同步时钟信号的作用进行数据的传输。以单片机 1 向单片机 2 传输数据 0x7B 为例,单片机 1 只需将数据 0x7B 输出到 P0 口上,单片机 2 在同步时钟信号的步调下将 0x7B 直接读取。此时同步时钟信号的周期长短将决定数据传输的速度,周期越短,速度越快。并口通信的最大优点为速度快,一个时钟周期内可以传播一个字节,甚至多个字节,缺点为需要占用大量的 I/O 口资源,对于大多数资源紧张的应用场合来说,这种方法是不可取的,而串行通信有效的解决了资源问题。

STC89C52 系列单片机配置了串行方式通信接口,对应单片机的管脚 P3.0/RxD,串行数据接收引脚、P3.1/TxD,串行数据发送引脚。如上图所示,单片机 1 的串行发送引脚 TxD 与单片机 2 的串行数据接收引脚 RxD 相连接,形成了一条单片机 1 发送、单片机 2 接收的数据通信链路。单片机 2 的 TxD 与单片机 1 的 RxD 连接,形成了一条单片机 2 发送、单片机 1 接收数据的通信链路。单片机 1 的 GND 与单片机 2 的 GND 相连接确保了两个单片机在同一电源基准下工作。接下来讲解单片机串行通信的工作原理

同样以单片机 1 向单片机 2 发送数据 0x7B 为例,二进制表示为 01111011,单片机依次 01111011 的最低位‘1’到最高位‘0’依次发送出去。发送 1 的时候为将 TxD 拉高’一段时间’,发送 0 的时候为将 TxD 拉低‘一段时间’,即发送数据的时候后,每发送一位都持续‘一段时间’,发送 0x7B 的从低位到高位的顺序为:1->1->0->1->1->1->1->0。“一段时间”的长短决定了单片机的串口传输的速度,时间越短,传输速度越快。那么在同样位传输速率的情况下,并行通信速度为串行通信的 8 倍,显然串行通信以牺牲速度的方式换取了更多的资源,这就是时间换资源的概念。

10.2 波特率概念

上面讲解的“一段时间”实际上为单片机串口传输 1 位数据所耗费的时间,在应用中我们常常把 1 秒传输多少位来衡量单片机串口传输速率,这就是波特率的概念。例如通信双方约定波特率为:9600bps,即每秒传输 9600 位(bps:bit per second)。波特率在单片串口通信中为非常重要的参数指标,通信双方只有在约定共同的波特率下才能保证数据的正确传输。

在单片机串口通信中,并没有同步时钟信号来统一数据发送和接收,通过双方约定的波特率来保证数据的通信。以单片机 1 向单片机 2 发送数据为例,假设双方设定的波特率为 9600bps,那么单片机 2 是怎么知道单片机 1 什么时候给它发送数据,又是什么时候结束的呢?

这里我们引入两个重要的概念,起始位和停止位。单片机在没有进行串口通信的情况下,数据发送引脚 TxD 为高电平,当单片机 1 需要发送数据时,首先通过 TXD 发送一位“0”,即把单片机 TxD 从高电平拉低,当单片机 2 检测到数据接收引脚 RxD 的低电平后便开始接收数据了。那么这里单片机 1 发送的第一位“0”称为起止位。紧接着单片机 1 将 8 位数据依次发送出去,当 8 位数据发送完后,单片机发送一位“1”,单片机 2 接收完 8 位数据后,又接收到一位“1”,便知道停止发送数据了,至此便完成了一次数据的传输。这里单片机 1 发送的最后一位“1”称之为停止位。根据上面的步骤,完成一次数据的传输,包括起始位、8 位数据、停止位,总共 10 位数据,如下图所示。这里的 10 位数据称之为一帧数据。

图片

10.3 单片机串口通信

下面讲解一下单片机串口的工作原理。STC89C52系列单片机串口内部模块有两个独立的串行口缓冲寄存器(SBUF),两个寄存器均为8位,一个为发送SBUF,只能往里写数据、另一个为接收SBUF、只能读取数据。当单片机要通过串口往外发送数据时,只需要将待发送的数据写入发送SBUF中,通过TxD引脚将数据发送出去。当一帧数据发送完成后,内部硬件自动置位TI,即TI=1,请求中断处理。前面讲过串口中断是单片机中断源的一种,产生中断后,程序进入串口中断函数。同样,当单片机接收到一帧数据后,内部硬件自动置位RI,即RI=1,请求串口中断处理,进入串口中断函数。读取接收SBUF可获得通过串口接收到的数据。

在单片机内部编程中两个寄存器共用 SBUF 这个名字,那么怎么区分是对发送还是接收 SBUF 进行操作呢?由于这两个寄存器一个只能读、另一个只能写。当程序中往 SBUF 中写入数据时,则代表操作发送 SBUF,当程序中读取 SBUF 的数据时,则代表操作接收 SBUF。

通过上面的介绍,无论是接收到一帧数据,还是发送完一帧数据,程序都会产生串口中断,那么在串口中断程序中是怎么区分来的是接收中断还是发送中断呢?在单片机串口中断程序开始的地方通过查询中断标志位 TI、RI 哪个为 1 来判断串口中断的类型。
图片

10.4 串口通信控制寄存器

和单片机的其它功能的实现一样,通过配置相应的特殊功能寄存器来实现串口通信的功能。与 STC89C52 系列单片机串口通信相关的寄存器如下表所示:
图片
熟练掌握上述特殊功能寄存器的应用便能掌握 STC89C52 系列单片机的串口功能应用。

10.4.1 串行口控制寄存器 SCON 和 PCON

STC89C52 系列单片机共设有两个控制寄存器:串行口控制寄存器 SCON 和波特率选择特殊功能寄存器 PCON。SCON 用于设置串口的工作方式和某些控制功能,寄存器格式如下表所示:

图片
其中,SM0、SM1 共同组合确定串口的工作方式:
图片
如上所示,单片机共有 4 种工作方式,各工作方式的主要区别为数据的位数以及波特率的不同。方式 0、1 均为 8 位数据模式,方式 2,3 为 9 位数据模式。方式 0,2 为固定波特率模式,方式 1,3 为波特率可变模式。根据应用场合的不同可以选择相应的工作模式。方式 1,3 最为常用。

SM2:为方式 2 或方式 3 多机通信控制位。

REN:允许/禁止串行接收控制位。有软件置位,当 REN=1 时,允许接收 RxD 引脚数据,当 REN=0 时,禁止接收串行数据。

TB8:在方式 2 或方式 3,它为要发送的第 9 位数据,按需要进行置位或清零。例如可作为数据的校验位。

RB8:在方式 2 或方式 3,是接收到的第 9 位数据。

TI:发送中断请求标志位。在发送完数据后,由内部硬件自动置位,即 TI=1,向主机请求中断,响应中断后必须用软件复位,即 TI=0。

RI:接收中断请求标志位。在发送完数据后,由内部硬件自动置位,即 RI=1,向主机请求中断,响应中断后必须用软件复位,即 RI=0。

在中断请求 TI 或 RI 响应完串口中断函数后,必须由软件进行复位,否则将程序将多次进入中断函数。

PCON 为串口波特率选择特殊功能寄存器,格式如下:
图片
SMOD:波特率选择位。当软件置位 SMOD,即 SMOD=1,则使串口工作方式 1,2,3 的波特率加倍,当软件清零 SMOD,即 SMOD=0,波特率不加倍。

中断允许寄存器 IE 的 ES 位为串行口中断允许位,ES=1,允许串行口中断,ES=0,屏蔽串行口中断。
根据上面介绍,我们大致可分析出单片机在进行通信之前要对上述寄存器进行设置。通过设置寄存器 SCON 选择串口工作方式,允许串口接收数据。设置 PCON 寄存器是否波特率加倍,设置中断控制寄存器 IE 允许串口中断。

10.4.2 波特率的计算

由表 10-4 所示,STC89C52 系列单片机工作在方式 1,3 时,波特率不仅与 SMOD 值有关,还与定时器 1 的溢出率有关。
图片
方式 1,3 波特率 =2SMOD/32x(定时器 1 的溢出率)

  • 当单片机工作在 12T 模式下,定时器 1 的溢出率 =SYSclk/12/(256-TH1)
  • 当单片机共工作在 6T 模式下,定时器 1 的溢出率 =SYSclk/6/(256-TH1)

其中,SYSclk 为系统时钟频率,在 RY-51 单片机系统时钟为晶振时钟频率 11.0592MHz。
其中,TH1 为定时器工作在模式 2 的初始值,当定时器工作在模式 2 时为 8 位自动重装模式,当定时器产生溢出时,系统会自动把 TL1 的值自动重载到 TH1 中开始重新定时,因此,在单片机编程过程中只需在初始化时将初始值同时赋值给 TH1,TL1 保证波特率正常的产生。

由上面公式计算可得,当单片机工作在 12T 模式下,定时器 1 初始值:
TH1 =TL1=256- SYSclk x2SMOD/32 /12/波特率
当单片机工作在 6T 模式下,定时器 1 初始值:
TH1 =TL1=256- SYSclk x2SMOD/32 /6/波特率

10.4.3 串口转 USB

单片机与单片之间通可以采用串口直接相连的方式进行,而计算机一般并没有配置与单片机接口一致的的串行通信接口,但一般计算机都配备了 USB 接口。在我们前面经常使用到的通过 USB 将程序下载到单片机,实际上是在计算机 USB 与单片机之间增加了一个串口转 USB 模块。在 RY-51 单片机开发板是配置了串口转 USB 芯片 CH340G,硬件原理图如下所示:
图片
如图所示,USB+、USB-分别连接到计算机 USB 接口的数据正负端,USB_RX、USB_TX 分别连接到单片机的 P3.0(RxD)、P3.1(TxD)引脚。在计算机安装好串口转 USB 驱动后,便可实现计算机与单片机之间的通信。我们经常使用串口调试助手来实现单片机与计算机专家的通信,串口调试助手软件主界面如下图所示:
图片
如上图所示,串口调试助手界面主要包含三大块,首先为通信方式选择区,根据通信双方的约定选择合适的参数,数据发送区,将数据输入到这个区域,点击发送可将数据发送到单片机,接收数据显示区,顾名思义计算机接收到单片机发来的数据将显示到该区域。

10.5 串口功能应用

前面介绍了单片机串口工作原理,这节我们结合上面内容举例说明串口的实际应用。程序实现的功能为:首先由计算机通过串口调试助手往单片机发送一个数据,当单片机接收到数据后翻转 led0 小灯,并将接收到的数据加 1 发送给计算机,发送完数据后翻转 led1。串口应用程序编写顺序如下:

  1. 配置串口工作方式 1,并允许接收串口数据
  2. 初始化 SMOD
  3. 配置定时器位工作模式 2,8 位自动重装模式
  4. 初始化 TH1,TL1
  5. 启动定时器,并禁止定时器中断
  6. 允许串口中断,允许总中断
  7. 编写串口中断程序
    串口应用程序代码如下:
/*----------------------------------------------------
** 串口应用程序
**	串口工作方式1,定时器1工作模式2
**  将接收到的数据加1发送回去,收到数据时翻转led0
**  发送完数据时翻转led1
**
----------------------------------------------------*/
#include< reg52.h >

#define uchar  unsigned char
#define uint unsigned int

#define FOSC 11059200 //单片机晶振频率
#define BAUD 9600	  //波特率设置为9600

sbit led0 = P1^0; //led0位声明
sbit led1 = P1^1; //led1位声明

void main()
{
	SCON = 0x50;//串口配置为工作方式1
	PCON = 0;   //波特率不加倍

	TMOD = 0x20;//设置定时器1为8位自动重装模式
	TH1=TL1= 256- FOSC/32/12/BAUD;//定时器1赋初始值
	
	ET1 = 0;//禁止定时器1中断
	TR1 = 1;//启动定时器1

	ES = 1;//允许串口中断
	EA = 1;//开总中断
	
	while(1);		
}
//串口中断函数
void Uart_r(void) interrupt 4
{
	if(RI)
	{
		RI = 0;		   //清零接收中断
		SBUF = SBUF+1;   //读取接收到的数据加1并发送出去
		led0 = ~led0;  //翻转led0
	}
	if(TI)
	{
		TI = 0;		   //清零发送中断
		led1 = ~led1;  //翻转led1
	}
}

将上述代码编译后,下载到开发板进行测试,打开串口调试助手软件,设置后下图中红框中参数,点击打开串口,如果打开串口成功,软件左上角红色指示灯灯会点亮。
图片
在数据发送区输入 16 进制数“EF”,点击“手动发送”按钮将数据“EF”发送给单片机,此时观察到串口调试助手数据接受区接收到 “F0”,接收到的值正好为发送的数值加 1,与我们预期的结果相同。同时观察 RY-51 开发 led0,led1 小灯也发生了翻转。

上面的程序只是发送单个字节的程序,下面举例说明字符串的发送方法。功能为当 RY-51 开发板上电后向计算机发送指定的字符串。为了程序的可读性,我们将定时器的初始化放到初始化函数 Uart_int()。代码如下所示:

/*----------------------------------------------------
** 串口应用程序
**	串口工作方式1,定时器1工作模式2
**  将接收到的数据加1发送回去,收到数据时翻转led0
**  发送完数据时翻转led1
**  上电后向单片机发送指定字符串
**
----------------------------------------------------*/
#include< reg52.h >

#define uchar  unsigned char
#define uint unsigned int

#define FOSC 11059200 //单片机晶振频率
#define BAUD 9600	  //波特率设置为9600

sbit led0 = P1^0; //led0位声明
sbit led1 = P1^1; //led1位声明
sbit dir485 = P3^7;

uchar busy = 0;//发送完一帧数据标志位

void Uart_init(void);//串口初始化函数声明
void Send_String(char *s);//字符串发送函声明

void main()
{
	Uart_init();  // 串口初始化
	EA = 1;           //开总中断
	
	Send_String("RY-51 STC89C52 Uart test!n");	//发送字符串
	while(1);		
}
//串口中断函数
void Uart_r(void) interrupt 4
{
	if(RI)
	{
		RI = 0;		   //清零接收中断
		dir485=1;
		SBUF = SBUF+1;   //读取接收到的数据加1并发送出去
	//	led0 = ~led0;  //翻转led0
		
	}
	if(TI)
	{	dir485=0;
		TI = 0;		   //清零发送中断
		led1 = ~led1;  //翻转led1
		busy = 0;      //发送完数据,清除发送完标志位
		
	}
}

//串口初始化函数
void Uart_init(void)
{
	SCON = 0x50;//串口配置为工作方式1
	PCON = 0;   //波特率不加倍

	TMOD = 0x20;//设置定时器1为8位自动重装模式
	TH1=TL1= 256- FOSC/32/12/BAUD;//定时器1赋初始值
	
	ET1 = 0;//禁止定时器1中断
	TR1 = 1;//启动定时器1

	ES = 1;//允许串口中断
}
//字符串发送函
void Send_String(char *s)
{	
	while(*s)   //检查字符串是否到了结尾
	{	
		while(busy);  //等待上一帧数据发送完毕
		busy = 1;
		dir485=1;
		SBUF = *s++;  //发送当前字符,并将字符指针移到下一个字符
	}
	dir485=0;	
}

将程序编译后,下载到 RY-51 开发板,设置后串口调试助手,并不选中“十六进制显示”,给开发板重新加电,收到的指定字符串如下图所示:
图片

10.6 本章小结

本章介绍了51单片机串口通信的基本原理。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 单片机
    +关注

    关注

    6032

    文章

    44513

    浏览量

    632691
  • 定时器
    +关注

    关注

    23

    文章

    3237

    浏览量

    114432
  • 串行通信
    +关注

    关注

    4

    文章

    564

    浏览量

    35277
  • 串口通信
    +关注

    关注

    34

    文章

    1609

    浏览量

    55408
  • 并行通信
    +关注

    关注

    1

    文章

    31

    浏览量

    10812
收藏 人收藏

    评论

    相关推荐

    LabVIEW串口通信实例:PC与51单片机串口通信实

    相关课程推荐:《8周LabVIEW视觉项目编程实战特训营》LabVIEW串口通信实例:PC与51单片机串口
    发表于 06-28 20:04

    LabVIEW串口通信实例:PC与51单片机串口通信实

    LabVIEW串口通信实例:PC与51单片机串口通信实
    发表于 12-18 10:16

    单片机串口通信实验

    单片机串口通信实验一、实验目的二、实验内容三、实验步骤四、C代码如下五、
    发表于 11-10 07:45

    RS232串口通信实验

    RS232串口通信实验 一. 实验目的利用单片机的TXD、RXD 口
    发表于 09-22 16:42 1.2w次阅读
    RS232<b class='flag-5'>串口</b><b class='flag-5'>通信实验</b>

    单片机之间的串口通信实

    STC80C51-单片机之间的串口通信实
    发表于 09-01 15:44 25次下载

    什么是单片机串口通信

    串口通信单片机一个重要的部分,单片机和PC,单片机单片机之间的
    发表于 07-25 07:36 6.1w次阅读
    什么是<b class='flag-5'>单片机</b>的<b class='flag-5'>串口</b><b class='flag-5'>通信</b>?

    深入理解51单片机串口通信通信实

    全文首先阐述了串口通信的原理及RS232相关概述,其次介绍了USB转串口通信与IO口模拟UART串口通信
    发表于 04-19 16:52 2.7w次阅读
    深入理解51<b class='flag-5'>单片机</b><b class='flag-5'>串口</b><b class='flag-5'>通信</b>及<b class='flag-5'>通信实</b>例

    51单片机串口通信的一些基础知识免费下载

    本文档的主要内容详细介绍的是51单片机串口通信的一些基础知识免费下载。
    发表于 08-21 17:31 5次下载
    51<b class='flag-5'>单片机</b><b class='flag-5'>串口</b><b class='flag-5'>通信</b>的一些<b class='flag-5'>基础知识</b>免费下载

    单片机应用系统设计技术——双单片机串口通信实验

    单片机串口通信实验一、实验目的二、实验内容三、实验步骤四、C代码如下五、
    发表于 11-05 13:50 15次下载
    <b class='flag-5'>单片机</b>应用系统设计技术——双<b class='flag-5'>单片机</b><b class='flag-5'>串口</b><b class='flag-5'>通信实验</b>

    51单片机串口通信

    51单片机串口通信文章目录51单片机串口通信串口介绍
    发表于 11-18 14:06 22次下载
    51<b class='flag-5'>单片机</b><b class='flag-5'>串口</b><b class='flag-5'>通信</b>

    51单片机串口通信

    51单片机串口通信文章目录51单片机串口通信串口介绍
    发表于 11-21 20:36 62次下载
    51<b class='flag-5'>单片机</b><b class='flag-5'>串口</b><b class='flag-5'>通信</b>

    STM32 串口通信实验

    stm32串口通信实验UART通信实验(通用异步收发器)UART串口通信原理:UART的通信过程
    发表于 12-20 19:26 15次下载
    STM32 <b class='flag-5'>串口</b><b class='flag-5'>通信实验</b>

    串口通信实验

    串口通信实验串口通信实验代码图像串口通信实验晶振12MHz,波特率1200, 程序启动后
    发表于 01-14 10:12 6次下载
    <b class='flag-5'>串口</b><b class='flag-5'>通信实验</b>

    串口通信实验资料分享

    串口通信实验资料分享
    发表于 06-29 15:03 5次下载

    基于LabVIEW的单片机串口通信实

    电子发烧友网站提供《基于LabVIEW的单片机串口通信实现.pdf》资料免费下载
    发表于 10-30 09:13 6次下载
    基于LabVIEW的<b class='flag-5'>单片机</b><b class='flag-5'>串口</b><b class='flag-5'>通信实</b>现