您现在的位置是:首页 >技术教程 >基于江科大51单片机视频笔记——串口通信网站首页技术教程

基于江科大51单片机视频笔记——串口通信

智控硬件砖家 2025-03-22 00:01:02
简介基于江科大51单片机视频笔记——串口通信

目录

串口介绍

​编辑

介绍陀螺仪与蓝牙串口

陀螺仪

蓝牙串口

串口简单电路

电平标准

常见通信接口比较

51单片机中的UART

电路图

时序图

串口模式图

串口的中断系统与相关寄存器

SM0/FE:

 SM1:

SM2:

 REN:

TB8:

 RB8:

 TI:

RI: 

SMOD:

SMOD0:

配置串口发送代码

先配置SCON

配置SBUF

配置PCON

配置中断相关寄存器

定时器控制波特率

SBUF控制发送

发送数据

配置串口接收代码

配置SCON

配置SBUF

 配置PCON

配置中断通道相关寄存器

配置中断函数

补充  T1溢出率的计算

补充  数据显示模式


串口介绍

串口就是一种传输数据用的接口,U盘,雷电接口等。就是可以和其他单片机或者外设传递数据的接口(交流接口)。

介绍陀螺仪与蓝牙串口

陀螺仪

能够测量X,Y,Z轴的角度和加速度等等,然后传递给单片机,可以通过串口来将数据传递给单片机。

蓝牙串口

可以通过相应的软件来进行传递数据,就是将手机要发送的数据传给蓝牙串口,后蓝牙串口传递给单片机。

串口简单电路

VCC:提供电压电源,驱动内部电路。

TXD:Transmit Data,发送数据线

RXD:Received Data,接受数据线

GND:电气参考点,信号传输。

不妨想一想,当设备之间需要传递一串字符数据,该怎么传输呢?电路又不能直接将字符传递过去,这就需要请出ASCII码了。我们知道,每个字母或数据都有一个对应的ASCII码。比如“a”的码为“97”,转化为二进制为“0110 0001”,这个二进制就代表“97”,这就为一个信号。

然而,如何将“0110 0001”发送出去呢?

这就需要介绍

电平标准

电压的计算就是VCC相对与GDN的电压,就是VCC-GND的电压,但GND一般为0。

两线压差与上述差别不大,就是GND可能不一定为0.

拓展:VCC相对GND的电压是电路设计和分析中描述直流电源电压水平的一个参数,而两线压差则是描述两个不同电位点之间电压差的一个概念。

TTL电平与RS232电平的缺点:最大传输距离为13左右米。

RS485:可以传输1000米以上。

常见通信接口比较

全双工:相当于打电话,同时间双方可以同时通信(讲话),两线。

半双工:相当于对讲机,同时间双方只有一个可以通信(讲话),一线。

单工:相当于电视遥控器,无论任何时间都只能一方发送给另一方数据,一线。

异步,同步中的通信速率,可以比作讲话速度,就是双方必须保持相同的说话速度,否则可能听不懂,听不清。打个比方,甲方是1秒发一个数据,而乙方是0.5秒读一次数据,这样乙方永远读的是甲方数据的一半。

异步:就是在传递信息,通信过程前就将速度设置好(这个需要自己配置好)。

同步:就是给个时钟线,当这根线上有数据时就读取。

还有一个通俗讲解:异步就是给你个翻译本,自己翻译。同步就是我给你翻译。

51单片机中的UART

电路图

时序图

波特率:通信的速率,因为异步,所以需要自己设置。就是讲话的速度。

校验位:如图,9位数据格式中。比如发送数据“0110 0000”中的 1 有2个,为偶数,就会在发送一个“1”来表示数据位有偶数个1,这个位就叫做校验位。   如果数据为“0110 0001”中的1有 3 个,为奇数个,就会在校验位发送一个“0”。

这有什么用呢?

打个比方,如果数据是:“0110 1000”,后校验位就是“0”。总的发送就为“0110 10000”。但中途有个信号异常,变为了0,比如变为了“0100 10000”,这时接受方在接受到最后的校验位时“0”,0代表这个数据1有奇数个,但此刻为偶数个,所以可以断定这个数据发送错了,可以选择不接受。

有人会问,如果突然有两个数,一个1  一个0  突变,那怎么样,这确实有可能,但概率极低,可以不计。也就是说,一般只有一个会变,因为两个都变化的概率极低。如果真的两个都变,那就只能接受了。

串口模式图

T1溢出率:它定义为定时器溢出一次所需的时间的倒数。例如,如果定时器每50秒溢出一次,则溢出率为1/50 = 20Hz。

T1控制的就是发送和接收的速率,就是一位一位读取8位数据的速率。

发送数据:先将8位的数据写入SBUF缓存寄存器中,在通过 控制门 发送(TXD)出去。

接收数据:将8位数据先通过移位寄存器 一位一位地写入SBUF缓存寄存器中

读写操作:如果是a=SBUF,就是读操作。

                  如果是SBUF=a,就是写操作。

