STC89C52单片机学习——第20节: [8-2]串口向电脑发送数据电脑通过串口控制LED

写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难,但我还是想去做!

本文写于:2025.03.15

51单片机学习——第20节: [8-2]串口向电脑发送数据&电脑通过串口控制LED

  • 前言
  • 开发板说明
  • 引用
  • 解答和科普
  • 一、串口通信
  • 二、串口向电脑发送数据
  • 三、电脑通过串口控制LED(*接收和发送)
  • 问题
  • 总结

前言

   本次笔记是用来记录我的学习过程,同时把我需要的困难和思考记下来,有助于我的学习,同时也作为一种习惯,可以督促我学习,是一个激励自己的过程,让我们开始51单片机的学习之路。
   欢迎大家给我提意见,能给我的嵌入式之旅提供方向和路线,现在作为小白,我就先学习51单片机了,就跟着B站上的江协科技开始学习了.
   在这里会记录下江协科技51单片机开发板的配套视频教程所作的实验和学习笔记内容,因为我之前有一个开发板,我大概率会用我的板子模仿着来做.让我们一起加油!
   另外为了增强我的学习效果:每次笔记把我不知道或者问题在后面提出来,再下一篇开头作为解答!

开发板说明

   本人采用的是慧净的开发板,因为这个板子是我N年前就买的板子,索性就拿来用了。不再另外购买视频中的普中开发板了。
   原理图如下
在这里插入图片描述
视频中的都用这个开发板来实现,如果有资源就利用起来。
仔细看了看:开发板的晶振为:11.0592Mhz;12Mhz晶振是用来给CH340G芯片外置晶振;

下图是实物图
在这里插入图片描述

引用

51单片机入门教程-2020版 程序全程纯手打 从零开始入门
还参考了下图中的书籍:
手把手教你学51单片机(C语言版)
在这里插入图片描述
STC89C52手册
在这里插入图片描述

解答和科普

一、串口通信

IO 口模拟串口通信,让大家了解了串口通信的本质,但是我们的单片机程序却需要不停的检测扫描单片机IO 口收到的数据,大量占用了单片机的运行时间。在单片机内部做一个硬件模块,让它自动接收数据,接收完了,通知我们一下就可以了。
51 单片机的UART 串口的结构由串行口控制寄存器SCON、发送和接收电路三部分构成。STC89C52系列单片机内部集成有一个功能很强的全双工串行通信口,与传统8051单片机的串口完全兼容。设有2个互相独立的接收、发送缓冲器,可以同时发送和接收数据。发送缓冲器只能写入而不能读出,接收缓冲器只能读出而不能入,因而两个缓冲器可以共用一个地址码(99H)。两个缓冲器统称串行通信特殊功能寄存器SBUF。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

模式1 是最常用的,就是我们前边提到的1 位起始位,8 位数据位和1 位停止位。STC89C52 单片机来讲,这个波特率发生器只能由定时器T1 或定时器T2 产生,而不能由定时器T0 产生,这和我们模拟的通信是完全不同的概念。如果用定时器2,需要配置额外的寄存器,默认是使用定时器1 的。 就使用定时器T1 作为波特率发生器来讲解,方式1 下的波特率发生器必须使用定时器T1 的模式2,也就是自动重装载模式,
定时器的重载值计算公式为:TH1 = TL1 = 256 - 晶振值/12 /2/16 /波特率
和波特率有关的还有一个寄存器,是一个电源管理寄存器PCON,他的最高位可以把波特率提高一倍,也就是如果写PCON |= 0x80 以后,计算公式就成了:TH1 = TL1 = 256 - 晶振值/12 /16 /波特率
公式中数字的含义这里解释一下,256 是8 位定时器的溢出值,也就是TL1 的溢出值,晶振值在我们的开发板上就是11059200,12 是说1 个机器周期等于12 个时钟周期,值得关注的是这个16,我们来重点说明。在IO 口模拟串口通信接收数据的时候,采集的是这一位数据的中间位置,而实际上串口模块比我们模拟的要复杂和精确一些。他采取的方式是把一位信号采集16 次,其中第7、8、9 次取出来, 这三次中其中两次如果是高电平,那么就认定这一位数据是1,如果两次是低电平,那么就认定这一位是0,这样一旦受到意外干扰读错一次数据,也依然可以保证最终数据的正确性。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
UART 串口程序
一般情况下,我们编写串口通信程序的基本步骤如下所示:
1、配置串口为模式1。
2、配置定时器T1 为模式2,即自动重装模式。
3、根据波特率计算TH1 和TL1 的初值,如果有需要可以使用PCON 进行波特率加倍。
4、打开定时器控制寄存器TR1,让定时器跑起来。
这里还要特别注意一下,就是在使用T1 做波特率发生器的时候,千万不要再使能T1 的中断了。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
TL1 = 0xF3; //设定定时初值 256-243=13 13us溢出一次 1/13us =0.07692MhzTH1 = 0xF3; //设定定时器重装值 256-243=13 SMOD=1 0.07692/16=0.00480769MHZ 10001000=4807.69HZ 7.69/4800=0.001602的误差。
在这里插入图片描述
在这里插入图片描述

