51单片机学习笔记-6串口通信

6 串口通信

[toc]

注:笔记主要参考B站江科大自化协教学视频“51单片机入门教程-2020版 程序全程纯手打 从零开始入门”。
注:工程及代码文件放在了本人的Github仓库


6.1 串口通信原理

串口是一种应用十分广泛的通讯接口,串口成本低、容易使用、通信线路简单,可实现两个设备的互相通信。单片机的串口可以使单片机与单片机、单片机与电脑、单片机与各式各样的模块互相通信,极大的扩展了单片机的应用范围,增强了单片机系统的硬件实力。51单片机内部自带UART(Universal Asynchronous Receiver Transmitter,通用异步收发器),可实现单片机的串口通信。

图6-1 串口通信接口示意图

上图所示的简单双向串口通信,有两根交叉连接的通信线(发送端TXD和接收端RXD)。当只需单向的数据传输时,可以只接一根通信线。当电平标准不一致时,需要加电平转换芯片。电平标准是数据1和数据0的表达方式,是传输线缆中人为规定的电压与数据的对应关系,串口常用的电平标准有如下三种:

  1. TTL电平:+5V表示1,0V表示0。
  2. RS232电平:(-3V,-15V)表示1,(+3V,+15V)表示0。
  3. RS485电平:两线压差(+2V,+6V)表示1,(-2V,-6V)表示0(差分信号)。
图6-2 DB9接口示意图
图6-3 现代串口应用案例

图6-2是串口通信最经典的DB9接口(单片机不支持流控信号),使用RS232电平标准,但是由于其体积大、速率慢等原因,逐渐的被笔记本电脑领域所淘汰。而为了完成与电脑的串口通信,现代通常使用USB转串口的模块(如上图6-3左)。同时也可以看出,由于51单片机最常用的还是串口通信,所以为了配合51单片机,有许许多多的模块开始与串口通信结合起来。

表6-1 常见通信接口比较
名称引脚定义通信方式特点
UARTTXD:发送端
RXD:接收端
GND:公共(参考)地
全双工、异步点对点通信
I²CSCL:同步时钟
SDA:数据输入/输出端
半双工、同步可挂载多个设备
SPISCLK:同步时钟
MISO:主机输入,从机输出
MOSI:主机输出,从机输入
CS:从设备使能信号,由主设备控制。
全双工、同步可挂载多个设备
1-WireDQ:发送/接收端半双工、异步可挂载多个设备
此外还有CAN(差分传输)、USB等

对于上表的注释:

  • 全双工:通信双方可以在同一时刻互相传输数据
    半双工:通信双方可以互相传输数据,但必须分时复用一根数据线
    单工:通信只能有一方发送到另一方,不能反向传输
  • 异步:通信双方各自约定通信速率
    同步:通信双方靠一根时钟线来约定通信速率
  • 总线:连接各个设备的数据传输线路(类似于一条马路,把路边各住户连接起来,使住户可以相互交流)
  • TXD全称:transmit external data。

在开发板上,I²C用于与EEPROM(AIM23A10)通信,SPI改编后与RTC芯片(DS1302通信),1-Wire用于与温度传感器(DS18B20)通信。CAN总线常用语汽车控制领域,USB协议则在日常生活中最常见。STC89C52只有1个UART(如下图P3.0/P3.1),这个UART有四种工作模式:

模式0:同步移位寄存器
模式1:8位UART,波特率可变(常用)
模式2:9位UART,波特率固定
模式3:9位UART,波特率可变

图6-4 STC89C52上的串口示意图

下面图6-5给出串口通信在单个通信线上的时序图,上面发送和接收各数据位的间隔时间就是 波特率,表明了串口通信的速率。可以看到主要包含 4个部分

  1. 起始位:拉低信号,表明开始传输8bit的数据。
  2. 数据位:每次传输8bit的数据,注意先传输低位LSB。
  3. 检验位(选填):只出现在9位UART的最后一位,用于数据验证。
  4. 停止位:拉高信号,用于数据帧间隔。

注意波特率只能为:4800、9600、115200等约定好的值。

图6-5 串口时序图

由于器件手册中给出的串口模式图过于复杂,包含了许多不利于学习理解的信号。所以下图给出了单片机内部的串口简化模式图。可以看到,最关键就是SBUF(存储发送和接收的数据)、RI(接收完毕中断)、TI(发送完毕的中断)这三个信号,甚至于RXDTXD都不用我们手动配置,只需要关心那两个中断请求就好。

图6-6 串口模式图
  • SBUF:串口数据缓存寄存器,物理上是两个独立的寄存器,但占用相同的地址。对于MCU来说,发送缓冲器只能写入,接收缓冲器只能读出,所以 可以同时操作
  • 根据上面的图可以发现,串口发送/接收所需要的 波特率都只能由定时器T1来提供!!且T1工作在模式3(8位自动重装)。
  • T1溢出率意思为定时器T1的溢出速率,可以SBUF的1bit数据保持时间与波特率一致。
