串口通信实验

要实现的功能:51单片机通过串口(UART)实现与PC机对话,51单片机的串口收到PC机发来的数据后原封不动的返回给PC机显示。

通信的概念

51单片机不仅可以实现串口通信,还可以通过IO口模拟实现多种其他通信,如SPI、IIC等。通信可以按照数据传送方式分为串行通信和并行通信。按照数据的传输方式可以分为异步通信和同步通信。按照数据的传输方向又可以分为单工、半双工和全双工通信。

串行通信与并行通信

串行通信

串行通信是指使用一条数据线, 将数据一位一位地依次传输, 每一位数据占
据一个固定的时间长度。 其只需要少数几条线就可以在系统间交换信息, 特别适
用于计算机与计算机、 计算机与外设之间的远距离通信。
 

特点: 传输线少,长距离传输成本低,但是数据的传送控制要比并行通信复杂。

并行通信

并行通信通常是将数据字节的各位用多条数据线同时进行传送, 通常是 8
位、 16 位、 32 位等数据一起传输。
 

特点 :控制简单、传输速度快;长距离传输成本高且接收方的各位同时接受存在困难,抗干扰能力差。

异步通信与同步通讯

异步通信

异步通信是指通信的发送与接收设备使用各自的时钟控制数据的发送和接收过程。 为使双方的收发协调, 要求发送和接收设备的时钟尽可能一致。异步通信是以字符(构成的帧) 为单位进行传输, 字符与字符之间的间隙(时间间隔) 是任意的, 但每个字符中的各位是以固定的时间传送的, 即字符之间不一定有“位间隔” 的整数倍的关系, 但同一字符内的各位之间的距离均为“ 位
间隔” 的整数倍。
特点:不要求收发双方时钟的严格一致,实现容易,设备开销小,但是每个字符需要附加2~3位用于起止位,各帧之间还有间隔,传输效率不高。

同步通讯

同步通信时要建立发送方时钟对接收方时钟的直接控制, 使双方达到完全同
。 此时, 传输数据的位之间的距离均为“位间隔” 的整数倍, 同时传送的字符
间不留间隙, 即保持位同步关系, 也保持字符同步关系。 发送方对接收方的同步
可以通过两种方法实现。
 

单工、半双工与全双工通信

单工通信:单工是指数据传输只能沿一个方向,不能实现反向传输。

半双工通信:数据传输可以沿两个方向,但是需要分时进行。

全双工通信:数据可以同时进行双向传输。

通信速率

用比特率来表示。比特率是每秒钟传输二进制代码的位数,单位是位/秒(bps)。

波特率表示每秒钟传输了多少个码元。码元是通信信号调制的概念,通信中常用时间间隔相同的符号来表示一个二进制数字,这样的信号叫做码元。如常见的通信传输中, 用 0V 表示数字 0, 5V 表示数字 1, 那么一个码元可以表示两种状态 0 和 1, 所以一个码元等于一个二进制比特位, 此时波特率的大小与比特率一致;如果在通信传输中, 有 0V、 2V、4V 以及 6V 分别表示二进制数 00、 01、 10、 11, 那么每个码元可以表示四种状态, 即两个二进制比特位, 所以码元数是二进制比特位数的一半, 这个时候的波特率为比特率的一半。

单片机串口介绍

串口通信简介

串口通信(Serial Communication), 是指外设和计算机间通过数据信号线、地线等按位进行传输数据的一种通信方式, 属于串行通信方式。 串口是一种接口标准, 它规定了接口的电气标准, 没有规定接口插件电缆以及使用的协议。

接口标准:

 在串口通信中, 通常我们只使用 2、 3、 5 三个管脚。

RS-232C 对逻辑电平也做了规定, 如下:
在 TXD 和 RXD 数据线上:
1.逻辑 1 为-3~-15V 的电压
2.逻辑 0 为 3~15V 的电压
在 RTS、 CTS、 DSR、 DTR 和 DCD 等控制线上:
1.信号有效( ON 状态) 为 3~15V 的电压
2.信号无效( OFF 状态) 为-3~-15V 的电压

由此可见, RS-232C 是用正负电压来表示逻辑状态, 与晶体管-晶体管逻辑集成电路(TTL) 以高低电平表示逻辑状态的规定正好相反。 而我们 51 单片机使用的就是 TTL 电平, 所以要实现 51 单片机与计算机的串口通信, 需要进行 TTL与 RS-232C 电平转换, 通常使用的电平转换芯片是 MAX232
串口通信中还需要注意的是, 串口数据收发线要交叉连接, 计算机的 TXD要对应单片机的 RXD, 计算机的 RXD 要对应单片机的 TXD, 并且共 GND。
 

 通信协议

