历史上的今天

今天是:2024年10月19日(星期六)

正在发生

2021年10月19日 | #51单片机#UART串口通信的初步认识

发布者:CuriousMind123 来源: eefocus关键字:51单片机  UART  串口通信 手机看文章 扫描二维码
随时随地手机看文章

UART串口通信

UART,全称Universal Asynchronous Receiver/Transmitter,即通用异步收发器。


串口通信是单片机中最常用的一种技术,通常用于单片机和计算机之间以及单片机和单片机之间的通信。


UART的通信类型可分为两种,并行通信串行通信


并行通信:数据各个位同时传送,可实现以字节为单位来通信。缺点:通信线占用资源多,成本高。


串行通信:一次只传输一个字节的数据。


STC89C52有两个专门的UART通信引脚,P3.0(RXD)和P3.1(TXD),由它们组成的通信接口叫串行接口,简称串口。


下图体现了两个单片机相互收发信息的过程:

在这里插入图片描述

图中两单片机的GND互连,因为单片机之间的通信,要保证电源基准一致。


GND——单片机系统电源的参考地。


TXD——串行发送引脚。


RXD——串行接收引脚。


学习UART通信,要认识波特率。


波特率是发送二进制数据位的速率,习惯上用baud表示。发送一位二进制数据的持续时间=1/baud。

(UART串口的波特率常用值是300、600、1200、4800、9600、14400、19200、28800、38400、57600、115200等。)


在通信前,两个单片机需要明确约定好通信波特率。只有保持波特率一致,才能保证收发双方实现正常通信。

UART通信原则:低位先发,高位后发。

UART通信规定:当没有通信信号发生时,通信线路应保持高电平。发送数据之前,要先发一位0,标志数据起始位,数据发送完毕,要发送一位1,标志数据截止位。

下图位串口数据发送示意图:

在这里插入图片描述

改图表现了信号随着时间变化的对应关系,实际上是一个时域示意图。


比如:在单片机发送引脚上,左边的是先发送的,右边的是后发生的。数据位的切换时间即为1/波特率。


掌握时域的概念,有助于理解不同通信的时序图


为了更好的理解UART串口通信的原理,下面给出了一段IO口模拟UART串口通信的程序。


IO口模拟UART串行通信程序是一个简单的演示程序。使用烧录工具中的串口调试助手下发一个数据,待数据加1后,将自动返回。


串口调试助手的实质是利用计算机上的UART通信接口,发送数据给单片机或接收来自单片机的数据并显示在调试助手的界面上。(单片机通过USB与计算机相连,计算机中有USB转UART的芯片)


#include


sbit PIN_RXD = P3^0; //定义接收引脚

sbit PIN_TXD = P3^1; //定义发送引脚


bit RxdOrTxd = 0; //标志当前状态(发送或接收)

bit RxdEnd = 0; //标志接收结束位

bit TxdEnd = 0; //标志发送结束位

unsigned char RxdBuf = 0; //接收缓冲器

unsigned char TxdBuf = 0; //发送缓冲器


void ConfigUART(unsigned int baud); //配置波特率

void StartTXD(unsigned char dat); //开始发送数据

void StartRXD(); //开始接收数据


void main()

{

EA = 1; //中断使能总开关

ConfigUART(9600); //配置波特率位9600

while(1)

{

while(PIN_RXD); //等待接收引脚出现低电平,即起始位

StartRXD(); //启动接收

while(!RxdEnd); //等待接收完成

StartTXD(RxdBuf+1); //将接收到的数据+1后,发送回去

while(!TxdEnd); //等待发送完成

}

}


void ConfigUART(unsigned int baud)

{

TMOD &= 0XF0; //清零T0的控制位

TMOD = 0X02;      //设置T0为模式2

TH0 = 256 - (11059200/12)/baud;  //计算T0重载值

}


void StartTXD(unsigned char dat)

{

TxdBuf = dat; //保存待发送数据到发送缓存器

TL0 = TH0; //T0计数初值为重载值

ET0 = 1; //使能T0中断

TR0 = 1; //启动T0

PIN_TXD = 0; //发送起始位

TxdEnd = 0; //清零发送结束标志

RxdOrTxd = 1; //设置当前状态为发送

}


void StartRXD()

{

TL0 = 256 - ((256-TH0)>>1); //启动时,将T0定时为1/2个波特率周期

ET0 = 1; //使能T0中断

TR0 = 1; //启动T0

RxdEnd = 0; //清零接收结束标志H7YHB 

RxdOrTxd = 0; //设置当前状态为接收

}


void InterruptTimer0() interrupt 1

