【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开头的是手机这里发送的。 

资源获取

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

  • 33
    点赞
  • 165
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用STM32开发板驱动JDY-31蓝牙模块遥控小车需要以下步骤: 1. 硬件连接:将JDY-31蓝牙模块STM32开发板连接。通常使用UART串口进行通信,将蓝牙模块的TX端口连接到STM32的RX端口,将蓝牙模块的RX端口连接到STM32的TX端口,并共享GND接地。 2. 确定通信参数:查找JDY-31蓝牙模块的数据手册,了解其通信协议和默认的波特率等参数。根据手册设置STM32的串口通信参数,包括波特率、数据位、停止位等。 3. 初始化串口:在STM32的代码中,初始化所使用的串口,使其与蓝牙模块相匹配。这涉及到设置串口的GPIO引脚、中断、波特率等。 4. 接收蓝牙数据:通过串口中断接收来自蓝牙模块的数据。当蓝牙模块发送数据时,STM32的串口接收中断会被触发,并将接收到的数据存储在指定的缓冲区中。 5. 解析和处理数据:根据JDY-31蓝牙模块的通信协议,解析收到的数据。根据协议定义的格式,提取出需要的指令和数据,例如前进、后退、转弯、停止等。 6. 控制小车:根据解析得到的指令和数据,控制小车的动作。通过驱动小车电机,控制其前进、后退、转弯等行为。 7. 反馈状态:根据实际情况,将小车的状态反馈给蓝牙模块。例如,可以通过蓝牙模块将小车的电量、速度等信息发送回手机或其他终端。 以上是使用STM32驱动JDY-31蓝牙模块遥控小车的基本步骤。具体实现上可能会有一些细节和特定的代码逻辑,具体根据实际情况进行修改和调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值