串口工作方式
串口工作方式
- 方式0
- 方式0输出
- 方式0输入
- 方式1
- 方式1输出
- 方式1输入
- 方式2或方式3
- 输出
- 输入
- 串口使用方法
- 如何计算波特率
- 串口初始化步骤
- 串口回传实验
- 模拟printf实验
- 串口接收数据不丢失实验
方式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 引脚 的负跳变。
串口使用方法
如何计算波特率
(256 - TH1) = 11.0592M/12169600,所以TH1=TL1=250;
串口初始化步骤
如何使用串口,大家可以按照以下几个步骤配置。
- ①确定 T1 的工作方式(TMOD 寄存器);
- ②确定串口工作方式(SCON 寄存器);
- ③计算 T1 的初值(设定波特率),装载 TH1、TL1;
- ④启动 T1(TCON 中的 TR1 位);
- ⑤如果使用中断,需开启串口中断控制位(IE 寄存器)。
串口回传实验
//功能:串口回传实验,PC通过串口通讯工具,发送字符a或字符串hello,MCU回复相同内容#include "reg52.h"typedef unsigned int u16;
typedef unsigned char u8;
typedef unsigned long u32;//以毫秒为单位的延时
void delay_ms(unsigned int ms){unsigned int i,j;for(i=ms;i>0;i--)for(j=123;j>0;j--);
}
//以10微秒为单位的延时
void delay_10us(u16 ten_us)
{while(ten_us--);
}void Uart1_Init(void); //串口1的初始化void main()
{Uart1_Init();while(1) //保持应用程序不退出{}
}void Uart1_Init(void)//配置串口为工作方式1,定时器1,工作方式为2,8位自重载
{//串口模块寄存器PCON |= 0x80; //使能波特率倍速位SMODSCON |= 0x50; //配置串口工作方式1,允许接收数据//定时器1相关寄存器TMOD &= 0x0F; //使用定时器1TMOD |= 0x20; //配置工作方式2,8位自重载TL1 = 0xFA; //设置定时计数器的低8位TH1 = 0xFA; //设置定时计数器的高8位TR1 = 1; //开启定时器1//中断相关寄存器ES = 1; //串行口中断允许位EA = 1; //CPU 中断允许(总允许)位
}void Uart1_Isp(void) interrupt 4
{u8 u8RecData = 0;if(RI) //检测串口接收完成中断{u8RecData = SBUF; //将串口模块缓存寄存器中的数据读到用户内存 SBUF = u8RecData; //将用户数据传输到串口缓存寄存器中,准备发送while(TI==0); //用户在等待串口发送单元发送完成RI = 0; //用户清除接收数据完成标志TI = 0; //用户清除发送数据完成标志}
}
模拟printf实验
//功能:实现printf的输出重定向#include "reg52.h"
#include "stdio.h"typedef unsigned int u16;
typedef unsigned char u8;
typedef unsigned long u32;//定义LED的引脚
sbit LED1 = P2^0;//以毫秒为单位的延时
void delay_ms(unsigned int ms){unsigned int i,j;for(i=ms;i>0;i--)for(j=123;j>0;j--);
}
//以10微秒为单位的延时
void delay_10us(u16 ten_us)
{while(ten_us--);
}void Uart1_Init(void); //串口1的初始化
void Uart1_SendData(u8 u8data); //串口1的发送数据void main()
{u16 i = 0;Uart1_Init();while(1) //保持应用程序不退出{i++;delay_ms(1000);printf("i = %03d,hello world!\r\n",i);}
}void Uart1_Init(void)//配置串口为工作方式1,定时器1,工作方式为2,8位自重载
{//串口模块寄存器PCON |= 0x80; //使能波特率倍速位SMODSCON |= 0x50; //配置串口工作方式1,允许接收数据//定时器1相关寄存器TMOD &= 0x0F; //使用定时器1TMOD |= 0x20; //配置工作方式2,8位自重载TL1 = 0xFA; //设置定时计数器的低8位TH1 = 0xFA; //设置定时计数器的高8位TR1 = 1; //开启定时器1//中断相关寄存器ES = 1; //串行口中断允许位EA = 1; //CPU 中断允许(总允许)位
}void Uart1_Isp(void) interrupt 4
{u8 u8RecData = 0;if(RI) //检测串口接收完成中断{u8RecData = SBUF; //将串口模块缓存寄存器中的数据读到用户内存 switch(u8RecData){case 0x10: LED1 = 1;break;case 0x11: LED1 = 0;break;default:break;}RI = 0; //用户清除接收数据完成标志}
}char putchar (char dat) //标准C的输出重定向
{Uart1_SendData(dat);return dat;
}void Uart1_SendData(u8 u8data)
{SBUF = u8data; //串口输出单元开始工作while(TI == 0) //等TI为高电平,输出完成{}TI = 0; //清除发送标志
}
串口接收数据不丢失实验
//功能:串口接收长字符(50以内)不丢失数据,通过printf发送给PC#include "reg52.h"
#include "stdio.h"typedef unsigned int u16;
typedef unsigned char u8;
typedef unsigned long u32;u8 u8Uart_Buffer[50]={0}; //串口缓存池
u8 u8Uart_Rx_STA = 0; //串口接收状态标志
//bit7 0:表示没有接收完成, 1反之
//bit6 0:表示没有接收到'\r', 1反之
//bit5--bit0 表示接收到的有效数据长度//以毫秒为单位的延时
void delay_ms(unsigned int ms){unsigned int i,j;for(i=ms;i>0;i--)for(j=123;j>0;j--);
}
//以10微秒为单位的延时
void delay_10us(u16 ten_us)
{while(ten_us--);
}void Uart1_Init(void); //串口1的初始化
void Uart1_SendData(u8 u8data); //串口1的发送数据
void Uart1_RecvData(void);void main()
{u8 len = 0;Uart1_Init();while(1) //保持应用程序不退出{if(u8Uart_Rx_STA & 0x80) //串口数据接收完成{len = u8Uart_Rx_STA & 0x3f;u8Uart_Buffer[len] = 0;printf("%s\r\n",u8Uart_Buffer);u8Uart_Rx_STA = 0; //清除状态标志}}
}void Uart1_Init(void)//配置串口为工作方式1,定时器1,工作方式为2,8位自重载
{//串口模块寄存器PCON |= 0x80; //使能波特率倍速位SMODSCON |= 0x50; //配置串口工作方式1,允许接收数据//定时器1相关寄存器TMOD &= 0x0F; //使用定时器1TMOD |= 0x20; //配置工作方式2,8位自重载TL1 = 0xFA; //设置定时计数器的低8位TH1 = 0xFA; //设置定时计数器的高8位TR1 = 1; //开启定时器1//中断相关寄存器ES = 1; //串行口中断允许位EA = 1; //CPU 中断允许(总允许)位
}void Uart1_Isp(void) interrupt 4
{u8 u8RecData = 0;if(RI) //检测串口接收完成中断{Uart1_RecvData();RI = 0; //用户清除接收数据完成标志}
}char putchar (char dat) //标准C的输出重定向
{Uart1_SendData(dat);return dat;
}void Uart1_SendData(u8 u8data)
{SBUF = u8data; //串口输出单元开始工作while(!TI); //等TI为高电平,输出完成TI = 0; //清除发送标志
}void Uart1_RecvData(void)
{u8 r = SBUF;if((u8Uart_Rx_STA & 0x80) == 0)//没有接收完成{if(u8Uart_Rx_STA & 0x40){if(r!='\n'){u8Uart_Rx_STA = 0; //将状态清0}else{u8Uart_Rx_STA |= 0x80; //标记数据接收完成}}else //还没有接收过'\r'{if(r == '\r'){u8Uart_Rx_STA |= 0x40; //标记数据接收到\r}else{if((u8Uart_Rx_STA & 0x3f)<48){u8Uart_Buffer[u8Uart_Rx_STA++] = r;}else{u8Uart_Rx_STA = 0;}}}}
}
相关文章:

