07:串口通信二
串口编程
- 1、与波特率之相关的寄存器
- 2、PCON寄存器
- 3、SCON寄存器
- 4、配置的代码分析
- 5、向PC发送一段字符串
- 6、PC机向单片机发送字符控制LED1灯的亮灭
1、与波特率之相关的寄存器
如图,与串口通信相关的寄存器主要是SCON和PCON寄存器。
2、PCON寄存器
SMOD:为1时,通信方式1,2,3波特率加倍,为0时不加倍。
SMOD0:帧错误检测位,为1时,SCON寄存器中的SM0用于帧错误检测。为0时,用于指定的串口工作方式
3、SCON寄存器
SM0:当PCON的SMOD0为1时,这个位用于帧错误检测。当SMOD0为0时,则用于通信方式的选择
SM0,SM1:
0 0 工作方式0
0 1 工作方式1 8位异步位数据传输(波特率可配)
1 0 工作方式2 9位(波特率不可配)
1 1 工作方式3 9位(波特率可配)
SM2:允许方式2,3多机控制
REN:运行接收控制位,为1,允许接收;为0,禁止接收。
TB8/RB8先不管它
T1:发送中断请求
R1:接收中断请求
- 工作方式0的波特率 = 系统晶振/12 = 11.0592MHz/12=11059200/12
- 工作方式1的波特率 = (2^SMOD/32)*定时器1的溢出率
- 工作方式2的波特率 = (2^SMOD/64)*11.0592MHz
- 工作方式3的波特率 = (2^SMOD/32)*定时器1的溢出率
定时器1的溢出率:
- 工作在12T时:溢出率 = 11.0592MHz / 12 / (256 - TH1)
- 工作在6T时:溢出率 = 11.0592MHz / 6 / (256 - TH1)
4、配置的代码分析
void UartInit(void) //9600bps@11.0592MHz
{PCON &= 0x7F; //波特率不倍速SCON = 0x50; //8位数据,可变波特率AUXR &= 0xBF; //定时器1时钟为Fosc/12,即12TAUXR &= 0xFE; //串口1选择定时器1为波特率发生器TMOD &= 0x0F; //清除定时器1模式位TMOD |= 0x20; //设定定时器1为8位自动重装方式TL1 = 0xFD; //设定定时初值TH1 = 0xFD; //设定定时器重装值ET1 = 0; //禁止定时器1中断TR1 = 1; //启动定时器1
}
PCON &= 0X7F;代表PCON变为0xxx xxxx,则最高位变为0,其他位不变。因为PCON的初始值为00x1 0000,所以PCON = 00x1 0000,代表波特率不加倍
SCON = 0x50; 代表0101 0000。8位数据传输(波特率可变),可以读取数据
AUXR = 0X01; 代表降低时钟对外界的辐射
TMOD &= 0X0F;
TMOD |= 0X20; 代表TMOD = 0010 0000,选用定时器1,且为8位自动重装,低8位溢出时,自动将高8位的值给低8位
TL1 = 0XFD;
TH1 = 0XFD; 代表1111 1101,波特率 = (2^0/32)*(11059200/12/(256 - 253)) = 9600,则波特率为9600
TR1 = 1;打开定时器1。
5、向PC发送一段字符串
代码①:
#include <REGX52.H>
#include "intrins.h"sfr AUXR = 0X8E;void Delay1000ms() //@11.0592MHz
{unsigned char i, j, k;_nop_();i = 8;j = 1;k = 243;do{do{while (--k);} while (--j);} while (--i);
}void UartInit(void) //波特率9600
{PCON &= 0x7F; //波特率不倍速SCON = 0x40; //8位数据,可变波特率AUXR = 0x01; TMOD &= 0x0F; //清除定时器1模式位TMOD |= 0x20; //设定定时器1为8位自动重装方式TL1 = 0xFD; //设定定时初值TH1 = 0xFD; //设定定时器重装值TR1 = 1; //启动定时器1
}void sendByte(char data_sj)
{SBUF = data_sj;/*单片机向SBUF里面开始写入数据,注意是开始,要经过一段时间才能写入完毕*/
}void sendString(char *str)
{while(*str != '\0'){sendByte(*str);str++;}
}void main()
{UartInit();while(1){sendString("wohaoshuai");Delay1000ms();}
}
出现的现象:
wwwoohhwwo
- 为什么是乱的喃?
因为啊,单片机向SBUF写入数据需要移位寄存器进行操作,而移位寄存器操作也是需要时间的,假设需要10us。当第一个数据写入并发送出去后,要等一段时间第二个数据才能写入成功,而这段时间SBUF里面只有一个w,而发送数据不需要时间,所以他会不断的把SBUF里面的w进行向外发送。
其实可以这样理解,如上图:SBUF = data_sj;开始向SBUF里面写入数据,而在这段代码后面,有一行代码代表着将SBUF里面的数据输出给上位机只是系统将这行代码隐藏起来了。不然程序员自己编写类似:SBUF = data-sj;开始向SBUF里面写入数据internal = SBUF 将SBUF里面的数据输出给上位机 (被隐藏)
- 解决方法1:
只需要在写入SBUF后面添加一个延迟函数,等待向SBUF成功写入数据后,然后才执行数据输出的代码。
代码①:
void sendByte(char data_sj)
{SBUF = data_sj;//开始向SBUF里面写入数据Delay10ms();//等待10ms,让数据成功写入SBUF里面internal = SBUF;//这行代码被隐藏了,不可编辑的
}
- 解决方法2:
通过中断请求标志位
如图,当使用工作方式1(8位数据传输),当8位数据通过移位寄存器成功写入结束时,TI变为1。例如第二个o用8位二进制数据表示,当第8位通过移位寄存器成功写入时,也代表着字符o成功的被写入SBUF里面,此时TI自动变为1,但是变为1后需要手动置0 ,以便下次数据的写入成功标志
代码②:
void sendByte(char data_sj)
{SBUF = data_sj;while(!TI);/*还没有写入完毕时,TI=0,则一直困在这个循环里面,当写入完毕时,TI=1,退出循环,进入下一行程序*/TI = 0;
}
还没有写入完毕时,TI=0,则一直困在这个循环里面,当写入完毕时,TI=1,退出循环,进入下一行程序
6、PC机向单片机发送字符控制LED1灯的亮灭
#include <REGX52.H>
#include "intrins.h"sfr AUXR = 0X8E;
sbit LED1 = P3^7;void Delay300ms() //@11.0592MHz
{unsigned char i, j, k;_nop_();i = 3;j = 26;k = 223;do{do{while (--k);} while (--j);} while (--i);
}void UartInit(void) //波特率9600
{PCON &= 0x7F; //波特率不倍速SCON = 0x40; //8位数据,可变波特率REN = 1; //运行单片机读取数据AUXR = 0x01; TMOD &= 0x0F; //清除定时器1模式位TMOD |= 0x20; //设定定时器1为8位自动重装方式TL1 = 0xFD; //设定定时初值TH1 = 0xFD; //设定定时器重装值TR1 = 1; //启动定时器1
}void main()
{char mark;//第一一个mark存储字符LED1 = 1;UartInit();while(1){Delay300ms();if(RI == 1) //表示上位机给单片机的SBUF已经写入数据完成了,RI会自动变为1,而需要手动置0,以便下次写入完成进行标志。{RI = 0;//手动置0mark = SBUF; //将SBUF里面的数存放在变量mark中if(mark == 'o')//如果读取的字符是O{LED1 = 0; //开灯}if(mark == 'c'){LED1 = 1;}}}
}
其实可以这样理解:
mark = SBUF;代表着将SBUF里面的数据交给mark这个变量。而在行代码之前,同样有一行代码代表着上位机将数据写入SBUF。只是这行代码被隐藏,不可编辑类似:SBUF = internal; 上位机将数据写入SBUF(被隐藏)mark = SBUF; SBUF将数据存在变量mark中
同理,RI代表着数据是否被成功写入SBUF里面,上位机成功将数据写入SBUF里面。则RI会自动变为1,同样的需要手动置0,以便下次数据的写入标志。
相关文章:

