历史上的今天
返回首页

历史上的今天

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

正在发生

2021年10月20日 | #51单片机# UART串口通信的基本应用、模块介绍和串口程序

2021-10-20 来源:eefocus

UART串口通信的基本应用

通信的三种基本类型:


单工通信:值允许一方向另一方传送星系,另一方不能回传信息。例:电视遥控器、收音机广播


半双工通信:数据可在双方之间相互传播,但同一时刻只能一方传给另一方。例:对讲机


全双工通信:发送数据的同时也可接收数据,两者同步进行。例:电话


UART模块介绍

通常情况下,我们关心的是通信的结果而非过程。51单片机内部存在UART模块,可自动接收数据,接收完毕,会发出通知信号。要使用这个模块,需要配置对应的具有特殊功能的寄存器。


51单片机的UART串口结构由串行口控制寄存器SCON、发送和接收电路三部分构成。


先来了解串口控制寄存器SCON


SCON——串行控制寄存器的位分配(地址0X98、可位寻址)

image.png?imageView2/2/w/550

SCON——串行控制寄存器的位描述

image.png?imageView2/2/w/550

对于串口的四种模式,模式1是最常用的,就是前面提到的1位起始位,8位数据位和1位停止位。 下面讲详细介绍模式1的工作细节和使用方法(其他3种模式与模式1大同小异,要用的时候自行查阅资料既可)。


在硬件模块中,有一个专门的波特率发生器用来控制发送和接收数据的速度。对于STC89C52单片机来说,这个波特率只能由定时器T1或定时器T2产生。这与模拟的通信概念完全不同。默认使用定时器T1(定时器T2需要额外配置的寄存器)。


下面主要就使用T1作为波特率发生器来讲解,方式1下的波特率发生器必须使用T1的模式2,也就是自动重装载模式。


定时器的重载值计算公式为:TH1 = TL1 = 256-晶振值/12/2/16/波特率


这里介绍一个与波特率有关的另一个计算器:电源管理寄存器PCON,他的最高位可以把波特率提高一倍,也就是如果写PCON |= 0X80以后,计算公式就成了:TH1 = TL1 = 256-晶振值/12/16/波特率


公式中数字的含义解释如下:

256——8位定时器的溢出值,1TL1的溢出值。

晶振值——在开发板上是11059200

12——1个机器周期等于12个时钟周期

16——将一位信号采集16次(IO口模拟串口通信接收数据时采集的是这位数据的中间位置,而实际串口模块比模拟的要复杂和精确一些。它采取的方式是把一位信号采集16次,其中7,8,9次取出来,如果这三次中有两次是高电平,就认为这个数据是1,如果有两次是低电平,就认为这个数据是0,这样即使是受到干扰导致数据读错,仍可保证最终数据的正确性)


了解了串口采集模式,这里可以思考一个问题。“晶振值/12/2/16/波特率”计算出的值有没有可能是小数?把这里理解了也就解释了晶振为何使用11059200。 因为11059200可以被常见的波特率整除。


串口通信的发送和接收电路在物理上有两个名字相同的SBUF寄存器,它们的地址相同都是0X99。 这两个寄存器一个用来发送缓冲,一个用来接收缓冲,实现了UART的全双工通信,互相不干扰。操作SBUF,单片机会自动判断并决定选择接收SBUF还是发送SBUF。


UART串口程序

一般情况下,串口通信程序的编写步骤如下:


1)配置串口为模式1


2)配置定时器T1为模式2(自动重装模式)


3)根据波特率计算TH1和TL1的初值,如果有需要可以使用PCON进行波特率加倍。


4)打开定时器控制寄存器TR1,让定时器跑起来。


注意:使用T1时,即在使用T1做波特率发生器,千万不能再使能T1中断。