串口工作方式
串口工作方式 方式0方式0输出方式0输入 方式1方式1输出方式1输入 方式2或方式3输出输入 串口使用方法如何计算波特率串口初始化步骤串口回传实验模拟printf实验串口接收数据不丢失实验 方式0 方式 0 时,串行口为同步移位寄存器的输入输出方式。主要用于扩展并行输 入…...
统计Nginx的客户端IP,可以通过分析Nginx的访问日志文件来实现
要统计Nginx的客户端IP,可以通过分析Nginx的访问日志文件来实现。以下是一些常见的方法和步骤: 一、通过命令行工具统计 查看Nginx访问日志: Nginx的访问日志通常默认存储在/var/log/nginx/access.log,但具体位置可能因安装和配置…...

Apache Airflow 快速入门教程
Apache Airflow已经成为Python生态系统中管道编排的事实上的库。与类似的解决方案相反,由于它的简单性和可扩展性,它已经获得了普及。在本文中,我将尝试概述它的主要概念,并让您清楚地了解何时以及如何使用它。 Airflow应用场景 …...

42 基于单片机的智能浇花系统
目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于51单片机,采样DHT11温湿度传感器检测温湿度,通过LCD1602显示 4*4按键矩阵可以设置温度湿度阈值,温度大于阈值则开启水泵,湿度大于阈值则开启风扇…...
乐橙云小程序插件接入HbuilderX
乐橙插件使用: 1.配置app.json文件,uniapp中在mainfest.json中配置 https://uniapp.dcloud.net.cn/collocation/manifest.html#mp-weixin ** 2、集成插件页面.json文件 ** uniapp在 pages.json 对应页面的 style -> usingComponents 引入组件&…...
VoCo-LLaMA: Towards Vision Compression with Large Language Models
视觉语言模型在各种多模态任务上取得了显著的成功,但经常受到有限上下文窗口和处理高分辨率图像输入和视频的高计算成本的瓶颈。视觉压缩可以通过减少视觉令牌数量避免该问题。先前方法使用额外模块压缩视觉令牌并强制LLM理解压缩的令牌。然而,LLM对视觉…...

