【STM32F103】JDY-31蓝牙模块(USART)

JDY-31

JDY-31蓝牙模块,就是下面这么个小玩意。某宝买大概就七八块,超过十块的不要买。

JDY一共有6根引脚,而我们想要让它工作的话只需要接两根线即可,那就是VCC和GND,给VCC接3.6V~6V的电压(推荐是5V),GND接地,然后JDY31就开始工作了,我们的手机打开蓝牙就能找到JDY的蓝牙了。

配对后我们的手机就可以和JDY31进行通信了,但是仅仅是和JDY31通信,这没有什么意义,所以我们会将JDY31和单片机进行连接,这样我们就可以用手机通过蓝牙去控制单片机了。

我们把JDY31的RXD接到我们STM32F103的TXD,而TXD接到我们STM32F103的RXT(推荐使用USART1的资源,GPIOA的9号引脚和10号引脚,因为JDY的工作电压较高,STM32F103一般的引脚受不了,而USART1资源的引脚能够接受5V电压,具体可以参考引脚定义表)

这样,只要我们的手机通过蓝牙和JDY31连接之后,并且JDY31和STM32F103通过串口连接之后,只要手机通过蓝牙助手发送串口数据,然后JDY就会直接收到并且发送给STM32F103。而STM32F103通过串口发送的数据也会经由JDY31来传输到我们的手机上。

所以蓝牙通信没那么难,或者说是因为有像JDY31这些集成度高的模块,使得我们的蓝牙通信变得简单。

剩下两个引脚是STATE和EN,简单来说EN没有用,而我们连接上来自JDY的蓝牙之后,STATE会输出高电平,可以外接一个LED来直观的查看蓝牙是否连接。不过其实没有太大必要,因为JDY自带一个小红灯,等待连接的时候小红灯会闪烁,而连接上之后小红灯常亮。

AT命令控制JDY31

上面讲述了怎么通过JDY31来进行蓝牙通信。

而如果我们想要修改JDY的一些配置信息(例如蓝牙名称,连接的密码之类的),我们就需要使用AT命令来对JDY进行控制。

其实AT命令听起来挺酷,实际上就是一堆特定的字符串罢了。

例如我要查询版本号,那么我直接让STM32F103通过串口发送字符串“AT+VERSION\r\n”即可,也就是指令再加上“\r\n”。然后JDY31就会通过串口把版本号再通过串口发过来。本质上还是串口通信。

总的指令就上面九条没什么可说的,下面就简单说一下带参数的指令。

波特率这条指令可以加上参数来修改波特率,不过不是自由设置的,例如我要设置9600的波特率,那么我发送的指令就应该是“AT+BAUD<4>\r\n”,其他波特率的参数可以参考上面的图。

设置配对密码,默认是1234,把要修改的密码当作参数发送即可。

蓝牙名称设置,这个会稍微有些延迟,要等一等,手机上搜索到的蓝牙名称才会更新。

上面说了,一般情况下,JDY31连接上蓝牙之后,STATE会发出高电平,如果我们将这个串口状态输出失能,那么STATE就会和EN一样没有任何用处了。

通过STM32F103对JDY-31使用串口进行AT命令

 接下来的讲解配合下面代码食用。

打开串口没什么可说的,直接复制我之前关于USART的文章的代码即可。

这边为了串口输出方便,我加入了stdio库以及重写了fputc,这是为了能够直接使用printf来进行串口的输出,keil5还需要像下图这样配置。

然后我们需要做的就是直接发送AT指令即可,需要注意的是连续两条指令之间需要延时一段时间,否则JDY31反应不过来(我猜的,总之就是JDY会忽略一些指令)

得到的结果在代码下面的图中。

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include <stdio.h>

//中断函数
void USART1_IRQHandler(void){
    //判断数据接收标志位
    if(SET==USART_GetFlagStatus(USART1,USART_FLAG_RXNE)){
        uint16_t data=USART_ReceiveData(USART1);            //读取出接收的数据
        printf("%c",data);
        USART_ClearITPendingBit(USART1,USART_FLAG_RXNE);    //清除数据接收标志位
    }
}
 
void sendbyte(uint16_t Data){
    //发送数据
    USART_SendData(USART1,Data);
    //等待数据发送完毕
    while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}

//这里重写fputc使得可以直接使用printf对串口进行输出
int fputc(int ch, FILE *f){
    sendbyte(ch);
    return ch;
}
 