07:串口通信二
串口编程 1、与波特率之相关的寄存器2、PCON寄存器3、SCON寄存器4、配置的代码分析5、向PC发送一段字符串6、PC机向单片机发送字符控制LED1灯的亮灭 1、与波特率之相关的寄存器 如图,与串口通信相关的寄存器主要是SCON和PCON寄存器。 2、PCON寄存器 SMOD࿱…...
识别视频中的人数并统计出来
目的: 使用Python和pysimpleguil以及opencv写一个统计人流量的软件。要求:1 加载选定的视频 2 通过形态学特征识别人,3统计人数并且在界面上显示出来,4 保存识别出人数的信息。 步骤 1: 安装必要的库 首先,确保你已经安装了Python。然后,安装PySimpleGUI和OpenCV。你可…...
【TypeDB 】机器学习和符号 AI 在机器人技术中的作用
机器学习和符号 AI 在机器人技术中的作用 煤油灯科技2022-06-29 14:23前言 机器人学是计算机科学中的一个多学科领域,致力于机器人的设计和制造,机器人在制造、太空探索和国防等行业都有应用。虽然该领域已经存在了 50 多年,但随着科幻小说成为现实,波士顿动力公司的Spot和…...

EPLAN 去掉PDF中的红色跳转标识
EPLAN PDF图纸导出后体验跳转标识会有红色标识,如何去掉呢?下面介绍一下方法: 此为现象: EPLAN 2.9的帮助文档里提示: 在导出的 PDF 文档中,跳转后的跳转目标现在通过红色的闪烁框进行标识。可能的跳转目…...

