什么可以用手机蓝牙控制LED???#串口通信【下】

什么可以用手机蓝牙控制LED???#串口通信【下】

    • 前言
    • 预备知识
    • 1.小白玩串口控制的ASSII避坑
      • 1.1问题引入
      • 1.2解决问题
    • 2.串口支持单词型指令控制
      • 2.1实现串口支持单词型指令控制的核心思路
      • 2.2利用字符数组来承接单词型指令
      • 2.3利用strstr函数来查找指令并执行
      • 2.4完整程序代码
      • 2.5补充知识
    • 3.串口原理协议概念收尾
      • 3.1串行口工作模式1:8位UART,波特率可变
      • 3.2串行口工作模式1:8位UART,波特率可变时序图
      • 3.3串口结构框图
    • 4.通过手机蓝牙控制LED
      • 4.1向单片机中烧入串口支持单词型指令控制代码
      • 4.2将蓝牙模块HC-08连接单片机
      • 4.3通过蓝牙串口助手小程序连接蓝牙模块
      • 4.4在发送对话框发送开灯即可打开LED灯,发送关闭即可关闭LED灯。
    • 5.HC-08蓝牙模块
      • 5.1蓝牙模块简介
      • 5.2 HC-08蓝牙串口通信模块接线
    • 6.AT指令修改蓝牙名字
      • 6.1 AT指令表
      • 6.2将USB转TTL转接器与蓝牙模块HC-08连接
      • 6.3把USB转TTL转接器连接电脑通过单片机下载器修改蓝牙名称
    • 结束语

前言

  本篇博文介绍的是用51单片机的串口通信【下】,包含小白玩串口控制的ASSII避坑,串口支持单词型指令控制,串口原理协议概念收尾,通过手机蓝牙控制LED,HC-08蓝牙模块,AT指令修改蓝牙名字。看到这篇博文的朋友,可以先赞再看吗?

预备知识

  一、数学分数计算。
  二、数字电子时序图

  三、数字电子中与或运算
  四、计算机中的进制转换
  五、C变量
  六、基本输入输出
  七、流程控制
  八、函数

  九、指针
  十,字符串

  如果以上知识不清楚,请自行学习后再来浏览。如果我有没例出的,请在评论区写一下。谢谢啦!

1.小白玩串口控制的ASSII避坑

1.1问题引入

  如果要用1控制开灯,0控制关灯。那么是直接改判断条件还是怎么做呢?

1.2解决问题

  • 显然是不行的,直接用1开灯,0关灯单片机上是没有任何反应的。因为中的是文本模式发送。

在这里插入图片描述

  • 尝试改到HEX模式呢?

在这里插入图片描述

  实验后观察可以开灯,也可以关灯

  这是为什么呢?我们想一想,在C语言中为什么int型和char型是可以互通的呢?其实是因为ASSII码的存在。也就是说计算机在处理文本时是用ASSII码来处理,所以在代码为1开灯0关灯时在文本模式下输入1开灯0关灯不执行,是因为代码下的1和0不是文本下的1和0的ASSII码。若要实现在文本模式下输入1开灯0关灯,那么就要在代码内写49和48来控制开关灯,因为49是1的ASSII码,48是0的ASSII码。当使用HEX模式时,在计算机中把16进制的1和二进制的1是互通的,也就是此时输入1能被单片机识别并执行开灯。

  • ASSI码对照表

在这里插入图片描述

2.串口支持单词型指令控制

2.1实现串口支持单词型指令控制的核心思路

  • 利用字符数组来承接单词型指令
  • 利用strstr函数来查找指令并执行

2.2利用字符数组来承接单词型指令

  • 将接收电脑开关灯的指令变量定义为一个大小为32的字符数组,并用宏定义定义出大小为32
#define SIZE 32

char LEDStatus[SIZE];
  • 在串口中断函数中定义一个静态变量,因为在多次函数调用中只被执行一次初始化
static int i = 0;
  • 让SBUF寄存器的数据赋给LEDStatus[i]的第i个元素,并入让i自增。为了方便一个字符一个字符的存入字符数组
LEDStatus[i] = SBUF;
i++; //数组标号增加,方便存放字符串