数据的接收和发送是自动执行的,就是当你写入数据到发送寄存器中时,系统自动帮你发送数据,并产生一个发送中断(transmit interrupt)。接收相同,你读数据到接收寄存器中时,系统自动帮你接收数据,并产生一个接收中断(receive interrupt)。

串口的中断系统与相关寄存器

数据手册中的寄存器讲解

SM0/FE:

SM0/FE是一个具有双重功能(就是有两个功能)寄存器位,其具体功能取决于PCON寄存器中的SMOD0位的设置。

  1. 当SMOD0=0时

    • SM0/FE(选择SM0)与SM1一起用来设置串口通信的工作模式。51单片机的串口可以工作在四种不同的模式下,这些模式通过SM0、SM1两位的组合来设置。具体来说,SM0和SM1可以组成四种状态(00、01、10、11),分别对应四种不同的串口工作模式。
  2. 当SMOD0=1时

    • SM0/FE(选择FE)用作帧错误(Frame Error)检测位。在串口通信过程中,如果出现无效的停止位,硬件会自动将SM0/FE位置“1”,表示检测到了帧错误。此时,该位必须由软件清零(就是自己写代码去清除)以恢复正常的通信状态。

 SM1:

与SM0配套使用。详情看SM0/FE。

SM2:

一、SM2位的基本功能

SM2位是串行口控制寄存器SCON中的一个控制位,它主要用于控制多机通信的过程。在多机通信中,通常有一个主机和多个从机,主机需要向特定的从机发送数据,而从机需要能够识别出这些数据是发送给自己的。

二、SM2位在不同工作模式下的作用

  1. 方式0:在方式0下,SM2位必须为0,因为方式0不支持多机通信。

  2. 方式1:在方式1下,SM2位的作用相对较弱。如果SM2=1,只有接收到有效的停止位时,接收中断才会被激活。但方式1主要用于单机通信,因此SM2位的作用并不突出

  3. (重点)方式2和方式3:在方式2和方式3下,SM2位的作用非常重要。这两个方式支持多机通信。当SM2=1时,如果接收到的第9位数据(RB8)为0,则接收中断不会被激活,接收到的前8位数据会被丢弃。只有当接收到的第9位数据为1时,前8位数据才会被送入接收缓冲器SBUF,并置位接收中断标志位RI,产生中断请求。这意味着在多机通信中,主机可以通过设置第9位数据为1来发送地址帧,从机则根据RB8的值来判断是否是发送给自己的数据。

 REN:

(R:read读数据。EN:enable使能)

REN位是一个接收允许控制位,用于控制单片机是否允许通过串口接收数据。当REN位被置1时,单片机允许通过串口接收数据;当REN位被置0时,单片机禁止通过串口接收数据。

TB8:

(T:发送。B:Bit。8:第8位) 发送数据位的第8+1(因为0开始)位

TB8的功能

  1. 数据帧的第9位:在串口通信的方式2和方式3中,TB8作为要发送数据的第9位被包含在内。这意味着除了常规的8位数据位之外,还可以发送一个额外的位,即第9位。
  2. 奇偶校验位:在许多通信协议中,TB8可以用作奇偶校验位,以增加数据传输的可靠性。
  3. 多机通信中的标志位:在多机通信中,TB8可以作为发送地址帧或数据帧的标志位。例如,TB8=1可能表示发送的是地址帧,而TB8=0可能表示发送的是数据帧。这样,从机就可以根据TB8的值来判断接收到的数据是地址还是数据,从而做出相应的处理。

 RB8:

RB8的功能

  1. 接收数据的第9位:在串口通信的方式2和方式3中,当单片机接收一帧数据时,会把数据帧中的第9位放到RB8中。这意味着除了常规的8位数据位之外,还可以接收一个额外的位,即第9位。
  2. 奇偶校验位或地址/数据标识位:RB8可以用作约定的奇/偶校验位,或者作为约定的地址/数据标识位。例如,在多机通信中,主机发送的地址帧的第9位可能设置为1,而从机在接收到数据后,可以根据RB8的值来判断该数据帧是地址帧还是数据帧。

 TI:

TI的功能

  1. 发送完成指示:当51单片机通过串口发送完一帧数据时,硬件会自动将TI置1,表示发送操作已完成。
  2. 中断请求:TI置1后,可以向CPU申请中断,通知CPU发送操作已完成,CPU可以响应此中断来处理发送完成后的相关事务。

RI: 

RI的功能

  1. 接收完成指示:当51单片机通过串口成功接收一帧数据时,硬件会自动将RI置1,表示接收操作已完成。
  2. 中断请求:RI置1后,可以向CPU申请中断,通知CPU接收操作已完成,CPU可以响应此中断来处理接收到的数据。

SMOD:

就是这个地方

SMOD==0时,开关向上,就是相比于/2,就是不加倍。

SMOD==1时,开关向上,就是相比于/2,就是加倍。

SMOD0:

SMOD0==0时,SM0/EF选择的就是SM0,控制串口工作方式。