图6-7 串口相关寄存器
  • 串行控制寄存器SCON(可位寻址):选择串行通信的工作方式和某些控制功能。
    SM0/FE:PCON中的SMOD0选择其为SM0时,与下面的SM1共同选择串口工作模式([SM0,SM1]=[0,1]模式1);PCON中的SMOD0选择其为FE时,检测到帧错误则拉高,且必须由软件归零。
    SM2:允许方式2/3多机通信。方式1中,SM2=1则接收到有效的停止位RI才拉高。
    REN:允许/禁止串行接收控制位(1/0)。默认禁止。
    TB8:方式2/3中发送的第9位数据,软件控制。
    RB8:方式2/3要接收的第9位数据。方式
    TI:表明发送完毕的中断请求,停止位开始的发送时拉高,必须软件复位。
    RI:表明接收完毕的中断请求。只有模式0需要软件置位。
  • 波特率选择特殊功能寄存器PCON(不可位寻址):
    SMOD:波特率加倍控制位,软件置位。SMOD=1,工作模式1、2、3波特率加倍;SMOD=0,波特率不加倍。
    SMOD0:帧错误检测有效控制位。决定了SCON 中的SM0/FE被选为FE(帧错误检测)还是SM0(0/1)。
  • IEIPHIP
    由于单片机串口通信用到了RI、TI两个中断,所以还需要配置 串口通信中断源 中断寄存器。可以参考上一节。

6.2 实验:串口向电脑发送数据

需求:单片机不断每秒向电脑发送一个8位递增数字(也可以直接发送单个字符,如’A’)。

图6-8 “串口发送连续数字”代码调用关系

代码展示:
- main.c

#include <REGX52.H>
#include "Delay.h"
#include "UART.h"

void main(){
  unsigned char num = 0x00; // 要发送的变量
  UART_Init(); // 串口初始化
  while(1){
    UART_SendByte(num);
    Delay(1000); // 软件延时,防止打乱定时器的操作
    num += 1;
  }
}

- UART.h

#ifndef __UART_H__
#define __UART_H__

void UART_Init(); // 串口初始化
void UART_SendByte(unsigned char Byte); // 串口发送1Byte数据

#endif

- UART.c

#include <REGX52.H>

/**
  * @brief :串口通信初始化,4800bps@11.0592MHz
  * @param :无
  * @retval :无
 */
void UART_Init(){
  SCON = 0x40; // 串口控制寄存器,暂时接收不使能
  PCON &= 0x7f; // 波特率选择特殊功能寄存器
  
  // 发送数据不需要开启中断,接收数据才需要
  
  // 下面配置定时器,用于波特率设置
  // 注:串口只能用定时器T1(8位自动重装模式)
  TMOD&=0x0F;TMOD|=0x20; //设置定时器模式
	TL1 = 0x66;  //设置定时初始值
	TH1 = 0xFA;  //设置定时初始值
	ET1 = 0;		 //禁止定时器中断,只要有溢出就可以生成波特率
	TR1 = 1;		 //定时器1开始计时
}

/**
  * @brief :通过串口发送8位数据
  * @param :需要发送的8位数据
  * @retval :无。但函数会直到该字节发送完成才返回。
 */
void UART_SendByte(unsigned char Byte){
  SBUF = Byte;
  while(TI==0); // 等待发送完毕
  TI = 0; // 软件复位
}

- Delay.h

#ifndef __DEALY_H_
#define __DEALY_H_

// 延时cycles ms,晶振@11.0592MHz
void Delay(unsigned int cycles){
  unsigned char i, j;
  do{
    i = 2;
    j = 199;
    do{
      while (--j);
    }while (--i);
  }while(--cycles);
}

#endif

6.3 实验:电脑通过串口控制LED

需求:电脑向单片机发送一个8位数字,用于控制8个LED的点亮情况,同时单片机将接收到的数据返回给电脑。

本节实验与上一个实验最大的区别就是,串口初始化的过程中添加了允许串口中断。下面是代码展示:
- main.c

#include <REGX52.H>
#include "UART.h"

void main(){
  UART_Init(); // 串口初始化
  while(1){}
}

// 串口接收中断子函数
// 注意发送和接收两种中断都会进入到这个子函数中来
void UART_Routine() interrupt 4{
  if(RI==1){
    P2 = ~SBUF; // 存储接收到的字节
    RI = 0; // 软件清空接收完成标志
    UART_SendByte(SBUF);
  }
}

- UART.h

#ifndef __UART_H__
#define __UART_H__

void UART_Init(); // 串口初始化
void UART_SendByte(unsigned char Byte); // 串口发送1Byte数据

#endif

- UART.c

#include <REGX52.H>

/**
  * @brief :串口通信初始化,4800bps@11.0592MHz
  * @param :无
  * @retval :无
 */