2.3利用strstr函数来查找指令并执行

  • 选用strstr字符查找函数是因为:如果选用strcmp字符串比较函数,必须一致才成立,但在传送字符串是会把字符顺序搞乱。所以使用查找函数来查找,查找函数只需要查找含有相应字符即可,不必顺序一致。
  • 使用strstr函数必须包含头文件string.h
#include "string.h"
  • 在if判断内将i软件置零,使用memset函数将LEDStatus变量清零
i    = 0;                    //清零是为了方便存放下一次指令
memset(LEDStatus,'\0',SIZE); //字符串清零函数,实参为清零的字符串变量,清理成什么字符,清理的大小或数量

2.4完整程序代码

#include "reg52.h"
#include "string.h"
#define SIZE 32

sfr AUXR = 0x8e;   //声明AUXR寄存器地址
sbit LED1 = P3^7;  //使用位定义声明LED1

//建立接收电脑开关灯的指令变量
char LEDStatus[SIZE];

void Delay1000ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	i = 8;
	j = 1;
	k = 243;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}


void UartInit(void)		//自己配
{
	//配置串口工作方式为方式1,从只收不发改为能收能发
	SCON =  0x50;
  //配置辅助寄存器,减少电磁辐射,稳定晶振频率  
	AUXR =  0x01;
	//设置定时器工作方式为定时器1的8位自动重装
	TMOD &= 0x0F;
	TMOD |= 0x20;
	//设置串口波特率为9600,0误差
	TH1   = 0xFD;
	TL1   = 0xFD;
	//打开定时器1
	TR1   = 1;
	//打开总中断
	EA = 1;
	//打开串口中断
	ES = 1;
}

void sendByte(char data_mas)
{
	SBUF = data_mas;
	while(!TI);
	TI = 0;          //一定要软件置零,不然会出现乱序
}

void sendString(char *str)
{
	while(*str != '\0')
	{
		sendByte(*str);
		str++;
	}
}

void main()
{
	//初始化灯的状态
	LED1 = 1;
	//初始化串口,配置波特率
	UartInit();
	
	//每延时1秒向电脑发送数据a
	while(1)
	{
		Delay1000ms();		
		sendString("一起来学串口通信!!!\r\n");  //\r\n 为串口中的换行,缺一不可
		//怎么知道PC发了数据:由手册可知RI位为接受中断标志位,所以用查询的方法来判断RI是否等于1来开关灯
	}
} 

void UART_handler() interrupt 4
{
	//定义一个静态整型变量,在多次函数调用中只被执行一次初始化
	static int i = 0;
	//在串口中段函数中可以对发送接收中断标志进行处理
	if(RI == 1)
		{
			RI = 0;     //必须软件置零
			LEDStatus[i] = SBUF;
			i++; //数组标号增加,方便存放字符串
			//如果用开灯指令开灯,关灯指令关灯
			if(strstr(LEDStatus,"开灯")) //运用C语言字符串知识,使用的是字符串查找函数,查找到即返回1
			{
				LED1 = 0;
				i    = 0;                    //清零是为了方便存放下一次指令
				memset(LEDStatus,'\0',SIZE); //字符串清零函数,实参为清零的字符串变量,清理成什么字符,清理的大小或数量
			}
			if(strstr(LEDStatus,"关灯"))
			{
				LED1 = 1;
				i    = 0;
				memset(LEDStatus,'\0',SIZE); 
			}
		}
		
	
	if(TI);
		
}

2.5补充知识

  • 在字符串中是支持中文的,计算机内部会把中文转换为相应的编码,方便使用

3.串口原理协议概念收尾

3.1串行口工作模式1:8位UART,波特率可变

  当软件设置SCON的SM0、SM1为“01”时,串行通信则以模式1工作。此模式为8位UART格式,**一帧信息为10位:1位起始位,8位数据位(低位在先)和1位停止位。**波特率可变,即可根据需要进行设置。TxD(TxD/P3.1)为发送信息,RxD(RxD/P3.0)为接收端接收信息,串行口为全双工接受/发送串行口。

3.2串行口工作模式1:8位UART,波特率可变时序图

3.3串口结构框图

在这里插入图片描述

4.通过手机蓝牙控制LED

4.1向单片机中烧入串口支持单词型指令控制代码

#include "reg52.h"
#include "string.h"
#define SIZE 32

sfr AUXR = 0x8e;   //声明AUXR寄存器地址
sbit LED1 = P3^7;  //使用位定义声明LED1