Vue+vite 组件开发的环境准备
一.nodejs安装 进入Node.js 官网(Node.js — Run JavaScript Everywhere),点击下载。 双击打开,进行安装 双击打开后,点击 next(下一步),后面也是一直点击 next 无其他设置,直到 …...

基于社区发现的GraphRAG思路
GraphRAG出自2024年4月的论文《From Local to Global: A Graph RAG Approach to Query-Focused Summarization》,其代码也在2024年年中开源 。它在用图结构来完成RAG时,使用社区这个概念并基于社区摘要来回答一些概括性的问题。 Graph RAG流程如论文图1所…...
react学习记录
一、目录结构react优秀代码之react目录结构简洁之道React 作为一个库,不会决定你如何组织项目的结构。这是件好事,因为这样 - 掘金【React】项目的目录结构全面指南_react项目结构-CSDN博客 1、创建项目:开发文档 Getting Started | Create…...

Day2——需求分析与设计
教师端签到应用软件的需求分析; 产品经理如何写好产品需求文档(附模板) 需求分析是软件开发过程中的关键步骤,它确保了开发的软件能够满足用户的需求。以下是进行需求分析的具体步骤: 1. 确定分析目标 明确教师端签到…...

VScode离线下载扩展安装
在使用VScode下在扩展插件时,返现VScode搜索不到插件,网上搜了好多方法,都不是常规操作,解决起来十分麻烦,可以利用离线下载安装的方式安装插件!亲测有效!!! 1.找到VScod…...

【机器学习】机器学习的基本分类-监督学习-决策树(Decision Tree)
决策树是一种树形结构的机器学习模型,适用于分类和回归任务。它通过一系列基于特征的条件判断来将数据分割为多个子区域,从而预测目标变量的值。 1. 决策树的结构 根节点(Root Node) 决策树的起点,包含所有样本。根据某…...