void UART_Init(){
  SCON = 0x50; // 串口控制寄存器,接收使能
  PCON &= 0x7f; // 波特率选择特殊功能寄存器
  
  // 接收数据需要串口中断
  EA = 1; ES = 1; // 允许全局中断、串口中断
  
  // 下面配置定时器,用于波特率设置
  // 注:串口只能用定时器T1(8位自动重装模式)
  TMOD&=0x0F;TMOD|=0x20; //设置定时器模式
  TL1 = 0xFA;  //设置定时初始值
  TH1 = 0xFA;  //设置定时初始值
  ET1 = 0;		 //禁止定时器中断,只要有溢出就可以生成波特率
  TR1 = 1;		 //定时器1开始计时
}

/**
  * @brief :通过串口发送8位数据
  * @param :需要发送的8位数据
  * @retval :无。但函数会直到该字节发送完成才返回。
 */
void UART_SendByte(unsigned char Byte){
  SBUF = Byte;
  while(TI==0); // 等待发送完毕
  TI = 0; // 软件复位
}

/*串口中断函数模板
// 串口接收中断子函数
// 注意发送和接收两种中断都会进入到这个子函数中来
void UART_Routine() interrupt 4{
  if(RI==1){ // 若接收到1Byte数据
    
  }
}
*/

编程感想:

其实好几次现象不对,都是因为对于串口助手的使用不熟练。注意点的是“发送数据”,而不是“发送回车”;另外发送和接收的模式“文本模式”/“HEX模式”要匹配上。

  • 4
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
### 回答1: 51单片机是一款常用的单片机,它的灵活性高,具有多样化的编程方式和强大的控制能力,因此在许多控制系统中得到广泛应用。而HC-05是一种低成本、易于使用的蓝牙串口模块,它可以使51单片机之间通过无线数据传输实现通信,从而达到无需物理连接的效果。 具体来说,当我们需要两个或多个51单片机进行通信时,可以采用HC-05模块来实现。首先将HC-05模块接入到51单片机的串口中,并通过编程控制51单片机与HC-05模块建立蓝牙连接。然后,在两个单片机之间实现数据传输,就可以实现无线通信了。 其中,数据传输可以采用多种方式实现,例如串口通信、I2C通信等。在传输数据时,需要注意数据格式的统一和错误处理方式的设置,以确保数据的准确传输和处理。 总之,通过使用HC-05模块,我们可以很方便地实现51单片机之间的无线通信,从而大大提高了系统的灵活性和可靠性。 ### 回答2: 51单片机是一种高性能、低功耗的单片机,可以广泛应用于各种嵌入式系统中。而HC-05则是一种基于蓝牙协议的无线串口模块,可以实现低成本、低功耗、短距离的数据传输。在嵌入式系统中,51单片机通过HC-05实现无线通信具有广泛的应用和广阔的市场前景。 首先,51单片机通过串口将需要传输的数据发送到HC-05。HC-05则将数据通过蓝牙信号发送给接收端设备。接收端设备收到数据后,通过串口将数据传输到目标设备。这个过程中,无需连接任何电缆或线路,因此无线通信具有便捷、灵活、高效的特点。 其次,该方案具有可靠的数据传输能力。蓝牙协议使用的是加密技术以及一种错误控制码技术,保证了数据传输的安全性和可靠性。传输端和接收端可以通过协议栈的自动协商功能选择最佳速率,以实现最快的传输速度和最佳的性能表现。 此外,该方案还具有低功耗的特点。蓝牙协议采用了低功耗模式,可以有效降低功耗。同时,蓝牙使用高频率的无线电技术,使信号传输更加稳定,同时又保持低功耗的特点。这对于需要长时间运行且需要频繁数据传输的应用场景非常适合。 总之,51单片机通过HC-05实现无线通信具有广泛的应用前景和重要的意义。通过无线通信的方式,极大地提升了嵌入式系统的可扩展性、可移植性和高效性。因此,在嵌入式系统领域,应用无线通信技术已成为一种重要的趋势和发展方向。 ### 回答3: 51单片机作为一种基础的微型计算机控制芯片,使用广泛。在实际应用中,为了实现控制与数据的远程传输,需要进行无线通信。而hc-05模块则是一种低功耗蓝牙模块,可与51单片机结合实现无线通信。 在使用hc-05模块与51单片机进行无线通信时,需要先将模块与单片机连接。首先,需要将hc-05模块与电脑连接。打开串口助手软件,并将hc-05模块连接到电脑上,按输入AT命令模式的方式进行设置。然后,将hc-05模块与51单片机进行连接,在51单片机中开启串口,并设置相应的波特率。 在通信时,需要先将单片机中需要发送的数据通过串口发送给hc-05模块,在模块中进行蓝牙传输。接收端设备可以是手机,电脑等设备,需要打开对应软件进行接收。将接收到的数据再次通过蓝牙进行传输回hc-05模块,并通过串口传输给单片机单片机再进行处理。 通过hc-05模块实现无线通信,可以大大简化传输过程,提高工作效率。相比有线传输,无线传输可以更加灵活,适应范围也更广。因此,hc-05模块与51单片机的结合成为了不少应用领域的首选方案。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

虎慕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值