//建立接收电脑开关灯的指令变量
char LEDStatus[SIZE];

void Delay1000ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	i = 8;
	j = 1;
	k = 243;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}


void UartInit(void)		//自己配
{
	//配置串口工作方式为方式1,从只收不发改为能收能发
	SCON =  0x50;
  //配置辅助寄存器,减少电磁辐射,稳定晶振频率  
	AUXR =  0x01;
	//设置定时器工作方式为定时器1的8位自动重装
	TMOD &= 0x0F;
	TMOD |= 0x20;
	//设置串口波特率为9600,0误差
	TH1   = 0xFD;
	TL1   = 0xFD;
	//打开定时器1
	TR1   = 1;
	//打开总中断
	EA = 1;
	//打开串口中断
	ES = 1;
}

void sendByte(char data_mas)
{
	SBUF = data_mas;
	while(!TI);
	TI = 0;          //一定要软件置零,不然会出现乱序
}

void sendString(char *str)
{
	while(*str != '\0')
	{
		sendByte(*str);
		str++;
	}
}

void main()
{
	//初始化灯的状态
	LED1 = 1;
	//初始化串口,配置波特率
	UartInit();
	
	//每延时1秒向电脑发送数据a
	while(1)
	{
		Delay1000ms();		
		sendString("一起来学串口通信!!!\r\n");  //\r\n 为串口中的换行,缺一不可
		//怎么知道PC发了数据:由手册可知RI位为接受中断标志位,所以用查询的方法来判断RI是否等于1来开关灯
	}
} 

void UART_handler() interrupt 4
{
	//定义一个静态整型变量,在多次函数调用中只被执行一次初始化
	static int i = 0;
	//在串口中段函数中可以对发送接收中断标志进行处理
	if(RI == 1)
		{
			RI = 0;     //必须软件置零
			LEDStatus[i] = SBUF;
			i++; //数组标号增加,方便存放字符串
			//如果用开灯指令开灯,关灯指令关灯
			if(strstr(LEDStatus,"开灯")) //运用C语言字符串知识,使用的是字符串查找函数,查找到即返回1
			{
				LED1 = 0;
				i    = 0;                    //清零是为了方便存放下一次指令
				memset(LEDStatus,'\0',SIZE); //字符串清零函数,实参为清零的字符串变量,清理成什么字符,清理的大小或数量
			}
			if(strstr(LEDStatus,"关灯"))
			{
				LED1 = 1;
				i    = 0;
				memset(LEDStatus,'\0',SIZE); 
			}
		}
		
	
	if(TI);
		
}

4.2将蓝牙模块HC-08连接单片机

  • 将蓝牙模块HC-08TXD连接51单片机的RXD
  • 将蓝牙模块HC-08RXD连接51单片机的TXD
  • 将蓝牙模块HC-08VCC连接51单片机的5V
  • 将蓝牙模块HC-08GND连接51单片机的GND

4.3通过蓝牙串口助手小程序连接蓝牙模块

  • 微信小程序搜索HCBLE串口助手
  • 打开HCBLE串口助手
  • 点击附近设备
  • 找到HC-08的设备并点击连接。
  • 在弹出的页面中可以看到单片机发送的字符。也可以发送字符给单片机。

4.4在发送对话框发送开灯即可打开LED灯,发送关闭即可关闭LED灯。

5.HC-08蓝牙模块

5.1蓝牙模块简介

  • 蓝牙模块,又叫做蓝牙串口模块
  • 串口透传技术

  透传即透明传送,是指在数据的传输过程中,通过无线的方式这组数据不发生任何形式的改变,仿佛传输过程是透明的一样,同时保证传输的质量,原封不动地到了最终接收者手里。

  • 以太网,蓝牙,Zigbee, GPRS 等模块玩法一样,对嵌入式程序员来说,不需要关心通讯模块内部数据及协议栈工作原理,只要通过串口编程获得数据即可
  • HC-08蓝牙串口通信模块为一对一连接透传,主从机一体。(用户可根据需求,用AT指令切换模块主从)
  • HC-08的参数

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

5.2 HC-08蓝牙串口通信模块接线

在这里插入图片描述

6.AT指令修改蓝牙名字

6.1 AT指令表

在这里插入图片描述