int main(void){
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    GPIO_InitTypeDef itd;
    itd.GPIO_Mode=GPIO_Mode_AF_PP;      //复用推挽输出
    itd.GPIO_Pin=GPIO_Pin_9;            //TX引脚
    itd.GPIO_Speed=GPIO_Speed_2MHz;     //这个随意
    GPIO_Init(GPIOA,&itd);
    itd.GPIO_Mode=GPIO_Mode_IN_FLOATING;//浮空输入
    itd.GPIO_Pin=GPIO_Pin_10;           //RX引脚
    GPIO_Init(GPIOA,&itd);
    
    USART_InitTypeDef uitd;
    uitd.USART_BaudRate=9600;                                       //波特率
    uitd.USART_HardwareFlowControl=USART_HardwareFlowControl_None;  //硬件流控制
    uitd.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;                    //串口模式
    uitd.USART_Parity=USART_Parity_No;                              //校验
    uitd.USART_StopBits=USART_StopBits_1;                           //停止位长度
    uitd.USART_WordLength=USART_WordLength_8b;                      //传输的字长
    USART_Init(USART1,&uitd);
    
    USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);                    //开启USART接收中断
    
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);                 //NVIC中断配置
    NVIC_InitTypeDef nitd;
    nitd.NVIC_IRQChannel=USART1_IRQn;
    nitd.NVIC_IRQChannelCmd=ENABLE;
    nitd.NVIC_IRQChannelPreemptionPriority=2;
    nitd.NVIC_IRQChannelSubPriority=2;
    NVIC_Init(&nitd);
    
    USART_Cmd(USART1,ENABLE);                                       //上电USART
    
    printf("AT+NAME\r\n");      //查询蓝牙名字
    Delay_ms(100);
    printf("AT+LADDR\r\n");     //查询mac地址
    Delay_ms(100);
    printf("AT+BAUD\r\n");      //查询波特率
    Delay_ms(100);
    printf("AT+PIN\r\n");       //查询蓝牙连接密码
    Delay_ms(100);
    printf("AT+ENLOG\r\n");     //查询状态输出使能状态
    Delay_ms(100);
    printf("AT+VERSION\r\n");   //查询版本
    Delay_ms(100);
    printf("AT+NAME<JDY>\r\n"); //更改蓝牙名称,但是反应比较慢,得等一下子才会更新
    
    while(1){
        
    }
}

忽略最后一行,那是蓝牙断开后,JDY发送的。

JDY与手机进行蓝牙通信

其实蓝牙通信听起来挺酷,实际上你手机连上蓝牙之后,所谓蓝牙通信实际上就是利用串口来发送信息。因此我们直接使用printf输出内容就行,然后手机就能收到,不过我们需要使用蓝牙助手才能看得到,我用的是某宝商家提供的,大家随便找一个都行,甚至微信小程序里都有。

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include <stdio.h>

//中断函数
void USART1_IRQHandler(void){
    //判断数据接收标志位
    if(SET==USART_GetFlagStatus(USART1,USART_FLAG_RXNE)){
        uint16_t data=USART_ReceiveData(USART1);            //读取出接收的数据
        printf("%c",data);
        USART_ClearITPendingBit(USART1,USART_FLAG_RXNE);    //清除数据接收标志位
    }
}
 
void sendbyte(uint16_t Data){
    //发送数据
    USART_SendData(USART1,Data);
    //等待数据发送完毕
    while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}

int fputc(int ch, FILE *f){
    sendbyte(ch);
    return ch;
}
 
int main(void){
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    GPIO_InitTypeDef itd;
    itd.GPIO_Mode=GPIO_Mode_AF_PP;      //复用推挽输出
    itd.GPIO_Pin=GPIO_Pin_9;            //TX引脚
    itd.GPIO_Speed=GPIO_Speed_2MHz;     //这个随意
    GPIO_Init(GPIOA,&itd);
    itd.GPIO_Mode=GPIO_Mode_IN_FLOATING;//浮空输入
    itd.GPIO_Pin=GPIO_Pin_10;           //RX引脚
    GPIO_Init(GPIOA,&itd);
    
    USART_InitTypeDef uitd;
    uitd.USART_BaudRate=9600;                                       //波特率
    uitd.USART_HardwareFlowControl=USART_HardwareFlowControl_None;  //硬件流控制
    uitd.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;                    //串口模式
    uitd.USART_Parity=USART_Parity_No;                              //校验
    uitd.USART_StopBits=USART_StopBits_1;                           //停止位长度
    uitd.USART_WordLength=USART_WordLength_8b;                      //传输的字长
    USART_Init(USART1,&uitd);
    
    USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);                    //开启USART接收中断
    
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);                 //NVIC中断配置
    NVIC_InitTypeDef nitd;
    nitd.NVIC_IRQChannel=USART1_IRQn;
    nitd.NVIC_IRQChannelCmd=ENABLE;
    nitd.NVIC_IRQChannelPreemptionPriority=2;
    nitd.NVIC_IRQChannelSubPriority=2;
    NVIC_Init(&nitd);
    
    USART_Cmd(USART1,ENABLE);                                       //上电USART

    while(1){
        printf("Hello World");
        Delay_ms(2000);
    }
}

