单片机的串口通信
今天,完整地总结一下普中科技的单片机的串口通信的硬件与编程,记录一下以后如果需要也比较方便捡起来。
单片机的串口部分的电路图。开发板上集成了 1 个串口通信电路,是 USB 转串口模块,它既可下载程序也可实现串口通信功能。

对这个模块简要分析一下输入输出。

描述一下CH340芯片的作用。(带你全面解析USB转串口芯片CH340 - 采芯网 (findic.com))

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

串口相关的寄存器。


我们一般选择串口工作在方式1下,定时器1工作在方式2下(8位自动重装)。
        定时器(定时器1)与波特率的关系。

SBUF介绍
 
串口初始化。
void uart_init(u8 baud)
{
TMOD|=0X20; //设置计数器工作方式 2
SCON=0X50; //设置为工作方式 1
PCON=0X80; //波特率加倍
TH1=baud; //计数器初始值设置
TL1=baud;
ES=1; //打开串口中断
EA=1; //打开总中断
/*定时器1的方式2是8位自动重装,定时器一旦溢出,就自动重装,与中断无关,所以定时器1进入中断后无事可做,所以无需打开定时器1的中断*/
TR1=1; //打开计数器
}
void main()
{
uart_init(0XFA);//波特率为 9600
while(1)
{
}
}
void uart() interrupt 4 //串口通信中断函数
{
u8 rec_data;
RI = 0; //清除接收中断标志位
rec_data=SBUF; //存储接收到的数据
SBUF=rec_data; //将接收到的数据放入到发送寄存器
while(!TI); //等待发送数据完成
TI=0; //清除发送完成标志位
}完整程序如下所示
#include "reg52.h"typedef unsigned int u16;	//对系统默认数据类型进行重定义
typedef unsigned char u8;/*******************************************************************************
* 函 数 名       : uart_init
* 函数功能		 : 串口通信中断配置函数,通过设置TH和TL即可确定定时时间
* 输    入       : baud:波特率对应的TH、TL装载值
* 输    出    	 : 无
*******************************************************************************/
void uart_init(u8 baud)
{TMOD|=0X20;	//设置计数器工作方式2SCON=0X50;	//设置为工作方式1PCON=0X80;	//波特率加倍TH1=baud;	//计数器初始值设置TL1=baud;ES=1;		//打开接收中断EA=1;		//打开总中断TR1=1;		//打开计数器		
}/*******************************************************************************
* 函 数 名       : main
* 函数功能		 : 主函数
* 输    入       : 无
* 输    出    	 : 无
*******************************************************************************/
void main()
{	uart_init(0XFA);//波特率为9600while(1){			}		
}void uart() interrupt 4 //串口通信中断函数
{u8 rec_data;RI = 0;			//清除接收中断标志位rec_data=SBUF;	//存储接收到的数据SBUF=rec_data;	//将接收到的数据放入到发送寄存器while(!TI);		//等待发送数据完成TI=0;			//清除发送完成标志位				
}我在其他博客看到的一些串口代码。
#include <REGX52.H>/* *** @brief 串口初始化		//4800bps@11.0592MHz* @param 无* @retval 无*/
void UART_Init(void)		//4800bps@11.0592MHz
{PCON |= 0x80;		//使能波特率倍速位SMODSCON = 0x50;		//8位数据,可变波特率TMOD &= 0x0F;		//清除定时器1模式位TMOD |= 0x20;		//设定定时器1为8位自动重装方式TL1 = 0xF4;		//设定定时初值TH1 = 0xF4;		//设定定时器重装值ET1 = 0;		//禁止定时器1中断TR1 = 1;		//启动定时器1EA = 1;			//启动所有中断ES = 1;			//启动串口中断
}/* *	串口发送模板* @brief 串口发送一个字节数据* @param Byte 要发送的一个数据* @retval 无*/void UART_SendByte(unsigned char Byte)
{SBUF = Byte;while(TI == 0); //一执行完就要复位TI = 0;         //TI为发射控制器;RI为接受控制器;
}/*串口中断函数模板
void UART_Routine() interrupt 4
{if(RI = 1){RI = 0;}
}*/串口的发送与接收数据的过程与串口中断一点关系都没有,并不是不开串口中断就说明禁止了单片机的串口通信,单片机的串口中断只是提供了那么一种方法,即当你接收完数据或者发送完数据,想要先停止此时的串口通讯,进行其他的诸如数据处理的任务,不管是否开中断,只要将数据放入到SBUF中,就一定会将数据发送出去。定时器也是如此,不管有没有开中断,定时器都是在定时的,只不过有些工作方式在定时一次后,再一次定时时初始值会发生变化(工作方式2会自动重装)。
在串口发送数据的时候,自己不用考虑起始位以及停止位,将数据写入到SBUF中(肯定没有起始位以及停止位),单片机发送的时候会自动将数据包装,在前面和后面加上起始位以及停止位。

串口调试工具


