51单片机应用开发(进阶)---串口接收字符命令
实现目标
1、巩固UART知识;
2、掌握串口接收字符数据;
3、具体实现目标:(1)上位机串口助手发送多字符命令,单片机接收命令作相应的处理(如:openled1 即打开LED1;closeled1 即关闭LED1;)
一、主要知识点
1.1 字符串定义
字符串是由字母、数字、下划线和空格等各种字符组成的一串字符,是一个常量。由一对双引号括起来。字符串的末尾都默认有一个'\0'的结束符。
C语言存储字符,其实是存储字符所对应的ASCII码,因此字符可以以%c或者%d输出均可以,需要作为常识记住的是:字符'0'对应的ASCII码为48,字符'A'对应的ASCII码为65,字符'Z'对应的ASCII码为90,字符'a'对应的ASCII码为97,字符'z'对应的ASCII码为122; 字符类型char占用1个字节。
用来存放字符的数组称为字符数组,字符数组实际上是一系列字符的集合,也就是字符串,C语言通常有两种表示字符串的方法:
第一种:定义一个字符数组;char str[]="abcd";
第二种:字符串指针; const char * str="hello"; 这种方式不可通过对字符指针解引用进行修改字符串,因为字符串常量不可修改!
这二者都是使用字符串常量对其进行初始化,从指针角度理解,本质一样,不论是字符数组,还是字符指针,str都代表字符串首字符的起始地址。区别在于:字符数组名为常量,常量不可以作左值!字符指针是变量,但是字符指针不可以进行解引用再修改值。
获取字符串的长度
方法一:sizeof()运算符
方法二:strlen()函数
求字符串“abcd”的长度
int str[]={"abcd"}
int len1=sizeof(str)/sizeof(str[0);
int len2=strlen(str);
解析:结果len1=5;len2=4;
sizeof 和strlen总结
①sizeof是运算符;strlen是库函数,包含在string.h头文件中
②sizeof功能是获得所建立对象的字节大小;strlen函数是获得字符串所占内存的有效字节数;
③sizeof运算符的参数可以是数组、指针、对象、函数等;strlen函数的参数必须是以'\0'结尾的字符串的指针;
④sizeof运算符计算大小在编译时就完成,因此不能用来计算动态分配内存大小;strlen函数结果要在运行时才能计算出来。
1.2 strstr 函数应用
(1) 头文件
#include <string.h>
(2) 函数原型
char *strstr(const char *haystack, const char *needle);
(3) 函数作用
1、strstr() 函数搜索一个字符串在另一个字符串中的第一次出现。
2、找到所搜索的字符串,则该函数返回第一次匹配的字符串的地址;
3、如果未找到所搜索的字符串,则返回NULL。
情景一:
用于单次匹配
返回的是匹配成功的字符串以及后面的字符串
#include <stdio.h>
#include <string.h>
main()
{char *s="GoldenGlobalView";char *l="lob";char *p;p=strstr(s,l);if(p)printf("%s",p);elseprintf("NotFound!");return 0;
}
二、原理图设计
STC89C52RC/RD+系列单片机串行口对应的硬件部分对应的管脚是P3.0/RxD和P3.1/TxD。
三、程序设计
3.1单片机接收上位机PC的命令
参数:波特率9600 ;SMOD为0,波特率不加倍;定时器1,工作模式2,8位自动重装。
具体功能:发字符 a,开启LED1; 发字符 b,关闭LED1;
#include <REGX52.H>#define FOSC 11059200L //System frequency
#define BAUD 9600 //UART baudratesbit LED1 = P2^0;int cmd = 0;//命令
bit flag = 0;void Uart_send(unsigned char dat);
void Uart_send_str(unsigned char *p);
void Delay500ms();void main()
{PCON &= 0x7F; //波特率不倍速SCON = 0x50; //8-bit variable UARTTMOD = 0x20;//0010 0000 //Set Timer1 as 8-bit auto reload modeTH1 = TL1 = -(FOSC/12/32/BAUD); //Set auto-reload vauleTR1 = 1; //Timer1 start runES = 1; //Enable UART interruptEA = 1; //Open master interrupt switchwhile(1){if(flag == 1)//查询是否接收一字节的命令{flag = 0;//标志位清零0if(cmd == 'a'){LED1 = 0;Uart_send(cmd);}else if(cmd == 'b'){LED1 = 1;Uart_send(cmd);} }}
}
void Uart_send(unsigned char dat)
{SBUF = dat;while(!TI);TI = 0;
}void Uart_send_str(unsigned char *p)
{while(*p!='\0'){Uart_send(*p); p++; }
}void Uart_Isr() interrupt 4
{if (RI == 1){RI = 0; //Clear receive interrupt flag flag = 1;cmd = SBUF; }
}void Delay500ms() //@11.0592MHz
{unsigned char i, j, k;i = 4;j = 129;k = 119;do{do{while (--k);} while (--j);} while (--i);
}
3.2 字符串命令控制LED
具体功能:发字符串open,开启LED1; 发字符串close,关闭LED1;
#include <REGX52.H>
#include <stdio.h>
#include <string.h> #define FOSC 11059200L //System frequency
#define BAUD 9600 //UART baudratesbit LED1 = P2^0; typedef struct
{unsigned char buff[32]; //用于存放接收到的字符串unsigned char flag; //接收完成中断标志位unsigned char len; //用于偏移字符串指针,可以理解为长度,如果buff设得很长,对应这里需要改成u16
}REC;REC UART_rec={0}; //初始化结构体
const char *substr1 = "open";
const char *substr2 = "close"; void Uart_send(unsigned char dat);
void Uart_send_str(unsigned char *p);
void Delay500ms();void main()
{PCON &= 0x7F; //波特率不倍速SCON = 0x50; //8-bit variable UARTTMOD = 0x20;//0010 0000 //Set Timer1 as 8-bit auto reload modeTH1 = TL1 = -(FOSC/12/32/BAUD); //Set auto-reload vauleTR1 = 1; //Timer1 start runES = 1; //Enable UART interruptTI = 1; EA = 1; //Open master interrupt switchwhile(1){if(UART_rec.flag == 1)//若接收完成{if (strstr(UART_rec.buff,substr1)!= NULL){printf("开启LED1\n"); LED1 = 0; }else if(strstr(UART_rec.buff,substr2)!= NULL){printf("关闭LED1\n"); LED1 =1; }// printf("接收到了:%s\r\n",UART_rec.buff);UART_rec.flag = 0; //接收标志位清零,准备接收下一字符串 }}
}void Uart_send(unsigned char dat)
{SBUF = dat;while(!TI);TI = 0;
}void Uart_send_str(unsigned char *p)
{while(*p!='\0'){Uart_send(*p); p++; }
}void Uart_Isr() interrupt 4
{unsigned char temp = 0; if (RI == 1){ RI = 0; //清除接收中断标志 temp = SBUF; if(temp=='\r'||temp=='\n'||UART_rec.len >= 32) {UART_rec.buff[UART_rec.len]='\0';UART_rec.flag = 1 ; //数据包接收完成标志UART_rec.len=0; //为下一个数据包做准备}else{UART_rec.buff[UART_rec.len++] = temp;}}
}void Delay500ms() //@11.0592MHz
{unsigned char i, j, k;i = 4;j = 129;k = 119;do{do{while (--k);} while (--j);} while (--i);
}
四、实验效果
五、仿真实现
5.1单片机接收的字符命令仿真
总结
相关文章:

51单片机应用开发(进阶)---串口接收字符命令
实现目标 1、巩固UART知识; 2、掌握串口接收字符数据; 3、具体实现目标:(1)上位机串口助手发送多字符命令,单片机接收命令作相应的处理(如:openled1 即打开LED1;closeled1 即关…...
redis 怎么样删除list
在 Redis 中,可以使用以下方法删除列表或列表中的元素: 1. 删除整个列表 使用 DEL 命令删除一个列表键: DEL mylist这个命令会删除键 mylist 及其值(无论 mylist 是一个列表还是其他类型的键)。 2. 删除列表中的部分…...

【数据结构——内排序】快速排序(头歌实践教学平台习题)【合集】
目录😋 任务描述 测试说明 我的通关代码: 测试结果: 任务描述 本关任务:实现快速排序算法。 测试说明 平台会对你编写的代码进行测试: 测试输入示例: 10 6 8 7 9 0 1 3 2 4 5 (说明:第一行是元素个数&a…...

npm或yarn包配置地址源
三种方法 1.配置.npmrc 文件 在更目录新增.npmrc文件 然后写入需要访问的包的地址 2.直接yarn.lock文件里面修改地址 简单粗暴 3.yarn install 的时候添加参数 设置包的仓库地址 yarn config set registry https://registry.yarnpkg.com 安装:yarn install 注意…...
STUN服务器用于内网NAT的方案
在内网中部署 STUN 服务器的场景通常用于处理多层 NAT 或内网客户端之间的通信需求,尤其是在大企业或学校等复杂网络环境下。通过 STUN 服务器,可以帮助客户端设备检测和适配 NAT 转换规则,进而支持 WebRTC 或其他实时通信技术的正常运行。 …...

Linux 简单命令总结
1. 简单命令 1.1. ls 列出该目录下的所有子目录与文件,后面还可以跟上一些选项 常用选项: ・-a 列出目录下的所有文件,包括以。开头的隐含文件。 ・-d 将目录象文件一样显示,而不是显示其下的文件。如:ls -d 指定目…...
Vue.js组件开发:提升你的前端工程能力
Vue.js 是一个用于构建用户界面的渐进式框架,它允许开发者通过组件化的方式创建可复用且易于管理的代码。在 Vue.js 中开发组件是一个直观且高效的过程,下面我将概述如何创建和使用 Vue 组件,并提供一些最佳实践。 1. 创建基本组件 首先&am…...
使用 Pandas 读取 JSON 数据的五种常见结构解析
文章目录 引言JSON 数据的五种常见结构1. split 结构2. records 结构3. index 结构4. columns 结构5. values 结构 引言 在日常生活中,我们经常与各种数据打交道,无论是从网上购物的订单信息到社交媒体上的动态更新。JSON(JavaScript Object…...

C++鼠标轨迹算法(鼠标轨迹模拟真人移动)
一.简介 鼠标轨迹算法是一种模拟人类鼠标操作的程序,它能够模拟出自然而真实的鼠标移动路径。 鼠标轨迹算法的底层实现采用C/C语言,原因在于C/C提供了高性能的执行能力和直接访问操作系统底层资源的能力。 鼠标轨迹算法具有以下优势: 模拟…...

Go mysql驱动源码分析
文章目录 前言注册驱动连接器创建连接交互协议读写数据读数据写数据 mysqlConncontext超时控制 查询发送查询请求读取查询响应 Exec发送exec请求读取响应 预编译客户端预编译服务端预编译生成prepareStmt执行查询操作执行Exec操作 事务读取响应query响应exec响应 总结 前言 go…...

GNSS误差源及差分定位
GNSS误差源: (一)卫星星历误差 由星历信息所得出的卫星位置坐标与实际位置坐标的偏差就是星历误差。星历信息是由 GPS 地面部分测量计算后传入空间部分的。由于卫星在运动中要受到各种摄动力的作用, 而地面部分又很难精确测量这些作用力,…...
pg数据类型
1、数值类型: smallint 2 字节 小范围整数 -32768 到 32767 integer 4 字节 常用的整数 -2147483648 到 2147483647 bigint 8 字节 大范围整数 -9223372036854775808 到 9223372036854775807 decimal 可变长 用户指定的精度&#x…...
【java】finalize方法
目录 1. 说明2. 调用过程3. 注意事项 1. 说明 1.finalize方法是Java中Object类的一个方法。2.finalize方法用于在对象被垃圾回收之前执行一些清理工作。3.当JVM(Java虚拟机)确定一个对象不再被引用、即将被回收时,会调用该对象的finalize方法…...

HNU_多传感器(专选)_作业4(构建单层感知器实现分类)
1. (论述题)(共1题,100分) 假设平面坐标系上有四个点,要求构建单层感知器实现分类。 (3,3),(4,3) 两个点的标签为1; (1,1),(0,2) 两个点的标签为-1。 思路:要分类的数据是2维数据,需要2个输入…...

以太网链路详情
文章目录 1、交换机1、常见的概念1、冲突域2、广播域3、以太网卡1、以太网卡帧 4、mac地址1、mac地址表示2、mac地址分类3、mac地址转换为二进制 2、交换机的工作原理1、mac地址表2、交换机三种数据帧处理行为3、为什么会泛洪4、转发5、丢弃 3、mac表怎么获得4、同网段数据通信…...
vue3 setup语法,子组件点击一个元素打印了这个元素的下标id,怎么传递给父组件,让父组件去使用
问: vue3 setup语法,子组件点击一个元素打印了这个元素的下标id,怎么传递给父组件,让父组件去使用 回答: 在 Vue 3 中,你可以使用 setup 语法糖和组合式 API 来实现子组件向父组件传递数据。具体来说&am…...

《Keras3 minist 手写数字AI模型训练22秒精度达到:0.97》
《Keras3 minist 手写数字AI模型训练22秒精度达到:0.97》 一、修改源码加上如下两条代码二、源码修改如下三、Keras3 minist 训练22秒结束,训练过程截图四、Keras3 minist 源码截图 一、修改源码加上如下两条代码 import os os.environ["KERAS_BAC…...
【.net core】【sqlsugar】大数据写入配置(需要版本5.0.45)
官网连接 https://www.donet5.com/home/Doc?typeId2404 泛型方法 /// <summary> /// 大数据写入(泛型方法) /// </summary> /// <param name"entitys"></param> /// <returns></returns> ///代码中_d…...

ansible运维实战
通过学习ansible自动化运维,初步对ansible有了一定的了解,此次分享两个案例,希望对大家有所帮助 案例一:自动化安装nginx 本次案例目的是ansible自动化安装nginx并配置 首先创建如图所示目录 在主机上安装好nginx,如…...
DDOS分布式拒绝服务攻击
DDOS分布式拒绝服务攻击 简单来说 传统的DOS就是一台或者多台服务对一个受害目标(服务器,路由,ip,国家)进行攻击,当范围过大时就是DDOS。目的就是通过大规模的网络流量使得正常流量不能访问受害目标&…...

铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存
文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...

用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...
GitHub 趋势日报 (2025年06月06日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...

C++--string的模拟实现
一,引言 string的模拟实现是只对string对象中给的主要功能经行模拟实现,其目的是加强对string的底层了解,以便于在以后的学习或者工作中更加熟练的使用string。本文中的代码仅供参考并不唯一。 二,默认成员函数 string主要有三个成员变量,…...

echarts使用graphic强行给图增加一个边框(边框根据自己的图形大小设置)- 适用于无法使用dom的样式
pdf-lib https://blog.csdn.net/Shi_haoliu/article/details/148157624?spm1001.2014.3001.5501 为了完成在pdf中导出echarts图,如果边框加在dom上面,pdf-lib导出svg的时候并不会导出边框,所以只能在echarts图上面加边框 grid的边框是在图里…...
起重机起升机构的安全装置有哪些?
起重机起升机构的安全装置是保障吊装作业安全的关键部件,主要用于防止超载、失控、断绳等危险情况。以下是常见的安全装置及其功能和原理: 一、超载保护装置(核心安全装置) 1. 起重量限制器 功能:实时监测起升载荷&a…...