【car】深入浅出学习机械燃油车知识、结构、原理、维修、保养、改装、编程
汽车的五大总成通常是指发动机、变速器、前后桥、车架和悬挂系统。 发动机:是汽车的动力来源,负责将燃料的化学能转化为机械能,驱动汽车行驶。常见的发动机类型有内燃机(如汽油发动机、柴油发动机)和电动机࿰…...

语音识别概述
语音识别概述 一.什么是语音? 语音是语言的声学表现形式,是人类自然的交流工具。 图片来源:https://www.shenlanxueyuan.com/course/381 二.语音识别的定义 语音识别(Automatic Speech Recognition, ASR 或 Speech to Text, ST…...

勒索防御第一关 亚信安全AE防毒墙全面升级 勒索检出率提升150%
亚信安全信舷AE高性能防毒墙完成能力升级,全面完善勒索边界“全生命周期”防御体系,筑造边界勒索防御第一关! 勒索之殇,银狐当先 当前勒索病毒卷携着AI技术,融合“数字化”的运营模式,形成了肆虐全球的网…...

elementui 日历组件el-calendar使用总结
功能: 1.日历可以周视图、月视图切换; 2.点击月视图中日期可以切换到对应周视图; 3.点击周视图查看当日对应数据; 4.周、月视图状态下,点击前后按钮,分别切换对应上下的周、月; 5.点击回到…...
RK3568 安卓12 EC20模块NOCONN没有ip的问题(已解决)
从网上东拼西凑找了不少教程,但是里面没有提到rillib.so需要替换,替换掉就可以上网了,系统也有4G图标了。 注意,这个rillib.so是移远提供的。把他们提供的文件放到rk3568_android_sdk/vendor/rockchip/common/phone/lib下&#x…...

【NLP自然语言处理】基于BERT实现文本情感分类
Bert概述 BERT(Bidirectional Encoder Representations from Transformers)是一种深度学习模型,用于自然语言处理(NLP)任务。BERT的核心是由一种强大的神经网络架构——Transformer驱动的。这种架构包含了一种称为自注…...