{

static unsigned char cnt = 0; //位接收或发送计数


if(RxdOrTxd)

{

if(cnt <= 8)

{

PIN_TXD = TxdBuf & 0X01;

TxdBuf >>= 1;

}

else if(cnt == 9)

{

PIN_TXD = 1;


}

else

{

cnt = 0; //复位bit计数器

TR0 = 0; //关闭T0

TxdEnd = 1; //标志发送结束

}

}

else

{

if(cnt == 0)      //处理起始位

{

if(!PIN_RXD) //起始位为0时,清零接收缓冲器,准备接收数据位

{

RxdBuf = 0;

cnt++;

}

else    //起始位不为0,中止接收

{

TR0 = 0;   //关闭T0

}

}

else if(cnt <= 8)

{

RxdBuf >>= 1; //低位在前,所以将之前接收的位向有移

if(PIN_RXD)     //接收脚为1时,缓冲器最高位置1

{

RxdBuf |= 0X80;

}

cnt++;

}

else //停止位处理

{

cnt = 0; //复位bit计数器

TR0 = 0; //关闭T0

if(PIN_RXD) //若停止位为1,证明数据有效

{

RxdEnd = 1; //标志接收结束

}

}

}


可以观察到,接收函数启动时,定时为半个波特率周期。这是UART通信的一个小技巧。回头看看串口数据示意图,如果在数据位电平变化时读取数据,可能会因为时序误差或信号不稳定导致读错数据。需要找到非信号变动的位置读取电平数据。于是有了这个约定:选择信号中间位置读取电平状态,从而保证正确读出数据。

关键字:51单片机  UART  串口通信 引用地址:#51单片机#UART串口通信的初步认识

上一篇:如何驱动51单片机串口(uart通信)
下一篇:51单片机串口通讯uart笔记

推荐阅读

去年8月三星公司发布了关于挖掘500个有潜力的创业公司的培育项目,三星公司表示“为了激活韩国国内创业,未来5年内将支持500家创新型公司,其中200个用于支援三星电子内部职员创业,剩余300个支援外部企业”。三星公司于10月17日首次公开选拔的15个外部创业公司。支援项目包括远程控制虚拟触摸远距离对象来识别的”V触摸”及远程诊断治疗等人工智能、健康...
  背景:  示波器是我们在物理试验、电路硬件调试、智能硬件开发等领域都能见到的一种仪器,就像是医生的听诊器,作为硬件研发工程师都要用的溜溜的。那么,里面到底是怎么样的一种构造呢?比较好奇的玩家可能已经想把实验室的示波器给拆开看看了,今天小编来满足一下比较好奇的小伙伴们,我们来一起看一下一款数字荧光示波器的内部构造。  今天拆的...
本文作者:Cadence的Paul McLellan早在20世纪60年代,当时在IBM工作的E.Rent注意到集成电路上使用的管教数P和集成电路上的晶体管门数G之间有一种联系,其中管脚数P等于cGR,c和R是常数。实际上,传统上用希腊语rho代替R,它的值通常在0.5到0.8之间。如果R为0.5,那么管脚的数量与√G成正比,这是我在VLSI设计课程中所记得的。因此,引脚的数量增长比栅极...
LCD控制器主要功能和需要的设置:取:从内存(FrameBuffer)取出某个像素的数据;之后需要把FrameBuffer地址、BPP、分辨率告诉LCD控制器;发:配合其它信号把FrameBuffer数据发给LCD;需要设置LCD控制器时序、设置引脚极性;这里主要的难点就是如何配合其它信号,需要我们阅读LCD芯片手册,知道其时序要求,然后设置相应的LCD控制器。先看下S3C2440芯片手册...

史海拾趣

问答坊 | AI 解惑

AVR_GCC教程

新会员,分享一下简单教程。 …

查看全部问答∨

单工无线呼叫系统的制作

单工无线呼叫系统分发射和接收两大部分。发射部分采用锁相环式频率合成器技术, MC145152和MC12022芯片组成锁相环,将载波频率精确锁定在35MHz,输出载波的稳定度达到4×10-5,准确度达到3×10-5,由变容二极管V149和集成压控振荡器芯片MC1648实现 ...…

查看全部问答∨

天馈系统不匹配对移动通信的影响及解决方法

天馈系统不匹配对移动通信的影响及解决方法   天馈系统是移动通信系统的重要组成部分,其性能优劣对整体移动通信质量的影响至关重要。根据移动网运行质量统计结果分析,造成移动通信质量指标下降的主要原因来自天馈系统(约占一半以上),而在天 ...…

查看全部问答∨

求单片机发送多字节数据程序,在线等高手!

如题:连续发送数据:01(起始位) 31(本机地址) #0A(控制命令字) __ __ __(数据) 06(结束位) …

查看全部问答∨

试着对flash写点内容,现在只写入了一个字节,请帮忙看看

SST的flash,main函数中定义了一个字符数组:char txt[]="This is a example";然后用此语句  Program(0,txt); 调用下面的函数。 uint8  Program(uint16 Addr, char *Data) {  volatile uint16  *ip ...…

查看全部问答∨

VS2005如何开发wince5.0的程序,如何测试,如何运行ce5.0模拟器

首先我要说我初次接触嵌入式开发。 再vs2003下面开发智能“只能设备应用程序”,vs2003本身就有windos ce net模拟器,可以非常轻松的运行模拟器,但是为什么vs2005下的就没有这个模拟器呢? 我的操作系统是windows server 2003从微软网站下载windo ...…

查看全部问答∨

51单片机矩阵键盘扫描程序(源代码)

//小菜出品---严禁抄袭,转载请注明出处 #include <reg52.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intuchar idata  x,y;uchar code disp_code[] ={  0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x ...…

查看全部问答∨

有关Stellaris Cortex-M3评估板

我最近收到了Stellaris Cortex-M3评估板,试验了一下里面的例子。现在想自己做一个项目,但是没有库函数,有哪位能提供一下Stellaris Cortex-M3评估板的库函数参考一下.谢谢了~~ [ 本帖最后由 linuxshx 于 2010-9-7 09:04 编辑 ]…

查看全部问答∨

如何通过DMA来接收串口数据?

若串口DMA接收的字节数据个数配置成8,并开数据全部完成DMA中断;而发送一端发送7个数据之后就不再发送数据了。那我如何能知道串口已接收到了7个数据??…

查看全部问答∨

驱动小型 AMOLED 显示器

想知道如何驱动小型 AMOLED 显示器吗?德州仪器 (TI) 市场营销经理Matthew Borne为您解读!!! …

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

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

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

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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