【第 1 章 初识 C 语言】1.8 使用 C 语言的 7 个步骤
目录 1.8 使用 C 语言的 7 个步骤 1.8.1 第 1 步:定义程序的目标 1.8.2 第 2 步:设计程序 1.8.3 第 3 步:编写代码 1.8.4 第 4 步:编译 1.8.5 第 5 步:运行程序 1.8.6 第 6 步:测试和调试程序 1.8.…...
Docker 使用 Dockerfile 文件打包部署前端项目
编写 Dockerfile 文件: FROM nginx:latest ADD dist /etc/nginx/html/dist COPY nginx.conf /etc/nginx/nginx.conf ENV PATH /usr/sbin:$PATH EXPOSE 80 ENTRYPOINT ["nginx"] CMD ["-g","daemon off;"]编写 nginx.conf 文件&#…...
HTML-全
. CSS css后缀名的文件被html引用 在HTML中,CSS(层叠样式表,Cascading Style Sheets)是一种用于设置网页上的文本内容、图片布局和版面设计等外观样式的样式表语言。简单来说,CSS定义了HTML元素如何显示在浏览器中。…...

高效流程图绘制:开发设计流程图利器
在选择画流程图的工具时,不同的项目和使用场景会决定最佳的工具。以下是几款常见的流程图工具,并结合具体项目使用场景提供建议: 1. Lucidchart 特点: 在线协作:支持多人实时协作,适合团队合作。模板丰富&…...
数据仓库的概念
先用大白话讲一下,数据仓库的主要目的就是存储和分析大量结构化数据的。 > 那么它的核心目的是:支持商业智能(BI)和决策支持系统,也就是说,它不仅仅是为了存储,更重要的是为了分析提供便利。…...

AI - 谈谈RAG中的查询分析(2)
AI - 谈谈RAG中的查询分析(2) 大家好,RAG中的查询分析是比较有趣的一个点,内容丰富,并不是一句话能聊的清楚的。今天接着上一篇,继续探讨RAG中的查询分析,并在功能层面和代码层面持续改进。 功…...

Java基础面试题,46道Java基础八股文(4.8万字,30+手绘图)
Java是一种广泛使用的编程语言,由Sun Microsystems(现为Oracle Corporation的一部分)在1995年首次发布。它是一种面向对象的语言,这意味着它支持通过类和对象的概念来构造程序。 Java设计有一个核心理念:“编写一次&am…...
taro小程序马甲包插件
插件名 maloulab/taro-plugins-socksuppet-ci maloulab/taro-plugins-socksuppet-ci安装 yarn add maloulab/taro-plugins-socksuppet-ci or npm i maloulab/taro-plugins-socksuppet-ci插件描述 taro官方是提供了小程序集成插件的tarojs/plugin-mini-ci ,且支持…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法
树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作,无需更改相机配置。但是,一…...

K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...

CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...
服务器--宝塔命令
一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...
uniapp 字符包含的相关方法
在uniapp中,如果你想检查一个字符串是否包含另一个子字符串,你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的,但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...

代码规范和架构【立芯理论一】(2025.06.08)
1、代码规范的目标 代码简洁精炼、美观,可持续性好高效率高复用,可移植性好高内聚,低耦合没有冗余规范性,代码有规可循,可以看出自己当时的思考过程特殊排版,特殊语法,特殊指令,必须…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能
1. 开发环境准备 安装DevEco Studio 3.1: 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK 项目配置: // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...

破解路内监管盲区:免布线低位视频桩重塑停车管理新标准
城市路内停车管理常因行道树遮挡、高位设备盲区等问题,导致车牌识别率低、逃费率高,传统模式在复杂路段束手无策。免布线低位视频桩凭借超低视角部署与智能算法,正成为破局关键。该设备安装于车位侧方0.5-0.7米高度,直接规避树枝遮…...