CSS选择器(1)
以内部样式表编写CSS选择器,其主要编写在<head></head>元素里,通过<style></style>标签来定义内部样式表。 基本语法为: 选择器{ 声明块 } 声明块:是由一对大括号括起来,声明块中是一个一个的…...

Claude 3.5 Sonnet模型发布,对比ChatGPT4o孰强孰弱
Anthropic 这家生而为打击 OpenAI 安全问题的公司,正式发布了Claude 3.5 Sonnet模型! 用官网的话就是: 今天,我们推出了 Claude 3.5 Sonnet,这是我们即将推出的 Claude 3.5 型号系列中的第一个版本。Claude 3.5 Sonne…...
MySQL 分库分表
分表 分表 将表按照某种规则拆分成多个表。 分表的使用原因 当数据量超大的时候,B-Tree索引效果很变差。 垂直分区 切分原则:把不常用或存储内容比较多的字段分到新的表中可使表存储更多数据。 原因,Innodb主索引叶子节点存储着当前行的所有信…...

AutoMQ 社区双周精选第十二期(2024.06.29~2024.07.12)
本期概要 欢迎来到 AutoMQ 第十一期双周精选!在过去两周里,主干动态方面,AutoMQ 跟进了 Apache Kafka 3.4.x BUG 修复,并进行了CPU & GC 性能优化,另外,AutoBalancing 的 Reporter 和 Retriever 也将支…...
Web开发:<div>标签作用
div作用 介绍基本用法特点和用途样式化示例嵌套示例与其他标签的对比总结 介绍 在Web开发中,<div> 标签是一个通用的容器元素,用于将HTML文档中的内容分组。它是一个块级元素,通常用于布局目的,因为它可以包含其他块级元素…...
如何使用unittest框架来编写和运行单元测试
Python 的 unittest 框架是用于编写和运行可重复的测试的一个强大工具。它允许你定义测试用例、测试套件、测试运行器和测试固件(fixtures),从而系统化地测试你的代码。以下是如何使用 unittest 框架来编写和运行单元测试的基本步骤ÿ…...
2024最新超详细SpringMvc常用注解总结
SpringMVC常用注解 控制器(Controller)相关注解: 1.Controller Controller 注解用于标识一个类为 Spring MVC 的控制器,它能够处理用户的请求并返回相应的视图或数据。通常与 RequestMapping 注解一起使用,以定义请求…...
Linux硬件中断(IRQ)的基础知识
目录 一、中断的概念1.1 什么是硬件中断1.2 中断类型二、中断处理的工作原理2.1 中断请求2.2 中断向量2.3 中断服务例程(ISR)2.4 上下文切换2.5 中断处理2.6 任务恢复三、中断处理的编程3.1 注册中断处理函数3.2 注销中断处理函数四、中断和系统性能4.1 中断风暴4.2 IRQ亲和性…...
DP讨论——适配器模式
学而时习之,温故而知新。 敌人出招(使用场景) 说是自己的程序对接第三方的库,但是自己的代码的接口设计完毕了,如何对接上? 你出招 适配器模式就是为此而生的——我觉得应该是该解决方法被命名为了适配…...

window下tqdm进度条
原代码是linux下运行,修改后可在window下运行。 #ifndef TQDM_H #define TQDM_H#include <chrono> #include <ctime> #include <numeric> #include <ios> #include <string> #include <cstdlib> #include <iostream> #i…...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...
Java + Spring Boot + Mybatis 实现批量插入
在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法:使用 MyBatis 的 <foreach> 标签和批处理模式(ExecutorType.BATCH)。 方法一:使用 XML 的 <foreach> 标签ÿ…...

Golang——6、指针和结构体
指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...

在 Spring Boot 中使用 JSP
jsp? 好多年没用了。重新整一下 还费了点时间,记录一下。 项目结构: pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...
十九、【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建
【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建 前言准备工作第一部分:回顾 Django 内置的 `User` 模型第二部分:设计并创建 `Role` 和 `UserProfile` 模型第三部分:创建 Serializers第四部分:创建 ViewSets第五部分:注册 API 路由第六部分:后端初步测…...