这是串口助手收到的完整信息,包括了蓝牙的连接到断开。 

这是手机的蓝牙助手里的信息,RX开头的是收到的信息,TX开头的是手机这里发送的。 

资源获取

如果大家想要蓝牙特供版的串口助手以及安卓手机版的蓝牙助手,可以关注我的公众号“折途想要敲代码”回复关键词“蓝牙”即可免费获取。

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

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

相关文章

Modbus网关BL101 既实现Modbus转MQTT,还能当串口服务器使用

随着工业4.0的迅猛发展&#xff0c;人们深刻认识到在工业生产和生活中&#xff0c;实时、可靠、安全的数据传输至关重要。在此背景下&#xff0c;高性能的工业电力数据传输解决方案——协议转换网关应运而生&#xff0c;广泛应用于工业自动化系统、远程监控和物联网应用应用环境…

【江科大】STM32:定时器中断

文章目录 TIM&#xff08;Timer&#xff09;定时器根据复杂度和应用场景分为了高级定时器、通用定时器、基本定时器三种类型基本定时器通用定数器 高级定时器 时钟&#xff08;时钟电路&#xff09;的作用是什么&#xff1a;设置定时器触发中断普通方法&#xff1a;预分频器时序…

架构篇15:高性能数据库集群-分库分表

文章目录 业务分库分表实现方法小结 上篇我们讲了“读写分离”&#xff0c;读写分离分散了数据库读写操作的压力&#xff0c;但没有分散存储压力&#xff0c;当数据量达到千万甚至上亿条的时候&#xff0c;单台数据库服务器的存储能力会成为系统的瓶颈&#xff0c;主要体现在这…

【pdf技巧】PDF文件设置打印限制

想要限制PDF文件的打印功能&#xff0c;想要限制PDF文件打印清晰度&#xff0c;都可以通过设置限制编辑来达到目的。 打开PDF编辑器&#xff0c;找到设置限制编辑的界面&#xff0c;切换到加密状态&#xff0c;然后我们就看到 有印刷许可。勾选【权限密码】输入一个PDF密码&am…

正则表达式、grep过滤工具、sed基本用法、sed基本操作指令、sed应用案例

1 案例1&#xff1a;使用正则表达式 1.1 问题 本案例要求熟悉正则表达式的编写&#xff0c;完成以下任务&#xff1a; 利用grep或egrep工具练习正则表达式的基本用法 1.2 方案 表&#xff0d;1 基本正则列表 表&#xff0d;2 扩展正则列表 1.3 步骤 实现此案例需要按照如…

aiXcoder自动跳出

在使用vscode时突然提示&#xff1a;需登录aixcoder才可以继续使用&#xff1b;如果不登录&#xff0c;一使用vscode就会自动弹出aixcoder试用界面&#xff1a; 试用&#xff1f;后面可能要收取费用&#xff0c;本着白嫖的宗旨思考&#xff1a;那么怎么恢复原来的版本呢&#x…

A 股承担着一个什么功能?

​A 股&#xff1a;中国资本市场的核心角色 A 股&#xff0c;即人民币普通股票&#xff0c;在中国资本市场中扮演着至关重要的角色。它不仅是投资者买卖交易的场所&#xff0c;更是中国经济发展的重要引擎。 首先&#xff0c;A 股为中国的企业提供了融资平台。中国有着庞大的…

天天酷跑-C语言搭建童年游戏(easyx)

游戏索引 游戏名称&#xff1a;天天酷跑 游戏介绍&#xff1a; 本游戏是在B站博主<程序员Rock>的视频指导下完成 想学的更详细的小伙伴可以移步到<程序员Rock>视频 【程序员Rock】C语言项目&#xff1a;手写天天酷跑丨大一课程设计首选项目&#xff0c;手把手带你用…

Web安全漏洞专项靶场—SQL注入—docker环境—sqli-labs靶场—详细通关指南

SQL注入—sqli-labs靶场 零、前言一、环境搭建①、VirtualBox②、Kali Linux③、Docker 二、闯关开始1、Less-1——union2、Less-2—数字型—union3、Less-3—)—union4、Less-4—")—union5、Less-5——布尔盲注6、Less-6—"—布尔盲注7、Less-7—))7.1—布尔盲注7.…