6.2将USB转TTL转接器与蓝牙模块HC-08连接

  • 将蓝牙模块HC-08TXD连接USBTTL转接器的RXD
  • 将蓝牙模块HC-08RXD连接USBTTL转接器的TXD
  • 将蓝牙模块HC-08VCC连接USBTTL转接器的5V
  • 将蓝牙模块HC-08GND连接USBTTL转接器的GND

6.3把USB转TTL转接器连接电脑通过单片机下载器修改蓝牙名称

  • 在单片机下载器中打开串口助手
  • 接收和发送缓冲区都设置为文本模式
  • 串口设置为相应串口,波特率为9600,校验位为无校验,停止位为1位
  • *在发送缓冲区发送AT+NAME=* * 即可修改蓝牙名字
  • 特别注意在修改蓝牙名字时,不用用手机端蓝牙助手连接蓝牙模块,不然会修改失败。

在这里插入图片描述

结束语

  很高兴您能看到这里,点个赞再走呗。谢谢您啦!!!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java 面向对象进阶 03 static 注意事项、重新认识main方法(黑马)

案例代码如下: 非静态的方法虚拟机会自带一个关键字,如下: 但是不能手动出来,它的类型就是当前类; 通过输出this,得到当前s1,s2 的地址; 所以在输出时会有隐藏的this,所以this所指向…

java+springboot电影订票选座及评论网站影评系统ssm+vue

广大观影消费者需要知道自己的空闲时间,在自己可以接受的地理距离范围内,是否有感兴趣的影片可供观看,也需要清楚哪家影院在销售自己需要的电影票;同时手握电影排期及上映信息的电影院的运营者也急需根据消费者的观影需求实时调整…

肉食食材大数据平台(附源码)

目录 一.需求分析 1.项目背景 2.用户简介 3.术语定义 4.功能概述 二.概要设计 1.概要设计流程图 2.流程图详细说明 三.数据库设计 1.软件名称 2.概念结构设计 2.1电商模块 2.2猪肉今日价格模块 2.3大屏展示模块 2.3.1舆论舆情 2.3.2 省均价模块 2.3.3进出口模块…

Kafka下载安装及基本使用

目录 Kafka介绍 消息队列的作用 消息队列的优势 应用解耦 异步提速 削峰填谷 为什么要用Kafka Kafka下载安装 Kafka快速上手(单机体验) 1. 启动zookeeper服务 2. 启动kafka服务 3. 简单收发消息 Kakfa的消息传递机制 Kafka介绍 Apache Kafka…

pysyft框架中WebsocketClientWorker与WebsocketServerWorker的消息传输

引言 pysyft是基于pytorch的一个联邦学习框架(虽然用起来很难受),通过内存管理实现联邦学习的模拟。 在pysyft中,WebsocketServerWorker充当数据的提供方(数据存储方),而WebsocketClientWorker…

vue项目在public中编写一个json文件 并用http请求获取 模仿数据接口

我们前后端分离是经常存在 前端已经开发到需要接口 但后端还没开始的情况的 如果直接在js中写假数据 后面还要改不少东西 多少有点麻烦 我们可以 直接在 public 静态资源目录下创建一个json文件 这里 我取名叫 city.json 大家可以根据自己喜好给json文件命名 我这个json文件的…

深入浅出HBase:一文理解HBase基础概念(列存储、时间戳、key-value)、架构特点以及适合的使用场景

文章目录 一. HBase 数据模型1. 行存储与列式存储1.1. 行存储1.2. 列存储 2. HBase 数据模型2.1. 模型概览2.2. 列与列族2.3. 时间戳:定义数据版本2.4. HBase的Key-Value 三. HBase架构1. HBase读写流程简述2. HRegionServer内部内部数据流转:HRegion &l…

Proxy ARP

1.路由式ARP 路由式Proxy ARP就是使那些IP地址在同一网段却连接到不同物理网络上的设备能够相互通信的一种功能。 当PC1需要与S1通信时,由于目的IP地址与本机的IP地址为同一网段,因此PC1以广播形式发送ARP请求报文,请求PC2的MAC地址。但是&…

使用orangepi玩linux

最近看了这个大佬的文章,写了使用远程来挂载linux的方案,觉得还是很有意思的,瞬间感觉linux这块都还是相通的,就跑了一下,果然,牛逼! 香橙派全志H3烧录Uboot,远程加载zImage&#xf…

【百度Apollo】探索创新之路:深入了解Apollo开放平台

