51单片机学习9 串口通讯

51单片机学习9 串口通讯

一、串口通讯简介

51单片机的串口通信是通过内置的串行通信口(UART)实现的,常用于与外部设备进行数据交换。

串口通信是一种基于串行传输的数据通信方式,通过一根数据线和一根时钟线(或不需要时钟线)进行数据传输。数据按照一定的规则和时序被发送和接收。

UART

串口通信通常使用异步串行通信协议(UART),其中数据按照一定的帧格式进行传输,包括起始位、数据位、校验位和停止位等。常见的串口通信速率(波特率)有9600、19200、38400等。

STC89C51RC/RD+的串口资源

STC89C51RC/RD+内置2个互相独立的接收、发送缓冲器,可以同时发送和接收数据。 两个缓冲器可以共用一个地址码 99H。

两个缓冲器统称串行通信特殊功能寄存器SBUF。

二、51单片机串口介绍

1. 内部结构

如图所示:

  • TXD:接P3.1引脚
  • RXD:接P3.0引脚
  • SBUF 是缓冲区,分为发送缓冲区和接收缓冲区。
  • TH1和TL1是定时器1的功能,需要工作在方式2(自动重载模式),用来设置波特率;
  • 接收数据时,数据从引脚接收,通过移位寄存器接收到 SBUF,然后控制寄存器把RI置1(接收中断),然后触发中断;
  • 发送数据时,SBUF传到控制门,由发送控制器控制TI 触发中断;

2. 寄存器

(1)串口控制寄存器SCON

SCON 寄存器结构

Bit:   7      6      5      4      3      2      1      0
      ┌────┬────┬────┬────┬────┬────┬────┬────┐
      │ SM0 │ SM1 │ SM2 │ REN │ TB8 │ RB8 │ TI  │ RI  │
      └────┴────┴────┴────┴────┴────┴────┴────┘

SCON 寄存器各位的功能

  • 位7-5:SM0、SM1、SM2(串口工作模式位)
  • 这三位用于设置串口工作的不同模式。它们的具体含义如下:
  • SM0、SM1:用于设置串口工作的模式,共有四种工作模式,包括模式0、模式1、模式2和模式3。
SM1 SM0 工作模式 描述
0 0 模式0 移位寄存器,波特率固定
0 1 模式1 10位异步收发器(8位数据),波特率可变
1 0 模式2 11位异步收发器(9位数据),波特率固定
1 1 模式3 11位异步收发器(9位数据),波特率可变
  • SM2:用于设置串口是否工作在多机通信模式,一般工作在单机模式时,该位为0。

  • 位4:REN(接收允许位): 该位用于控制串口的接收功能,置1时允许串口接收数据,清0时禁止串口接收数据。

  • 位3:TB8(发送位8): 该位用于设置在串口工作在模式2或模式3时发送的数据的第9位,通常用于设置奇偶校验位。

  • 位2:RB8(接收位8): 该位用于存储在串口接收到的数据的第9位,通常用于接收端的奇偶校验检测。

  • 位1:TI(发送中断标志位): 该位用于指示串口发送数据的中断标志,发送完一帧数据后会被置1,需要在中断服务程序中清零。

  • 位0:RI(接收中断标志位): 该位用于指示串口接收数据的中断标志,接收到一帧数据后会被置1,需要在中断服务程序中清零。

(2)电源控制寄存器PCON

PCON全称为Power Control Register(电源控制寄存器),它包含了一些与单片机的电源管理相关的控制位。

PCON寄存器结构

Bit:   7      6      5      4      3      2      1      0
      ┌────┬────┬────┬────┬────┬────┬────┬────┐
      │ SMOD │ SMOD0│---- │ ---- │ ---- │ ---- │ POF0 │ POF1 │
      └────┴────┴────┴────┴────┴────┴────┴────┘

PCON寄存器各位的功能

  • 位7:SMOD(串口波特率倍增控制位)

    • SMOD用于控制串口波特率是否加倍。置1时,串口波特率加倍;清0时,不加倍。
  • 位6:SMOD0(串口0波特率倍增控制位)

    • 该位是SMOD的扩展位,一般在多串口通信时使用。SMOD置1时,SMOD0表示串口0的波特率是否加倍;SMOD清0时,该位无效。
      其它位与串口通讯没大关系。