SMOD0==1时,SM0/EF选择的就是EF,帧错误检测。

配置串口发送代码

根据下图配置

先配置SCON

SM0/FE(选择SM0)与SM1一起用来设置串口通信的工作模式。51单片机的串口可以工作在四种不同的模式下,这些模式通过SM0、SM1两位的组合来设置。具体来说,SM0和SM1可以组成四种状态(00、01、10、11),分别对应四种不同的串口工作模式。

配置SBUF

不需要。

配置PCON

待定。。。。

配置中断相关寄存器

Slave Address Mask是从设备地址掩码,用于在I2C通信中筛选或匹配特定的从设备地址。

发送数据端不需要配置中断,所以这里没有中断。

定时器控制波特率

还需要定时器配置代码,用于

 插入小插曲,之前讲了模式1——16位定时器。

这次介绍一下模式2——8位自动重装载值模式

16位定式器就是两个8位寄存器相接,但有个缺点进入中断后需要给寄存器赋初值,要不然就是从0开始计时。并且赋初值这个代码会浪费时间,所以定时精度会降低。

然而模式1可以避免这个问题

TL1占8位,用作计数器寄存器。
TH1同样占8位,但用作预装载寄存器。

就是CNT是8位寄存器,就是TL1,自动从装载寄存器也是8位,就是TH1,这样在CNT计数器积满中断后,自动从装载寄存器中的值直接赋予给CNT。

如果没有自动从装载寄存器,那么在CNT计数器积满中断后,CNT就会在次从0开始计时,如果我们想让他从200开始计时,就需要手动写代码给CNT赋初值。但现在不用这么麻烦,自动自动从装载寄存器就是在CNT计数器积满中断后,自动将寄存器中的值直接赋予给CNT,省去了手动赋初值的时间。

代码

可以用stc_isp来配置

按如图设置

但需要注意的是

STC89C52在stc_isp波特率发生器中只有定时器1(8位自动重装载)这个选项

定时器时钟只有12T可选

波特率误差,误差太大不能通信,如果选择11.0592就没有,但不能随便选,这需要看你单片机板上的晶振频率(频率就在晶振上写着)。

如何减少误差

波特率选择4800,选择波特率倍数。

SBUF控制发送

while(TI==0)是判断数据是否发送完成,就是防止连续发送数据出错。

就是比如不断发送数据中,如果SBUF在接收8位数据,比如0110 0001中,还没接收完成,只接收了 0001,后四位,就开始发送,这样就会出错。

后 TI=0 软件手动清零。因为之前说过

发送数据

但如果这样

系统就会出错

原因

波特率误差影响

解决方法

配置串口接收代码

配置SCON

REN位,R:接收。EN:enable使能。就是接收使能端。

配置SBUF

不需要。

 配置PCON

配置中断通道相关寄存器

配置中断函数

先认识串口的中断函数

P2==~SBUF:如果SBUF接收的是0x66(0110 0110),那么P2=0110 0110,如果直接P2=SBUF(没有“~”),那么因为LED(LED属于P2寄存器调控)为低电平驱动。就会1,4,5,8位亮。这不好看。为了使LED亮代表“1”,我们“~”。

UART_SendByte():发送数据。

RI=0:手动清零标志位。

实验现象

错误示范

就是UART_SendByte()函数不能同时在main函数与中断函数中调用。会冲突。

就是当此刻电脑发送数据给单片机,此时就会调用接收中断函数UART_Routine()  interrupt  4,从而调用UART_SendByte()函数,但我们会发现,其实main()中while循环一直在调用UART_SendByte()函数,这就引起了同时间调用UART_SendByte()函数两次的情况。

补充  T1溢出率的计算

TL1占8位,用作计数器寄存器。
TH1同样占8位,但用作预装载寄存器。

拿这个做例子,计数器初始值是TL1=0xF3,就是1111 0011二进制,转化为十进制就是1*2^7+1*2^6+1*2^5+1*2^4+1*2^1+1*2^0=243。初始值为243

然后一个一个计时,然而TL1只有8位,最大计数到255(因为从0开始计时,所以是256-1),在255后在记一次数就溢出,所以记到256就溢出。

期间计数13次,而我们拿晶振频率12MHz作比较,经过12分频后,就是1MHz=1*10^6Hz,也就是

1s/1*10^6==1us计数一次

全部计数完成为1*13==13us。而溢出率就是将秒转化为频率,就是1s/13us==76923.0769Hz。

还需要/16。

结果等于76923.0769/16==4807.69Hz。这就是溢出率。

补充  数据显示模式

如图,我们发送一个0x33

在HEX模式下接收的是30。

在文本模式下接收的是0。

这是什么原因呢?

这就是ASCII码

HEX模式就是字符对应的16进制数,

文本模式就是16进制数翻译过来的字符。

同样可以发送字符“B”。

HEX模式就是字符对应的就是0x42

文本模式就是16进制数翻译过来的字符,对应的是“B”。

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。