以下是一段演示代码


 #include


 void ConfigUART(unsigned int baud);//串口配置函数,baud——通信波特率


 void main()

 {

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


while(1)

{

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

RI = 0; //清零接收中断标志

SBUF = SBUF + 1;//接收到的数据+1后,发送回去

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

TI = 0; //清零发送中断标志位

}

 }



 void ConfigUART(unsigned int baud)

 {

  SCON = 0X50; //配置串口为模式1

TMOD &= 0X0F; //清零T1的控制位

TMOD |= 0X20; //配置T1为模式2

TH1 = 256 - (11059200/12/32)/baud; //计算T1重载值

TL1 = TH1; //初值等于重载值

ES = 0; //禁止T1中断

TR1 = 1; //启动T1

 }


注意:实际工程开发中,并不会这样编写这段代码,因为这段代码在主循环里等待接收中断标志位和发送中断标志位,占据了大量程序内存。实际使用串口时常用到串口中断。


以下是串口中断的演示代码


 #include


 void ConfigUART(unsigned int baud);//串口配置函数,baud——通信波特率


 void main()

 {

  EA = 1; //使能总中断

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

while(1);

}



 void ConfigUART(unsigned int baud)

 {

  SCON = 0X50; //配置串口为模式1

TMOD &= 0X0F; //清零T1的控制位

TMOD |= 0X20; //配置T1为模式2

TH1 = 256 - (11059200/12/32)/baud; //计算T1重载值

TL1 = TH1; //初值等于重载值

ET1 = 1; //禁止T1中断

ES = 1; //使能串口中断

TR1 = 1; //启动T1

 }


 //UART中断服务函数

 void InterruptUART() interrupt 4

 {

  if(RI)     //接收到字节

{

RI = 0;   //手动清零接收中断标志

SBUF = SBUF + 1;    //接收到的数据+1后发回,左边是发送SBUF,右边是接收SBUF

}

if(TI)   //字节发送完毕

{

TI = 0;     //手动清零发送中断标志位

}

 }

推荐阅读

史海拾趣

Flambeau公司的发展小趣事

在追求经济效益的同时,Flambeau公司始终不忘履行社会责任和环保使命。公司积极响应全球可持续发展号召,将环保理念融入产品研发、生产和销售的各个环节。通过采用环保材料、优化生产工艺、推广循环经济等措施,Flambeau有效降低了产品生命周期中的环境影响。此外,公司还积极参与环保公益活动和社会责任项目,为推动电子行业的绿色可持续发展贡献力量。

DS-IMP公司的发展小趣事

在电子行业,供应链管理是企业发展的关键因素之一。DS-IMP公司深知这一点,因此在发展过程中不断优化供应链管理。公司建立了完善的供应链体系,与供应商和客户建立了长期稳定的合作关系。同时,公司还引入了先进的供应链管理软件和技术手段,实现了对供应链的实时监控和精细化管理。这些措施不仅提高了公司的运营效率,还降低了成本风险,为公司的发展提供了有力保障。

FUJIKURA公司的发展小趣事

DS-IMP公司一直将研发创新作为企业发展的核心动力。在研发过程中,公司不断投入大量资金,引进先进设备和技术,并与国内外知名高校和研究机构建立合作关系。通过不懈努力,公司在多个领域取得了重大突破,成功研发出了一系列具有自主知识产权的高性能模拟混合电路产品。这些产品不仅满足了国内外客户的需求,还为公司赢得了良好的市场声誉。

CYMBET公司的发展小趣事

在电子行业中,技术的更新换代速度极快。为了保持竞争力,CYMBET公司始终将创新作为核心驱动力。公司不断投入研发资金,引进先进设备和技术人才,对EnerChip技术进行持续的优化和升级。例如,公司成功研发出了更高能量密度、更长寿命的EnerChip电池芯片,进一步提升了产品的性能和市场竞争力。同时,CYMBET还积极探索新的应用领域,将EnerChip技术应用于可穿戴设备、物联网等新兴领域,为公司带来了新的增长点。