RS232 的通信协议比较简单, 通常遵循 96-N-8-1 格式。
“96” 表示的是通信波特率为 9600。 串口通信中通常使用的是异步串口通信, 即没有时钟线, 所以两个设备要通信, 必须要保持一致的波特率, 当然, 波特率常用值还有 4800、 115200 等。
“N” 表示的是无校验位, 由于串口通信相对更容易受到外部干扰导致传输数据出现偏差, 可以在传输过程加上校验位来解决这个问题。 校验方法有奇校验(odd)、 偶校验(even)、 0 校验(space)、 1 校验(mark)以及无校验(noparity)。具体的介绍, 大家可以百度串口通信了解。
“8”表示的是数据位数为 8 位, 其数据格式在前面介绍异步通信中已讲过。
当然数据位数还可以为 5、 6、 7 位长度。“1” 表示的是 1 位停止位, 串口通讯的一个数据包从起始信号开始, 直到停止信号结束。 数据包的起始信号由一个逻辑 0 的数据位表示, 而数据包的停
止信号可由 0.5、 1、 1.5 或 2 个逻辑 1 的数据位表示, 只要双方约定一致即可。

串口内部结构

 TXD 和 RXD 为单片机 IO 口, TXD 对应的是 P3.1 管脚, RXD 对应的是 P3.0 管脚。

串口相关寄存器

串口控制寄存器

 SM0 和 SM1 为工作方式选择位:

 SM2: 多机通信控制位, 主要用于方式 2 和方式 3。 当 SM2=1 时可以利用收到的 RB8 来控制是否激活 RI(RB8=0 时不激活 RI, 收到的信息丢弃; RB8=1 时收到的数据进入 SBUF, 并激活 RI, 进而在中断服务中将数据从 SBUF 读走) 。 当SM2=0 时, 不论收到的 RB8 为 0 和 1, 均可以使收到的数据进入 SBUF, 并激活 RI(即此时 RB8 不具有控制 RI 激活的功能) 。 通过控制 SM2, 可以实现多机通信。

REN: 允许串行接收位。 由软件置 REN=1, 则启动串行口接收数据; 若软件置REN=0, 则禁止接收。

RB8: 在方式 2 或方式 3 中, 是接收到数据的第 9 位, 作为奇偶校验位或地址帧/数据帧的标志位。 在方式 1 时, 若 SM2=0, 则 RB8 是接收到的停止位。

TI: 发送中断标志位。 在方式 0 时, 当串行发送第 8 位数据结束时, 或在其它方式, 串行发送停止位的开始时, 由内部硬件使 TI 置 1, 向 CPU 发中断申请。在中断服务程序中, 必须用软件将其清 0, 取消此中断申请。
RI: 接收中断标志位。 在方式 0 时, 当串行接收第 8 位数据结束时, 或在其它方式, 串行接收停止位的中间时, 由内部硬件使 RI 置 1, 向 CPU 发中断申请。也必须在中断服务程序中,用软件将其清 0, 取消此中断申请。

电源控制寄存器

SMOD: 波特率倍增位。 在串口方式 1、 方式 2、 方式 3 时, 波特率与 SMOD 有关, 当 SMOD=1 时, 波特率提高一倍。 复位时, SMOD=0。

串口工作方式

方式0

方式 0 时, 串行口为同步移位寄存器的输入输出方式。 主要用于扩展并行输入或输出口。 数据由 RXD(P3.0) 引脚输入或输出, 同步移位脉冲由 TXD(P3.1)引脚输出。 发送和接收均为 8 位数据, 低位在先, 高位在后。 波特率固定为fosc/12。
方式0输出

方式0输入

 方式1

方式 1 是 10 位数据的异步通信口。 TXD 为数据发送引脚, RXD 为数据接收引脚, 传送一帧数据的格式如下所示。 其中 1 位起始位, 8 位数据位, 1 位停止位。

方式1输出

 

方式1输入

 

 用软件置 REN 为 1 时, 接收器以所选择波特率的 16 倍速率采样 RXD 引脚电平, 检测到 RXD 引脚输入电平发生负跳变时, 则说明起始位有效, 将其移入输入移位寄存器, 并开始接收这一帧信息的其余位。 接收过程中, 数据从输入移位寄存器右边移入, 起始位移至输入移位寄存器最左边时, 控制电路进行最后一次移位。 当 RI=0, 且 SM2=0(或接收到的停止位为 1) 时, 将接收到的 9 位数据的前8 位数据装入接收 SBUF, 第 9 位(停止位) 进入 RB8, 并置 RI=1, 向 CPU 请求中断。

方式2和方式3

方式 2 或方式 3 时为 11 位数据的异步通信口。 TXD 为数据发送引脚, RXD 为
数据接收引脚。
 

 输入输出时序图

输出

 发送开始时, 先把起始位 0 输出到 TXD 引脚, 然后发送移位寄存器的输出位(D0) 到 TXD 引脚。 每一个移位脉冲都使输出移位寄存器的各位右移一位, 并由TXD 引脚输出。 第一次移位时, 停止位“1” 移入输出移位寄存器的第 9 位上,以后每次移位, 左边都移入 0。 当停止位移至输出位时, 左边其余位全为 0, 检测电路检测到这一条件时, 使控制电路进行最后一次移位, 并置 TI=1, 向 CPU请求中断。