3. 计算波特率

使用本文开源地址里的 51 波特率计算.exe 工具:

注意软件里设置定时器1的定时器方式,不是串口的工作方式。

SMOD:是否倍频(不是波特率加倍,只是计算初始值变化)。

晶振频率最好使用11.0592,这样误差比较小。

4. 串口配置步骤

  1. 通过TMOD寄存器 确定定时器T1工作方式2(自动重载) ;
  2. 通过SCON寄存器 确定串口工作方式 ;
  3. 计算T1的初值,设定波特率,装载 TH1,TL1;
  4. 启动定时器T1;
  5. 开启中断;
  6. 串口初始化;

三、 开发示例

1. 硬件电路

开发板使用USB转串口电路,同时也是下载模块的电路。

2. 代码实现

本代码效果: 串口接收数据后,原样返回串口。

uart_utils.c

c 复制代码
#include "uart_utils.h"
#include <reg52.h>

/**
* @brief 串口初始化
*/
void uart_init(u8 baud){
    // 设置计数器1的工作方式2
    TMOD = 0x20;
    // 设置定时器1的工作方式1
    SCON = 0x50; // 0b01010000 
    // 波特率倍频
    PCON = 0x80; // 0b10000000
    // 计数器初始值
    TH1 = baud;
    TL1 = baud;
    // 打开接收中断
    ES = 1; 
    // 打开总中断
    EA = 1;
    // 启动定时器1
    TR1 = 1;
}
/**
* @brief 串口发送数据
*/
void uart_send(u8 dat){
    SBUF = dat;
    while(!TI);
    TI = 0;
}
/**
* @brief 使用中断接收串口数据
*/
void uart_recv() interrupt 4{
    u8 dat;
    if(RI){
        RI = 0;
        dat = SBUF;
        uart_send(dat);
    }
}

main.c

c 复制代码
#include <reg52.h>
#include "led_utils.h"
#include "common_utils.h"
#include "types.h"
#include "timer_utils.h"
#include "uart_utils.h"

/**
* @brief 主函数
*/
main()
{
	// 关闭所有led
	led_all_off();
	uart_init(0xfa);
	while(1)
	{
		
	}
}

操作步骤:

  1. 烧录程序;
  2. 在电脑打开串口调试助手,连接开发板串口,点打开,如下图所示;
  3. 在发送区输入字符,点发送。

调试效果:

本文代码开源地址:

https://gitee.com/xundh/learn51.git

相关推荐
@小博的博客2 小时前
C++初阶学习第十弹——深入讲解vector的迭代器失效
数据结构·c++·学习
南宫生2 小时前
贪心算法习题其四【力扣】【算法学习day.21】
学习·算法·leetcode·链表·贪心算法
scan13 小时前
单片机串口接收状态机STM32
stm32·单片机·串口·51·串口接收
懒惰才能让科技进步3 小时前
从零学习大模型(十二)-----基于梯度的重要性剪枝(Gradient-based Pruning)
人工智能·深度学习·学习·算法·chatgpt·transformer·剪枝
love_and_hope3 小时前
Pytorch学习--神经网络--搭建小实战(手撕CIFAR 10 model structure)和 Sequential 的使用
人工智能·pytorch·python·深度学习·学习
Chef_Chen3 小时前
从0开始学习机器学习--Day14--如何优化神经网络的代价函数
神经网络·学习·机器学习
芊寻(嵌入式)3 小时前
C转C++学习笔记--基础知识摘录总结
开发语言·c++·笔记·学习
Qingniu013 小时前
【青牛科技】应用方案 | RTC实时时钟芯片D8563和D1302
科技·单片机·嵌入式硬件·实时音视频·安防·工控·储能
hong1616884 小时前
跨模态对齐与跨领域学习
学习
阿伟来咯~5 小时前
记录学习react的一些内容
javascript·学习·react.js