Alcatel-Lucent公司的发展小趣事

随着全球环境问题的日益严重,环保和可持续发展已经成为电子行业的重要议题。CYMBET公司积极响应这一趋势,致力于环保和可持续发展。公司的EnerChip电池芯片采用环保材料制造,具有生物相容性,不会对环境造成污染。此外,CYMBET还积极探索绿色生产技术和资源循环利用方案,减少生产过程中的能源消耗和废弃物排放。这种对环保和可持续发展的重视不仅体现了CYMBET的社会责任感,也为公司的可持续发展奠定了坚实的基础。

Autotrol公司的发展小趣事

Autotrol公司成立于1964年,最初是一家领先的可定制小功率齿轮马达生产商。在初创时期,公司面临着激烈的市场竞争和技术挑战。然而,Autotrol凭借其卓越的技术实力和创新能力,成功开发出一系列具有竞争力的齿轮马达产品,逐渐在市场中脱颖而出。公司不断完善产品线,推出了永久磁铁同步电动机、滞后电动机和直流齿轮马达等,这些产品以其高效、稳定的性能赢得了客户的信赖。

问答坊 | AI 解惑

请教:在vc++下能通过,移植到evc下提示链接错误!

HTTPServer.obj : error LNK2019: unresolved external symbol \"public: __cdecl std::_Lockit::~_Lockit(void)\" (??1_Lockit@std@@QAA@XZ) referenced in function \"public: __cdecl std::_Tree::~_Tree(vo id)\" (??1?$_Tree@V?$basic_string ...…

查看全部问答>

pci的bar问题

请问高手们,怎样通过pci的配置寄存器中的bar读取的值,来获取映射到io或者memory的地址?bar是一个32位的寄存器。。。…

查看全部问答>

IDE转SATA时,端口怎么初始化?

我想利用IDE转SATA和SATA转IDE 2种卡实现并/串高速数据传输! 有2个地方都是并口,40M速度,想利用IDE转SATA卡先并--串行,然后用SATA转IDE卡再把串--并行,实现近距离数据传输。实验时距离不超过30cm, 但用示波器就是看不到数据传过来。此方案若 ...…

查看全部问答>

用什么方法能够实时采集8路PWM信号的占空比

用什么方法能够实时采集8路PWM信号的占空比 现有8路PWM信号,信号不同步,且占空比都很小周期一样都为50HZ,最小脉宽为0.5ms,最大为2.5ms,想通过一种方法实时得到这8路信号的脉冲宽度 …

查看全部问答>

mxchip制作的中文手册不厚道

                                 mxchip制作的中文手册排版上太浪费空间,本来一页能写下的东西洋洋洒洒写了两页多,还不让编辑,要是把一本stm32固 ...…

查看全部问答>

请教香水城

VTarget = 3.352V Info: TotalIRLen = 9, IRPrint = 0x0011 ***JLink Error: Wrong ROM location (15:2). Expected 0xE00FF003, Found 0x14 ...…

查看全部问答>

寻找测量物体竖直高度的传感器

公司的垂直连续电镀线上面需要安装一个能测量PCB板的高度的传感器,PCB板子是垂直悬吊起来的,排成一排,在水平方向运动…

查看全部问答>

FCI连接器已解决FFC/FPC方案

      FCI已推出高速I/O接口的完整产品线。然而随着科技的不断进步,由FCI公司生产的新型SFGL系列( 0.4毫米间距和0.9毫米高度)FPC后翻式ZIF连接器含有各种微间距后翻执行机构系列,它们就是目前的间距0.5毫米、高度0.9毫米( ...…

查看全部问答>

M430 UART0 接收数据

最近在研究430 看到有人写的一段代码,为了接收GPS的数据,使用串口中断接收,部分代码如下: if(global_temp_data_num==0)   //获取\"GG\"标志         {           if ...…

查看全部问答>