二、串口向电脑发送数据

配置UART串口:
1、配置串口为模式1。
在这里插入图片描述

SCON=0x40;						//工作模式选择1

在这里插入图片描述
只改变PCON寄存器的最高位,使SMOD为1.给1的时候是不处于2的。所以我们要给1.也就是12个周期的。

PCON &= 0x7F;		//波特率不倍速				

2、配置定时器T1 为模式2,即自动重装模式。
在这里插入图片描述
在这里插入图片描述
只操作T1,左边的M1和M0配置。定时器1应该配置为0010.

TMOD &= 0x0F;		//设置定时器模式清零
TMOD |= 0x20;		//设置定时器模式置1

3、根据波特率计算TH1 和TL1 的初值,如果有需要可以使用PCON 进行波特率加倍。

TL1 = 0xFD;		//设定定时初值
TH1 = 0xFD;		//设定定时器重装值

4、打开定时器控制寄存器TR1,让定时器跑起来。
这里还要特别注意一下,就是在使用T1 做波特率发生器的时候,千万不要再使能T1 的中断了。

ET1 = 0;		//禁止定时器1中断
TR1 = 1;		//启动定时器1

在这里插入图片描述
在这里插入图片描述

只发给电脑不接受的代码

#include <REGX52.H>/*** @brief    串口初始化 9600bps@11.0592MHz* @param  	无* @retval 	无*/
void UART_Init(void)		//9600bps@11.0592MHz
{PCON &= 0x7F;		//波特率不倍速SCON = 0x40;		//8位数据,可变波特率TMOD &= 0x0F;		//清除定时器1模式位TMOD |= 0x20;		//设定定时器1为8位自动重装方式TL1 = 0xFD;		//设定定时初值TH1 = 0xFD;		//设定定时器重装值ET1 = 0;		//禁止定时器1中断TR1 = 1;		//启动定时器1
}void UART_SendByte(unsigned char Byte)
{SBUF=Byte;while(TI==0);TI=0;

main.c

#include <REGX52.H>
#include <INTRINS.H>
#include "Delay.h"
#include "UART.h"unsigned char sec;void main()
{UART_Init();while(1){UART_SendByte(sec);sec++;Delay(1000);}
}

实验现象:

在这里插入图片描述

三、电脑通过串口控制LED(*接收和发送)

单片机接收的时候是不知道什么时候电脑会发送,所以用中断来触发。

在这里插入图片描述

SCON = 0x50;		//8位数据,可变波特率允许接收REN

在这里插入图片描述
使能中断

EA=1;
ES=1;			//接收和发送都会触发中断

在这里插入图片描述
前面的名称可以自己写
在这里插入图片描述
在这里插入图片描述
验证是否进入中断:

void UART_Routine()   interrupt 4
{P1=0x00;
}	
void UART_Routine()   interrupt 4		//发送和接受进入这同一个中断
{if(RI==1)				//区分开是发送还是接收{P1=SBUF;	//读取SBUF的值放在P1直接处理了RI=0;			//必须软件清零,硬件置1}
}	

实验现象:

电脑通过串口发送数据控制P1口接收SBUF

#include <REGX52.H>
#include <INTRINS.H>
#include "Delay.h"
#include "UART.h"unsigned char sec;void main()
{UART_Init();while(1){}
}void UART_Routine()   interrupt 4		//发送和接受进入这同一个中断
{if(RI==1)				//区分开是发送还是接收{P1=SBUF;	//读取SBUF的值放在P1直接处理了UART_SendByte(SBUF);RI=0;			//必须软件清零,硬件置1}
}	

实验现象:
在这里插入图片描述

发送控制单片机LED并给电脑显示

在这里插入图片描述

UART_SendByte(0x30);

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

问题

1、就是波特率加不加速
2、就是控制位有点多,脑子有点乱了
3、注意配置是否正确
4、另外涉及到通讯之后和我的拓展坞会卡顿我的鼠标

总结

本节课主要学了了LED闪烁,通过延迟函数的延迟,实现了LED闪烁。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/34881.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java简单基础学习

目录 简单5位验证码快捷键的使用 评委打分5个评委 去掉一个最高分和一个最低分 取平均分 抢红包出现数组越界java​编辑 双色球系统--之蒟蒻学习 简单5位验证码快捷键的使用 题目意思做个验证码 //生成一个5位数的验证码 //前四位是字母,大小字母都可以 //最后一位要是数字…

前端学习记录:解决路由缓存问题

问题描述&#xff1a;响应路由参数的变化&#xff0c;使用带有参数的路由时需要注意的是&#xff0c;当用户从 /users/johnoy 导航到 /users/jolyne 时&#xff0c;相同的组件实例将会被重复使用。因为两个路由都渲染同个组件&#xff0c;比起销毁再创建&#xff0c;复用则显得…

Leetcode-1278.Palindrome Partitioning III [C++][Java]

目录 一、题目描述 二、解题思路 【C】 【Java】 Leetcode-1278.Palindrome Partitioning IIIhttps://leetcode.com/problems/palindrome-partitioning-iii/description/1278. 分割回文串 III - 力扣&#xff08;LeetCode&#xff09;1278. 分割回文串 III - 给你一个由小写…

deepseek GRPO算法保姆级讲解(数学原理+源码解析+案例实战)

文章目录 什么是GRPO群组形成(Group Formation):让大模型创建多种解决方案偏好学习(Preference Learning)&#xff1a;让大模型理解何为好的解答组内相对优势 优化(optimization): 让大模型从经验中学习(learning from experience)目标函数 GRPO算法的伪码表示GRPO算法的局限与…

【Linux我做主】基础命令完全指南上篇

Linux基础命令完全指南【上篇】 Linux基础命令完全指南github地址前言命令行操作的引入Linux文件系统树形结构的根文件系统绝对路径和相对路径适用场景Linux目录下的隐藏文件 基本指令目录和文件相关1. ls2. cd和pwdcdpwd 3. touch4. mkdir5. cp6. mv移动目录时覆盖写入的两种特…

自然语言秒转SQL—— 免费体验 OB Cloud Text2SQL 数据查询

在数据驱动决策的今天&#xff0c;企业急需从庞大业务数据中提炼信息&#xff0c;获取深度洞察。然而&#xff0c;面对海量数据&#xff0c;业务人员往往因缺乏SQL专业技能而难以快速查询和分析所需信息&#xff0c;频繁求助于BI部门不仅抬高了企业的沟通与时间成本&#xff0c…

鸿蒙next 多行文字加图片后缀实现方案

需求 实现类似iOS的YYLabel之类的在文字后面加上图片作为后缀的样式&#xff0c;多行时文字使用…省略超出部分&#xff0c;但必须保证图片的展现。 系统方案 在当前鸿蒙next系统提供的文字排版方法基本没有合适使用的接口&#xff0c;包括imagespan和RichEditor,根据AI的回…

C语言基础知识04---指针

目录 1、指针 1.1 指针概念 1.2 指针的大小 1.3 指针的定义 1.4 多级指针 1.5 指针的初始化 1.6 指针的使用 1.7 类型转换 1.8 大小端 1.9 地址偏移 1.10 指针常量&&常量指针 1.11 指针数组&&数组指针 1、指针 1.1 指针概念 指针保存地址&#xff…

spring boot 发送邮件验证码

一、前置需求 1、准备邮箱 2、登录授权码 qq邮箱在–>设置–>账号POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务 开启服务 二、发送邮件 1、简单邮件 包含邮件标题、邮件正文 2、引入mail启动器 <dependency><groupId>org.springframework.boot</groupI…

Spring Cloud Config - 动态配置管理与高可用治理

引言&#xff1a;为什么需要配置中心&#xff1f; 在微服务架构中&#xff0c;配置管理面临分散化、多环境、动态更新三大挑战。传统基于application.yml等配置文件的硬编码方式&#xff0c;导致以下问题&#xff1a; • 环境差异&#xff1a;开发、测试、生产环境配置混杂&a…

[网络][tcp协议]:tcp报头

tcp(传输控制协议)是一种面向字节流的传输层协议,相较于udp协议,tcp能保证传输数据的可靠性与准确性,tcp也是目前最常见的传输层协议 本文主要介绍tcp报头各个字段的含义与用途 注:保留6位和6位标记位是目前最普遍的写法,在我查资料时,发现有一些拓展情况,会在后文细说 最简单的…

【sklearn 01】人工智能概述

一、人工智能&#xff0c;机器学习&#xff0c;深度学习 人工智能指由人类制造出的具有智能的机器。这是一个非常大的范围&#xff0c;长远目标是让机器实现人工智能&#xff0c;但目前我们仍处在非常初始的阶段&#xff0c;甚至不能称为智能 机器学习是指通过数据训练出能完成…

Excel ScriptLab学习笔记

注意 The Excel JavaScript API 没有“Cell”对象或类。 相反&#xff0c;Excel JavaScript API 将所有 Excel 单元格定义为 Range 对象。 Excel UI 中的单个单元格转换为 Excel JavaScript API 中包含一个单元格的 Range 对象。 单个 Range 对象也可以包含多个连续的单元格。…

【数据结构】线性表简介

0.本篇问题 线性表&#xff0c;顺序表&#xff0c;链表什么关系&#xff1f;它们是逻辑结构还是存储结构&#xff1f;线性表的基本操作有哪些&#xff1f; 线性表是具有相同数据元素的有限序列。 表中元素有先后次序&#xff0c;每个元素占有相同大小的存储空间。 一、线性…

设计模式(行为型)-备忘录模式

目录 定义 类图 角色 角色详解 &#xff08;一&#xff09;发起人角色&#xff08;Originator&#xff09;​ &#xff08;二&#xff09;备忘录角色&#xff08;Memento&#xff09;​ &#xff08;三&#xff09;备忘录管理员角色&#xff08;Caretaker&#xff09;​…

Navicat如何查看密码

近期遇到需要将大部分已存储的navicat数据库转发给其他人&#xff0c;于是乎进行导出文件 奈何对方不用navicat&#xff0c;无法进行文件的导入从而导入链接 搜罗navicat的密码查看&#xff0c;大部分都为php代码解析 以下转载GitHub上看到的一个python代码解析的脚本 这里是对…

Matlab 四分之一车体车辆半主动悬架鲁棒控制

1、内容简介 略 Matlab 173-四分之一车体车辆半主动悬架鲁棒控制 可以交流、咨询、答疑 2、内容说明 略 3、仿真分析 略 4、参考论文 略

Python学习第十九天

Django-分页 后端分页 Django提供了Paginator类来实现后端分页。Paginator类可以将一个查询集&#xff08;QuerySet&#xff09;分成多个页面&#xff0c;每个页面包含指定数量的对象。 from django.shortcuts import render, redirect, get_object_or_404 from .models impo…

【大模型】Transformer、GPT1、GPT2、GPT3、BERT 的论文解析

前言 在自然语言处理&#xff08;NLP&#xff09;和深度学习的快速发展中&#xff0c;Transformer模型和 GPT系列模型扮演了至关重要的角色。本篇博客旨在对这些开创性的论文进行介绍&#xff0c;涵盖它们的提出时间、网络结构等关键信息&#xff0c;能够快速的理解这些模型的设…

【DeepSeek应用】本地部署deepseek模型后,如何在vscode中调用该模型进行代码撰写,检视和优化?

若已成功在本地部署了 DeepSeek 模型(例如通过 vscode-llm、ollama 或私有 API 服务),在 VS Code 中调用本地模型进行代码撰写、检视和优化的完整流程如下: 1. 准备工作:确认本地模型服务状态 模型服务类型: 若使用 HTTP API 服务(如 FastAPI/Flask 封装),假设服务地址…