我自己随便写了个PC端控制单片机LED亮灭的程序。
#include "reg52.h"typedef unsigned int u16;	//对系统默认数据类型进行重定义
typedef unsigned char u8;sbit LED1=P2^0;	//将P2.0管脚定义为LED1/*******************************************************************************
* 函 数 名       : uart_init
* 函数功能		 : 串口通信中断配置函数,通过设置TH和TL即可确定定时时间
* 输    入       : baud:波特率对应的TH、TL装载值
* 输    出    	 : 无
*******************************************************************************/
void uart_init(u8 baud)
{TMOD|=0X20;	//设置计数器工作方式2SCON=0X50;	//设置为工作方式1PCON=0X80;	//波特率加倍TH1=baud;	//计数器初始值设置TL1=baud;ES=1;		//打开接收中断EA=1;		//打开总中断TR1=1;		//打开计数器		
}void delay_10us(u16 ten_us)
{while(ten_us--);	
}
/*******************************************************************************
* 函 数 名       : main
* 函数功能		 : 主函数
* 输    入       : 无
* 输    出    	 : 无
*******************************************************************************/
void main()
{	uart_init(0XFA);//波特率为9600while(1){						}		
}void send_Byte(u8 rec_data)
{SBUF=rec_data;	//将接收到的数据放入到发送寄存器while(!TI);		//等待发送数据完成TI=0;			//清除发送完成标志位	
}void uart() interrupt 4 //串口通信中断函数
{if(RI){u8 rec_data;rec_data=SBUF;	//存储接收到的数据if(rec_data == 'G' || rec_data == 'g'){LED1=0;	//点亮delay_10us(50000); //大约延时450msLED1=1;	//熄灭delay_10us(50000);}send_Byte(rec_data);RI = 0;			//清除接收中断标志位}
}printf重定向简介


char putchar(char c)
{SendByte(c);return c;
}void SendByte(unsigned char data)
{SBUF = data;while(!TI);TI = 0;
}附录:
51单片机之寄存器-3.3单片机串口通信之发送与接收 - 微波EDA网 (mweda.com)
单片机串行通信总结_单片机接收sbuff的条件为ri_tony_0620的博客-CSDN博客
51单片机的串口通信(UART)及其应用_51单片机 uart_小菜冀的博客-CSDN博客
相关文章:
 
单片机的串口通信
今天,完整地总结一下普中科技的单片机的串口通信的硬件与编程,记录一下以后如果需要也比较方便捡起来。 单片机的串口部分的电路图。开发板上集成了 1 个串口通信电路,是 USB 转串口模块,它既可下载程序也可实现串口通信功能。 对…...
【C/C++】STL学习所得
文章目录 STL 框架核心组成部分STL 序列容器分类STL 容器适配器分类STL 迭代器分类STL 中一些易混淆知识点一些重要的简述 STL 框架核心组成部分 算法容器迭代器适配器空间配置器访函数 STL 序列容器分类 vectorqueuelistarrayforward_list STL 容器适配器分类 stack 栈qu…...
 
leetcode几个数组题
数组理论基础 数组是存放在连续内存空间上的相同类型数据的集合 因为数组的在内存空间的地址是连续的,所以我们在删除或者增添元素的时候,就难免要移动其他元素的地址 二分查找 移除元素 有序数组的平方 209.长度最小的子数组...
 
【LeetCode】模拟实现FILE以及认识缓冲区
模拟实现FILE以及认识缓冲区 刷新缓冲逻辑图自定义实现如何强制刷新内核缓冲区例子 刷新缓冲逻辑图 自定义实现 mystdio.h #pragma once #include <stdio.h>#define NUM 1024 #define BUFF_NOME 0x1 #define BUFF_LINE 0x2 #define BUFF_ALL 0x4typedef struct _MY_FIL…...
 
【Terraform学习】使用 Terraform 将 EC2 实例作为 Web 服务器启动(Terraform-AWS最佳实战学习)
使用 Terraform 将 EC2 实例作为 Web 服务器启动 实验步骤 前提条件 安装 Terraform: 地址 下载仓库代码模版 本实验代码位于 task_ec2 文件夹中。 变量文件 variables.tf 在上面的代码中,您将声明,aws_access_key,aws_secr…...
 
WebGL 变量uniform、gl.getUniformLocation、gl.uniform4f及其同族函数相关
目录 uniform变量命名规范 获取 uniform 变量的存储地址 gl.getUniformLocation 向uniform变量赋值 gl.uniform4f 编辑 gl.uniform4f()的同族函数 demo:点击webgl坐标系的四个象限绘制各自不同颜色的点 uniform变量命名规范 var FSHADER_SOURCE uniform vec4…...
 
【Visual Studio】生成.i文件
环境 VS版本:VS2013 问题 如何生成.i预编译文件? 步骤 1、打开VS项目属性,打开C/C\预处理器页面,【预处理到文件】选择是,开启。 2、生成文件如下。 3、正常编译需要关闭此选项。...
 
本地生活服务平台加盟哪家公司好?
本地生活的竞争从年初的火热到现在,已经进入了下半场,随着优胜劣汰的筛选,那么直到现在,想做本地生活服务平台加盟,哪家公司比较好呢,应该如何选择呢? 首先我们得弄懂,我们加盟本地…...
css-grid使用
文章目录 grid概念容器和项目网格轨道:网格单元网格线 使用分配item空间大小对于子元素的意义 行列指定隐式和显示网格默认排列 grid容器属性grid-template-rows: 100px 100px 200px;grid-template-columns: 100px 100px 100px;grid-auto-rows: 200pxgrid-column-ga…...
springBoot提取一个List<?>中的某个字段集合
import cn.hutool.core.collection.CollUtil;PageResult prrecommendUserApi.queryRecommendUserList(dto.getPage(),dto.getPagesize(),userId);List<RecommendUser> items (List<RecommendUser>) pr.getItems(); //提取所有推荐的用户id List<Long> ids …...
【BUG】 ‘cv2.cv2‘ ‘wechat_qrcode_WeChatQRCode‘
首发博客地址 https://blog.zysicyj.top/ 报错内容 AttributeError: module cv2 has no attribute wechat_qrcode_WeChatQRCode 解决方法 pip install opencv-pythonpip install opencv-contrib-python 本文由 mdnice 多平台发布...
 
10 Mybatis
文章目录 1 概述1.1 什么是Mybatis?1.2 JDBC介绍(了解)1.2.1 问题分析1.2.2 技术对比 1.3 数据库连接池1.4 lombok 2 Mybatis基础操作2.1 准备2.2 删除2.2.1 日志输入2.2.2 预编译SQL2.2.2.1 介绍2.2.2.2 SQL注入2.2.2.3 参数占位符 2.3 新增2.3.1 主键返回 2.4 更新2.5 查询2…...
【PHP】PHP的面向对象编程
PHP面向对象编程是PHP编程的一个重要方向,它通过将数据和操作封装在对象中,使得代码更加模块化、可重用性和易于维护。本文将介绍PHP面向对象编程的基本概念、核心思想和常见应用,并探讨使用PHP面向对象编程时需要注意的问题。 一、概述 PH…...
 
Windows10突然出现音频无法正常运行的解决方法
文章目录 前言 一 问题描述 二 解决方法 2.1 下载完成之后选择安装 2.2 选择其他位置来安装 2.3 静静等待安装完成 三 升级Windows显卡和声卡 总结 前言 本文主要介绍Windows里面的音频出现问题的解决方法 一 问题描述 Windows使用好好的,突然就出现声卡出…...
Maven面试题大全及答案
1.什么是Maven? Maven使用项目对象模型(POM)的概念,可以通过一小段描述信息来管理项目的构建,报告和文档的软件项目管理工具。 Maven 除了以程序构建能力为特色之外,还提供高级项目管理工具。由于 Maven 的缺省构建规则有较高的可…...
探究字符串匹配算法:暴力法与KMP算法的Java实现
探究字符串匹配算法:暴力法与KMP算法的Java实现 字符串匹配是计算机科学中的基本问题之一,它涉及在一个主串中查找特定的子串。在本文中,我们将深入探讨暴力法和KMP算法这两种常见的字符串匹配算法,并提供详细的Java代码示例。 …...
前端面试:【浏览器与渲染引擎】工作原理与渲染流程
嗨,亲爱的读者!你是否曾经好奇过当你在浏览器中输入URL并按下回车时,网页是如何显示在你的屏幕上的?这背后涉及了复杂的浏览器工作原理和渲染流程。本文将带你深入了解浏览器如何工作以及网页如何被渲染出来。 1. 浏览器的工作原理…...
 
PySide6学习笔记--gui小模版使用
一、界面绘制 1.desiner画图 2.画图代码 # -*- coding: utf-8 -*-################################################################################ ## Form generated from reading UI file t1gui.ui ## ## Created by: Qt User Interface Compiler version 6.5.2 ## ##…...
如何用Python实现冒泡排序
1 问题 冒泡排序是一种简单的排序算法,它也是一种稳定排序算法。其实现原理是重复扫描待排序序列,并比较每一对相邻的元素,当该对元素顺序不正确时进行交换。一直重复这个过程,直到没有任何两个相邻的元素可以交换,就表…...
 
C++Qt堆叠窗体的使用案例
本博文源于笔者最近学习的Qt,内容讲解堆叠窗体QStackedWidget案例,效果是选择左侧列表框中不同的选项时,右侧显示所选的不同的窗体。 案例效果 案例书写过程 控件都是动态创建的,因此.h文件需要创建控件,.cpp书写业务…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...
 
51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...
 
css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
 
为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?
在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...
 
基于当前项目通过npm包形式暴露公共组件
1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹,并新增内容 3.创建package文件夹...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...
 
SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...
 
【从零学习JVM|第三篇】类的生命周期(高频面试题)
前言: 在Java编程中,类的生命周期是指类从被加载到内存中开始,到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期,让读者对此有深刻印象。 目录 …...
 
【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)
前言: 双亲委派机制对于面试这块来说非常重要,在实际开发中也是经常遇见需要打破双亲委派的需求,今天我们一起来探索一下什么是双亲委派机制,在此之前我们先介绍一下类的加载器。 目录 编辑 前言: 类加载器 1. …...

 
 