单片机学习笔记---串口向电脑发送数据电脑通过串口控制LED

目录

串口向电脑发送数据

每隔一秒串口就发送一个递增的数给电脑

电脑通过串口控制LED

波特率的具体计算

HEX模式和文本模式


前两节是本节的理论基础,这节开始代码演示!

串口向电脑发送数据

接下来先开始演示一下串口单向发送一个数字给电脑:

写好框架后把前几节写好的Delay程序添加进来,后面会用到

接下来就是怎么配置串口的问题。

我们要写一个串口初始化函数,可以借助STC软件上的一个小工具帮我们生成代码

复制过来

改造成

即完成了下图中的定时器(橘色标识)和串口相关寄存器(蓝色标识)的配置(目前是禁止中断状态,即还没有配置中断系统)

开始调用

然后我们尝试发送一个字节给电脑

首先要把值写进SBUF,只要上面写的那个串口函数的波特率配置好了,定时器配置好了之后就自动发出去了。

但是我们还需要检测是否完成发送,因为刚写完不会立即发完,如果连续发就会出错,所以我们需要检测。怎么检测呢?就是看TI标志位。

标志位置1之后,我们用软件清零

然后我们来调用一下这个函数,假设传一个字节0110 0110过去

编译无错误后下载到单片机里面,重启板子,然后找到串口助手,点击打开串口(注意打开串口之后一定要把波特率改成4800,因为我们前面选择定时器1的初始值(波特率)是4800,采样之前要保证接收双方的速率是相同的,所以这里接收的话也要设置为4800)然后一般都是选择无校验位,停止位为1位

然后按下开发板上的复位

就可以看到电脑的确接收了0x66的数据,以十六进制显示

PS:以后我们可以把这里给勾上,以后就不用每次都要点击打开串口了

以上单向发送就已经写好了。

每隔一秒串口就发送一个递增的数给电脑

下面我们开始演示本节要实现的第一个示例:每隔一秒串口就发送一个递增的数给电脑。

首先我们要在以上程序的基础之上添加一个全局变量

然后主程序改成每发送一次就延迟1秒

看看效果

第一个程序完成!

然后我们可以模块化我们的程序,方便下一次代码演示。

main.c

UART.c

UART.h

别忘了还有我们的延时Delay函数的模块化,前面很多节都模块化过了,这里就不说了。

模块化后的程序放在评论区了,需要的自取!

电脑通过串口控制LED

下面我们开始演示本节要实现的第二个示例:电脑通过串口控制LED

我们把新创建一个工程(可以复制前面的工程文件,修改工程文件名)打开

然后把前面写的UART代码改造一下。

我们要添加一个中断函数,因为我们不知道电脑什么时候发过来,我们也不能一直检测,我们就利用中断,当电脑发过来之后就触发中断,然后再中断函数里面进行数据处理,把这个数据拿出来。

这次我们要将REN置1,所以把SCON改成0x50

REN允许接收后,单片机接收完数据之后触发中断,这时我们要把串口的中断打开

启动中断后,程序就跳转到中断函数里面

我们要查询串口中断的中断号,由下图我们可以知道UART的中断号为4

然后我们就应用这个中断号写一个串口中断函数在主程序文件中

由于给SBUF写数据的时候(即串口给电脑发送数据的时候)也会触发中断,而且发送和接收的中断标志位是占用同一通道的

所以发送和接收要区分开,因此加一个if判断语句

编译无错误后下载到单片机,然后重启板子,在串口助手中的发送区写入数据(然后串口就能接收到数据),点击发送后就能看到开发板上的LED发生响应的变化。

比如我写一个11即0x11,也就是0001 0001,所以LED的状态如下:

如果想让LED按二进制响应,比如你输入数字1,就是D1亮,输入2就是D2亮,输入3就是D2和D1亮,要实现这样的效果的话可以对输入的数据进行取反:

以上是单片机接收数据,然后我们还要把单片机接收的数据发给电脑

怎么写呢?就是调用前面写的UART_SendByte ( )函数

完整的代码:

main.c

UART.c

UART.h

别忘了还有我们的延时Delay函数的模块化,前面很多节都模块化过了,这里就不说了。

模块化后的程序放在评论区了,需要的自取!

编译后下载到单片机里面,当我们在发送区写入数据后,LED按响应的二进制响应,同时接收区就收到我们的数据

到这里,电脑和串口之间互相通信的程序就写好了。

波特率的具体计算

接下来我们具体说一下串口初始化函数里面的这个波特率怎么计算的

首先我们的波特率产生时是这个环节

然后函数里面我们当时在STC上选择的波特率是4800,生成的代码是F3

F3的十进制是243

每隔256溢出一次

256-243=13,就说明计数值是13,也就是每计13个数就溢出一次。

我们的单片机晶振是12MHz,机器周期是1微秒,也就是每一微秒就计一次数,也就是每隔13微秒就溢出一次,那溢出的频率就是1/13微秒,这就是定时器的溢出率。

1/13等于:

也就是说T1定时器的溢出率是0.07692MHz

然后我们这里还设置了波特率的倍数SMOD=1

那它就走的是除以16这条路线,

那0.07692还要除以16

这个结果是兆赫兹,我们需要转换成赫兹,那就乘以1000000

四舍五入就等于我们当时选的4800,这就是波特率了,大概0.16%的误差

如果不选择SMOD=1的话,那就是1/13先除2再除以16,那最后波特率就是SMOD=1时的一半