🎬 鸽芷咕:个人主页 🔥 个人专栏: 《linux深造日志》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! ⛳️ 推荐 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下…

代码随想录算法训练营DAY8 | 字符串(1)

一、LeetCode 344 反转字符串 题目链接&#xff1a; 344.反转字符串https://leetcode.cn/problems/reverse-string/ 思路&#xff1a;双指针法交换。 class Solution {public void reverseString(char[] s) {int n s.length;int left 0, right n-1;while(left < right){c…

轮转数组[中等]

优质博文&#xff1a;IT-BLOG-CN 一、题目 给定一个整数数组nums&#xff0c;将数组中的元素向右轮转k个位置&#xff0c;其中k是非负数。 示例 1: 输入: nums [1,2,3,4,5,6,7], k 3 输出: [5,6,7,1,2,3,4] 解释: 向右轮转 1 步: [7,1,2,3,4,5,6] 向右轮转 2 步: [6,7,1,2,…

Android矩阵Matrix变换setRectToRect,Kotlin

Android矩阵Matrix变换setRectToRect&#xff0c;Kotlin 在 Android画布Canvas裁剪区域clipRect&#xff0c;Kotlin-CSDN博客 基础上&#xff0c;增加一个点&#xff0c;通过setRectToRect挖出Bitmap原图中心区域的一块放到目标RectF里面。 import android.content.Context imp…

MBR分区转换为GPT分区

这里有一个ecs-test用于测试MBR转换为GPT 新增一块数据盘 将数据盘以MBR分区格式分区 将整块磁盘以mbr形式分区 格式化&#xff0c;挂载等 上传文件&#xff0c;方便测试(以便后续转换格式类型&#xff0c;防止文件丢失) 取消挂载 将MBR转换为GPT 需先下载gdisk yum instal…

k8s从私有库harbor中拉取镜像

一、前言 Docker镜像是构建应用程序的基础。然而&#xff0c;许多组织和开发团队希望保留他们的Docker镜像在私有仓库中&#xff0c;并从中拉取镜像&#xff0c;而不是从公共Docker Hub中下载。这样做的原因有很多&#xff0c;包括&#xff1a; 1. 安全性&#xff1a;私有仓库可…

V2X,启动高增长引擎

车载通讯的下一个新周期&#xff0c;毋庸置疑是V2X。从4G、5G再到C-V2X&#xff0c;是车载通讯逐步从信息娱乐、行车数据监控到万物互联的关键。 去年5月&#xff0c;全球车载通讯芯片巨头—高通公司宣布&#xff0c;与以色列车联网&#xff08;V2X&#xff09;芯片设计公司Aut…

二叉搜索树操作题目:删除二叉搜索树中的结点

文章目录 题目标题和出处难度题目描述要求示例数据范围进阶 解法一思路和算法代码复杂度分析 解法二思路和算法代码复杂度分析 题目 标题和出处 标题&#xff1a;删除二叉搜索树中的结点 出处&#xff1a;450. 删除二叉搜索树中的结点 难度 5 级 题目描述 要求 给定二叉…

关于JVM常见的十道面试题

方法区、永久代和元空间有什么区别&#xff1f; 方法区、永久区和元空间是Java虚拟机用于存储类信息的区域&#xff0c;它们在不同的Java虚拟机版本有所不同&#xff1a; 方法区&#xff1a;方法去是一块用于存储类的结构信息、常量、静态变量、即时编译器编译后的代码等数据…

5、应急响应-拒绝服务钓鱼识别DDOS压力测试邮件反制分析应用日志

目录 前言&#xff1a; 1、#内网应急-日志分析-爆破&横向&数据库 2、#红队APT-钓鱼邮件识别-内容&发信人&附件 3、#拒绝服务攻击-DDOS&CC-代理&防火墙防御 用途&#xff1a;个人学习笔记&#xff0c;欢迎指正&#xff01; 前言&#xff1a; 了解和…

opencv#41 轮廓检测

轮廓概念介绍 通常我们使用二值化的图像进行轮廓检测&#xff0c;对轮廓以外到内进行数字命名&#xff0c;如下图&#xff0c;最外面的轮廓命名为0&#xff0c;向内部进行扩展&#xff0c;遇到黑色白色相交区域&#xff0c;就是一个新的轮廓&#xff0c;然后依次对轮廓进行编号…