输入

 接收时, 数据从右边移入输入移位寄存器, 在起始位 0 移到最左边时, 控制电路进行最后一次移位。 当 RI=0, 且 SM2=0(或接收到的第 9 位数据为 1) 时,接收到的数据装入接收缓冲器 SBUF 和 RB8(接收数据的第 9 位) , 置 RI=1, 向CPU 请求中断。 如果条件不满足, 则数据丢失, 且不置位 RI, 继续搜索 RXD 引脚的负跳变。

串口的使用方法

(1)计算波特率

  • 方式 0 的波特率 = fosc/12
  • 方式 2 的波特率 =(2SMOD/64) · fosc
  • 方式 1 的波特率 =(2SMOD/32) · (T1 溢出率)
  • 方式 3 的波特率 =(2SMOD/32) · (T1 溢出率)
  • 其中 T1 溢出率 = fosc /{12× [256 -(TH1) ]}

使用工具:51波特率初值设定

选择定时器工作方式, 输入开发板上使用的晶振频率大小, 选择所要使用的波特率, SMOD 为是否倍频, 这个在前面介绍寄存器时说过, 下面的误差大小可以反映出通信时是否出现乱码。 在使用串口通信时, 定时器 1 工作方式为 2,串口工作方式为 1, 以开发板晶振是 11.0592Mh 为例, 假如晶振频率是 12M, 那么在生成的波特率就会有误差而导致通信出错。 为什么替换可以从误差值反映出来。 在本章实验中波特率选择 9600, 使用 SMOD, 即值为 1, 点击确定后即会自动生成定时/计数器 THx 的值。

 

(2)串口初始化步骤

  • 确定 T1 的工作方式(TMOD 寄存器);
  • 确定串口工作方式(SCON 寄存器);
  • 计算 T1 的初值(设定波特率), 装载 TH1、 TL1;
  • 启动 T1(TCON 中的 TR1 位);
  • 如果使用中断, 需开启串口中断控制位(IE 寄存器)。

例如: 设置串口为工作方式 1、 波特率为 9600、 波特率加倍、 使用中断。 其配置程序如下:
 

//串口通信中断配置函数, 通过设置 TH 和 TL 即可确定定时时间。baud: 波特率对应的 TH、 TL 装载值
void uart_init(unsigned char baud){
    TMOD |= 0x20;//设置计数器工作方式2
    SCON = 0x50;//设置为工作方式1
    PCON = 0x80;//波特率加倍
    TH1 = baud ;//计数器初值设置
    TL1 = baud ;//
    ES =1;//打开接收中断;
    EA =1;//打开总中断
    TR1 = 1;//打开计数器
}

主函数调用:

uart_init(0xfa);//波特率为9600

硬件设计

 从上图中可以看出, 通过 CH340 芯片把 51 单片机的串口与 PC 机的 USB 口进行连接, 不仅可以实现程序的烧入, 还可实现串口通信功能。 根据前面介绍,串口通信需将数据收发管脚交叉连接, 所以可以看到在 CH340 芯片的 2 和 3 脚已做处理。 电路中其他部分是自动下载电路部分, 目的是控制单片机的电源, 无需冷启动。 使用 USB 转串口芯片, 免去了一根串口线, 使用普通 USB 数据线(支持安卓手机数据线) 就可以进行串口通信。

从上图中可以看到 CH340 的 2、 3 脚串口并非直接连接到单片机串口, 而是连接在 P5 端子上, 这样就把 CH340 的串口与单片机串口独立出来, 为什么不直接连接而要使用这个 P5 端子呢? 这是方便用户可以使用开发板上的 USB 转 TTL模块(也就是 CH340 转串口模块) 做一些串口类模块的调试, 比如: WIFI、 蓝牙、GPS、 GPRS 等, 直接利用 PC 上位机来调试模块。 同时也方便用户使用板载 USB转 TTL 模块给其它类型单片机下载程序。

如果使用黄色跳线帽将 P5 端子的 1、 2 短接, 3、 4 短接, 那么 CH340 串口与单片机串口是连接一起的, 此时即可实现程序的下载或串口通信。

软件设计

本章所要实现的功能是: 当串口助手发送数据给单片机, 单片机原封不动转发给串口助手显示。
 

#include <REG52.H>

void uart_init(unsigned char baud)
{
    TMOD |= 0x20;
    SCON = 0x50;
    PCON = 0x80;
    TH1  = baud;
    TL1  = baud;
    ES   = 1;
    EA   = 1;
    TR1  = 1;
}

void main()
{
    uart_init(0xfa);

    while (1)
        ;
}

void uart() interrupt 4
{
    unsigned char rec_date;

    RI       = 0;        // 清除接收中断标志位
    rec_date = SBUF;     // 存储接收到的数据
    SBUF     = rec_date; // 将接收到的数据放入到发送寄存器
    while (!TI)
        ; // 等待数据发送完成
    TI = 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值