手册上也有计算公式

最后再补充一下数据显示模式方面的知识

HEX模式和文本模式

我们看到串口助手这里有两种数据模式:HEX模式和文本模式

HEX模式/十六进制模式/二进制模式:以原始数据的形式显示

文本模式/字符模式:以原始数据编码后(对照ASCII表上的数据)的形式显示

为什么需要这个ASCII值呢?

是因为原始数据只能发0~255这些数字,如果我们需要发其他的,比如说发个ABCD和其他一些符号,怎么发呢?这个时候就需要它按照这个ASCII表对我们输入的数据进行编码。

比如我们想要给电脑发个A,那我就可以输入0x41

文本模式下,它就会把0x41编码成A

如果你忘记了A这个字符的ASCII值,可以写成 ’A’,它和0x41是一个意思

以上就是本节所有内容,本节的代码都放在文件在评论区了,自取!

如有问题,请评论区留言。

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

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

相关文章

【学习笔记】TypeScript编译选项

TS 中的编译选项 我们写了一个TS的文件,我们需要使用如下的命令将我们的TS文件转换为JS文件。 tsc xxx.ts 这样会产生一个对应的js文件 自动编译文件 编译文件时,使用 -W 指令后,TS编译器会自动监视文件的变化,并在文件发生变…

[HTTP协议]应用层的HTTP 协议介绍

目录 1.前言 2.使用fiddler抓包来观察HTTP协议格式 3.HTTP协议的基本格式 2.1请求 2,1.1首行 2.1.2请求头 2.1.3空行 2.2响应 2.2.1首行 2.2.2响应头 键值对 ​编辑2.2.3空行 2.2.4载荷(响应正文) 3.认识URL 3.1关于URL encode 1.前言 我们在前面的博客中,简单的…

windows编程-系统编程入门

1.进程线程概念(简略版) 1.1 进程 1.1.1 概念 我们编写的代码只是一个存储在硬盘的静态文件,通过编译后就会生成二进制可执行文件,当我们运行这个可执行文件后,它会被装载到内存中,接着 CPU 会执行程序中…

【C++】初识模板:函数模板和类模板

目录 一、模板函数 1、函数模板的概念 2、函数模板的格式 3、函数模板的原理 4、函数模板实例化 5、 模板参数的匹配原则 二、类模板 1 、类模板的定义格式 2 、类模板的实例化 3、模板类示例 一、模板函数 1、函数模板的概念 函数模板代表了一个函数家族&#xff0c…

堆的概念实现

前言 本文将详细讲解堆。堆是一种二叉树(一般是完全二叉树)使用顺序结构的数组来存储。 tip:这里我们需要注意区分堆在不同地方的含义,这里的堆是一个数据结构,操作系统虚拟进程地址空间的堆是操作系统中管理内存的一块…

备战蓝桥杯---动态规划之背包问题引入

先看一个背包问题的简单版: 如果我们暴力枚举可能会超时。 但我们想一想,我们其实不关心怎么放,我们关心的是放后剩下的体积。 用可行性描述即可。 于是我们令f[i][j]表示前i个物品能否放满体积为j的背包。 f[i][j]f[i-1][j]||f[i-1][j-v…

怎么开启耳穴实操的道路

一.背景 前面的文章耳穴为什么有用?-CSDN博客,我说明了耳穴为什么有用、又是很安全的。 然后又告诉你了颈椎痛的耳穴配方用程序员的思维学习耳穴调理的第一个配方“颈椎病”-CSDN博客。 大胆放手去实操吧! 二.工具用什么 1.耳穴贴 由一…

K210如何下载程序

一、打开资料包里提供的K-Flash程序烧录软件 二、选择串口 三、选择波特率 四、选择In-Chip,烧录到Flash芯片里面,重新上电还会运行程序 五、如果选择In - Memory,这次可以运行,但下次重新上电就不会保持这次的程序了。 六、选择固…

火星符号运算 - 华为OD统一考试

OD统一考试(C卷) 分值: 100分 题解: Java / Python / C 题目描述 已知火星人使用的运算符号为 #和$ 其与地球人的等价公式如下 x#y2*x3*y4 x$y3*xy2x y是无符号整数。地球人公式按照c语言规则进行计算。火星人公式中&#xff0…

leetcode:63.不同路径二

dp数组含义:由初始位置到最终位置路径个数 递推公式:如果没有障碍再进行递推公式 初始化:1.若起始位置和终止位置有障碍路径个数为0 2.dp[i][0] 1和dp[0][j] 1的for循环条件都需要加上一个and dp[i][0] 0和and dp[0][j] 0. 3.遍历顺序…

Vue-Vue3 集成编辑器功能

1、安装依赖 编辑器插件需要安装 wangeditor/editor 和 wangeditor/editor-for-vue 两个插件 npm install wangeditor/editor --savevue3运行如下命令安装 npm install wangeditor/editor-for-vuenext --savevue2运行如下命令安装 npm install wangeditor/editor-for-vue -…

【前端web入门第四天】01 复合选择器与伪类选择器

文章目录: 1. 复合选择器 1.1 后代选择器 1.2 子代选择器 1.3 并集选择器1.4 交集选择器(了解) 2.伪类选择器 2.1 伪类-文本2.2 伪类-超链接(拓展) 1. 复合选择器 什么叫复合选择器? 由两个或多个基础选择器,通过不同的方式组合而成。 复合选择器的作…