Git学习笔记(第8章):IEAD实现GitHub操作(VSCode)

目录 8.1 VSCode登录GitHub账号 8.2 创建远程库 8.3 本地库推送到远程库(push) 8.4 远程库拉取到本地库(pull) 8.5 远程库克隆到本地库(clone) 8.1 VSCode登录GitHub账号 Step1&#xff1a;安装“GitHub Pull Requests and Issues”插件 Step2&#xff1a;登录GitHub账号 …

加密项目调研的评估框架

当谈到加密货币时&#xff0c;您在决定是否投资之前需要考虑几个关键因素。无论您是刚刚开始接触新的加密项目还是正在寻求扩展您的投资组合&#xff0c;拥有一个方便的加密项目评估框架都会很有帮助。 本文将解释一个分步框架&#xff0c;以帮助您评估各种加密项目。 您如何…

Kubernetes的ConfigMap

文章目录 环境概念配置pod使用ConfigMap创建ConfigMapkubectl create configmap目录文件自定义key值literal值 产生器&#xff08;generator&#xff09;文件自定义key值literal值 定义容器环境变量单个ConfigMap多个ConfigMap 配置ConfigMap里所有键值对为环境变量在pod命令里…

透明拼接屏在汽车领域的应用

随着科技的进步&#xff0c;透明拼接屏作为一种新型的显示技术&#xff0c;在汽车领域的应用越来越广泛。尼伽小编将围绕透明拼接屏在汽车本身、4S店、展会、工厂等方面的应用进行深入探讨&#xff0c;并展望未来的设计方向。 一、透明拼接屏在汽车本身的应用 车窗显示&#x…

JeecgBoot 3.6.1使用Online表单开发生成代码,如何定义自定义查询条件

一、使用Online表单生成代码&#xff0c;运行结果如下 二、如果我们想要加入一些筛选条件&#xff0c;例如用姓名查询 1.可在生成的前端代码中加入如下代码&#xff0c;文件为****data.ts //查询数据 export const searchFormSchema: FormSchema[] [ ];2.对如上代码进行编辑…

3D应用开发工具HOOPS引领数字化工厂浪潮:制造业转型的关键角色!

随着科技的迅猛发展&#xff0c;制造业正经历着数字化转型的浪潮。在这一变革的前沿&#xff0c;Tech Soft 3D 的 HOOPS技术正扮演着关键的角色。 本文将深入研究HOOPS技术如何在数字化工作流程中发挥作用&#xff0c;以及它是如何引领制造业朝着更高效、智能的未来迈进的。 …

【C语言进阶】预处理详解

引言 对预处理的相关知识进行详细的介绍 ✨ 猪巴戒&#xff1a;个人主页✨ 所属专栏&#xff1a;《C语言进阶》 &#x1f388;跟着猪巴戒&#xff0c;一起学习C语言&#x1f388; 目录 引言 预定义符号 #define定义常量 #define定义宏 带有副作用的宏参数 宏替换的规则 …

空气净化器or宠物空气净化器?五款猫用空气净化器优质推荐!

作为一个养猫家庭的主人&#xff0c;每天都要面对清理猫砂盘的挑战&#xff0c;这种令人难以形容的气味实在让人难以忍受。尤其是家里有小孩和老人&#xff0c;他们可能会出现过敏性鼻炎等问题&#xff0c;而抵抗力较差的人更容易受到影响。此外&#xff0c;换毛季节到来时&…

Qt 拖拽事件示例

一、引子 拖拽这个动作,在桌面应用程序中是非常实用和具有很友好的交互体验的。我们常见的譬如有,将文件拖拽到某个窗口打开,或者拖拽文件到指定位置上传;在绘图软件中,选中某个模板、并拖拽到画布上,画布上变回绘制该模板的图像… 诸如此类,数不胜数。 那么,在Qt中我…

【MySQL】最左匹配原则

最左匹配原则 0x1 简单说下什么是最左匹配原则 顾名思义&#xff1a;最左优先&#xff0c;以最左边的为起点任何连续的索引都能匹配上。同时遇到范围查询(>、<、between、like&#xff09;就会停止匹配。 例如&#xff1a;b 2 如果建立(a&#xff0c;b&#xff09;顺序…

远程桌面--虚拟机与主机的文件传输

注意&#xff1a; 确保VMware开头的服务全部在运行进入虚拟机打开文件管理器点击计算机右键选择属性在选择远程管理选择允许 1.winR 输入mstsc 2.输入虚拟机的ip地址 2.输入虚拟机的密码 上面的Administrator是虚拟机的用户名&#xff0c;有时会需要我们手动输入 3.验证…