0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

第五章-V1.5 HC05蓝牙模块使用 STM32串口接受中断 HC05蓝牙模块连手机

STM32智能小车V1.5 来源:dfhjgfg 作者:dfhjgfg 2024-08-15 16:22 次阅读

功能介绍放开头, 使用便捷无需愁。

这是全网最详细、性价比最高的STM32实战项目入门教程,通过合理的硬件设计和详细的视频笔记介绍,硬件使用STM32F103主控资料多方便学习,通过3万字笔记、12多个小时视频、20多章节代码手把手教会你如何开发和调试。让你更快掌握嵌入式系统开发。

V1.5.0-STM32智能小车

V1.5.0:库函数开发。功能:循迹、避障、跟随、遥控、电池电压显示等。

视频合集链接推荐观看

[https://www.bilibili.com/video/BV1SY411L7rJ/?spm_id_from=333.337.search-card.all.click]

**V3.3.0-STM32智能小车 **

V3:HAL库开发、功能:PID速度控制、PID循迹、PID跟随、遥控、避障、PID角度控制、视觉控制、电磁循迹、RTOS等功能。

视频合集链接推荐观看

[https://www.bilibili.com/video/BV16x4y1M7EN/?spm_id_from=333.337.search-card.all.click]

串口接收发送

STM32串口初始化

这里先初始化使用串口1

//串口1中断服务程序
//注意,读取USARTx- >SR能避免莫名其妙的错误
u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.
//接收状态
//bit15, 接收完成标志
//bit14, 接收到0x0d
//bit13~0, 接收到的有效字节数目
u16 USART_RX_STA=0; //接收状态标记
void uart_init(u32 bound){
//GPIO端口设置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);
//使能USART1,GPIOA时钟
//USART1_TX GPIOA.9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
//USART1_RX GPIOA.10初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10
//Usart1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
//USART 初始化设置
USART_InitStructure.USART_BaudRate = bound;//串口波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
USART_InitStructure.USART_HardwareFlowControl =
USART_HardwareFlowControl_None;//无硬件数据流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
USART_Init(USART1, &USART_InitStructure); //初始化串口1
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断
USART_Cmd(USART1, ENABLE); //使能串口1
}

在main中定义标志位

int g_USART1_FLAG1 = 0; //串口控制标志位

在usart.h中声明变量

extern int g_USART1_FLAG1 ;

在中断服务函数添加处理

void USART1_IRQHandler(void) //串口1中断服务程序
{
u8 Res;
#if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
OSIntEnter();
#endif
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必
须是0x0d 0x0a结尾)
{
Res =USART_ReceiveData(USART1); //读取接收到的数据
if(Res == 'A') g_USART1_FLAG1 = 1 ; //根据接受的数据 置为标志位
if(Res == 'B')g_USART1_FLAG1 = 2 ;
if((USART_RX_STA&0x8000)==0)//接收未完成
{
if(USART_RX_STA&0x4000)//接收到了0x0d
{
if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
else USART_RX_STA|=0x8000; //接收完成了
}
else //还没收到0X0D
{
if(Res==0x0d)USART_RX_STA|=0x4000;
else
{
USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
USART_RX_STA++;
if(USART_RX_STA >(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错
误,重新开始接收
}
}
}
}
#if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
OSIntExit();
#endif
}

调用初始化函数

uart_init(115200); //串口初始化为115200

在main.c 的逻辑

while(1)
{
//串口
if(g_USART1_FLAG1 == 1){
LED =! LED;
}
if(g_USART3_FLAG1 == 2) {
LED =! LED;
}
}
​

测试单片机串口

TTL与单片机连接
在这里插入图片描述
TTL插入电脑,使用串口助手->选择端口->更改波特率115200->发送数据
在这里插入图片描述
现象 发送A 或B 可以使小灯反转、发送其他命令无现象。

配置蓝牙

更改蓝牙波特率
见硬件蓝牙介绍
我们在AT模式下设置发送AT指令:AT+UART=115200,0,0
在这里插入图片描述

测试蓝牙

断电重启蓝牙,更改软件波特率为115200,打开手机蓝牙与HC-05配对 (密码:1234)
使用蓝牙调试器(应用商店下载即可),发送aa 观察电脑串口软件
在这里插入图片描述
手机APP-蓝牙调试器的设置方法
调试成功 :蓝牙软件和串口软件能够通讯
在这里插入图片描述

练一练--蓝牙控制小灯

连接如图
在这里插入图片描述
通过发送A或者B 控制单片机小灯反转
那么上面我们就完成了蓝牙的基本控制
然后我们就可以蓝牙反转灯的时候控制小车前行停止

//串口
if(g_USART1_FLAG1 == 1){
g_USART1_FLAG1 = 0;
//左电机慢速正转
AIN1=0;
AIN2=1;
TIM_SetCompare4(TIM1,1700); //设置
//右边电机慢速执行
BIN1 =1;
BIN2 =0;
TIM_SetCompare1(TIM1,1700);
LED =! LED;
}
if(g_USART1_FLAG1 == 2) {
g_USART1_FLAG1 = 0;
//双电机停止
BIN1 = 0;
BIN2 = 0;
AIN1 = 0;
AIN2 =0;
LED =! LED;
}

上面是通过串口一(PA9 PA10)
蓝牙硬件是串口三(PB10 PB11)下面我们通过串口三实现
初始化使用串口3

//初始化串口3
void uart_init_3(u32 bound){
//GPIO端口设置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); //使能USART3
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); //,GPIOB时钟
//USART3_TX GPIOB.10
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PB.10
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB.10
//USART3_RX GPIOB.11初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;//PB11
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB.11
//Usart3 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
//USART 初始化设置
USART_InitStructure.USART_BaudRate = bound;//串口波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
USART_InitStructure.USART_HardwareFlowControl =
USART_HardwareFlowControl_None;//无硬件数据流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
USART_Init(USART3, &USART_InitStructure); //初始化串口3
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//开启串口接受中断
USART_Cmd(USART3, ENABLE); //使能串口3
}

在main中定义标志位

int g_USART3_FLAG1 = 0; //串口3控制标志位

在usart.h中声明变量

extern int g_USART3_FLAG1 ;

在中断服务函数添加处理

//串口3 中断处理函数
void USART3_IRQHandler (void)
{
u8 Res;
if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
{
Res =USART_ReceiveData(USART3); //读取接收到的数据
if(Res == 'A') g_USART3_FLAG1 = 1 ; //根据接受的数据 置为标志位
if(Res == 'B')g_USART3_FLAG1 = 2 ;
}
}

调用初始化函数

uart_init_3(115200); //初始化串口3

在main.c 编写逻辑

while(1)
{
//串口
if(g_USART3_FLAG1 == 1){
g_USART3_FLAG1 = 0;
//左电机慢速正转
AIN1=0;
AIN2=1;
TIM_SetCompare4(TIM1,1700); //设置
//右边电机慢速执行
BIN1 =1;
BIN2 =0;
TIM_SetCompare1(TIM1,1700);
LED =! LED;
}
if(g_USART3_FLAG1 == 2) {
g_USART3_FLAG1 = 0;
//双电机停止
BIN1 = 0;
BIN2 = 0;
AIN1 = 0;
AIN2 =0;
LED =! LED;
}
}

把蓝牙安装顺序连接到STM32
跳线帽改至蓝牙
在这里插入图片描述
手机连接蓝牙 使用蓝牙调试器发送 A 或者 B
现象:发送A 小车直行、发送B小车停止。

练一练--蓝牙控制小车运动

USART中断服务函数

//串口3 中断处理函数
void USART3_IRQHandler (void)
{
u8 Res;
if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
{
Res =USART_ReceiveData(USART3); //读取接收到的数据
if(Res == 'A') g_USART3_FLAG1 = 1 ; //根据接受的数据 置为标志位
if(Res == 'B')g_USART3_FLAG1 = 2 ;
if(Res == 'C') g_USART3_FLAG1 = 3 ; //根据接受的数据 置为标志位
if(Res == 'D')g_USART3_FLAG1 = 4 ;
if(Res == 'E')g_USART3_FLAG1 = 5;
}
}

main 中的逻辑

while(1)
{
if(g_USART3_FLAG1 == 1) //前进
{
g_USART3_FLAG1=0;
Forward();
delay_ms(500);
}
if(g_USART3_FLAG1 == 2) //向右
{
g_USART3_FLAG1=0;
Rightward();
delay_ms(500);
}
if(g_USART3_FLAG1 ==3) //向左
{
g_USART3_FLAG1=0;
Leftward();
delay_ms(500);
}
if(g_USART3_FLAG1 ==4) //向后
{
g_USART3_FLAG1=0;
Backward();
delay_ms(500);
}
if(g_USART3_FLAG1 ==5) //停止
{
g_USART3_FLAG1=0;
AIN1=0;
AIN2=0;
BIN1=0;
BIN2=0;
delay_ms(500);
}
}

手机中蓝牙调试助手的设计
在这里插入图片描述

练一练--把数据发送给电脑串口助手和手机APP

前面我们介绍了,如何通过电脑或者蓝牙APP,向单片机发送数据,下面我们介绍如何:单片机如何向
电脑和蓝牙APP发送数据。
库函数提供了相关串口函数,但是每次只能发送一个字节

USART_SendData(USART1,'X');//通过库函数发送字节数据
while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET);//判断发送标志位,是否发送
结束

在正点原子例程中完成了对printf的重映射,所以我们可以轻松的通过printf ()函数向串口1 发送不定长
数据,这是正点原子的例程

struct __FILE
{
int handle;
};
FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
void _sys_exit(int x)
{
x = x;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{
while((USART1- >SR&0X40)==0);//循环发送,直到发送完毕 通过SR寄存器判断是否发送完成
USART1- >DR = (u8) ch; //通过DR寄存器发送数据
return ch;
}

那么我们如何实现任意串口都可以任性发送那?
这里我们使用vsprintf 格式化字符串来完成
需要包含的头文件

#include "stdarg.h"
void UsartPrintf(USART_TypeDef * USARTx,char * fmt ,...)
{
unsigned char UsartPrintfBuf[256]; //定义一个字符串数组
va_list ap;//初始化指向参数列表的指针
unsigned char *pStr = UsartPrintfBuf; //指针指向数组首地址
va_start(ap,fmt);//将第一个可变参数的地址付给ap,即ap 指向可变参数列表的开始
vsprintf((char *)UsartPrintfBuf, fmt,ap);
//将参数fmt、ap 指向的可变参数一起转化成格式化字符串,放string数组中,作用同sprintf
(),只是参数类型不同
va_end(ap); //清除指针
while(*pStr != 0) //判断是否发送完字符串
{
//while(USART_GetFlagStatus(USART3,USART_FLAG_TC == RESET));//判断发送标志
位,是否发送结束
USART_SendData(USARTx,*pStr++);//通过库函数发送字符串
//pStr ++;
while(USART_GetFlagStatus(USARTx,USART_FLAG_TC) == RESET);//判断发送标志
位,是否发送结束
}
}

参考资料
在main 中调用函数

UsartPrintf(USART3,"Distance:%dMode:%d",TCRT5000_Dist(),Mode);

在手机APP显示数据
在这里插入图片描述

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • STM32
    +关注

    关注

    2270

    文章

    10900

    浏览量

    356012
  • 串口
    +关注

    关注

    14

    文章

    1554

    浏览量

    76517
  • HC05
    +关注

    关注

    2

    文章

    28

    浏览量

    26221
  • 蓝牙模块
    +关注

    关注

    30

    文章

    575

    浏览量

    55738
收藏 人收藏

    评论

    相关推荐

    请问安卓手机怎么与HC05蓝牙模块通信?

    最近公司的产品想使用手机蓝牙STM32芯片通信,购买了HC05蓝牙模块,用资料里面的
    发表于 05-08 23:02

    hc05蓝牙模块串口使用stm32

    hc05蓝牙模块串口使用stm32hc05蓝牙.rar (2.59 MB )
    发表于 05-20 22:15

    蓝牙HC05是什么

    stm 32 串口通信蓝牙篇1. HC-05蓝牙1.1蓝牙模块使用介绍
    发表于 08-11 09:29

    蓝牙HC05是什么?hc05蓝牙模块如何使用

    蓝牙HC05是主从一体的蓝牙串口模块,简单的说,当蓝牙设备与
    发表于 01-11 07:46

    stm32f407Zgt6与hc05蓝牙模块通信步骤

    stm32f407Zgt6 与 hc05蓝牙模块通信步骤stm32f407Zgt6串口配置
    发表于 03-02 07:08

    蓝牙HC05资料

    蓝牙HC05资料
    发表于 12-19 14:01 100次下载

    串口蓝牙模块HC05资料

    串口蓝牙模块HC05资料
    发表于 11-29 16:33 75次下载

    hc05hc06有什么不同_hc05hc06区别

    hc05hc06是两种蓝牙串口模块,两者经常被拿来比较,他们之间有何区别呢?
    发表于 01-11 15:51 7.8w次阅读
    <b class='flag-5'>hc05</b>和<b class='flag-5'>hc</b>06有什么不同_<b class='flag-5'>hc05</b>和<b class='flag-5'>hc</b>06区别

    hc05蓝牙模块如何使用_两个hc05蓝牙模块配对

    蓝牙HC05是主从一体的蓝牙串口模块,简单的说,当蓝牙设备与
    发表于 01-11 16:09 11.1w次阅读

    HC05蓝牙串口模块的原理图和源代码配套软件及实验说明

    本文档的主要内容详细介绍的是HC05蓝牙串口模块的原理图和源代码配套软件及实验说明包括了:ATK-HC05
    发表于 03-18 08:00 155次下载
    <b class='flag-5'>HC05</b><b class='flag-5'>蓝牙</b><b class='flag-5'>串口</b><b class='flag-5'>模块</b>的原理图和源代码配套软件及实验说明

    嵌入式单片机基础篇(二十八)之蓝牙模块HC05与BT05 AT指令

    蓝牙模块HC05与BT05 AT指令1、HC05:2、BT05
    发表于 11-24 12:06 23次下载
    嵌入式单片机基础篇(二十八)之<b class='flag-5'>蓝牙</b><b class='flag-5'>模块</b><b class='flag-5'>HC05</b>与BT<b class='flag-5'>05</b> AT指令

    HC05 蓝牙模块 连接 ESP32 经典蓝牙

    概述HC05是一款常用的经典蓝牙模块,某宝有大量销售,主从机一体,而ESP32的蓝牙兼容经典蓝牙和低功耗
    发表于 11-24 12:36 65次下载
    <b class='flag-5'>HC05</b> <b class='flag-5'>蓝牙</b><b class='flag-5'>模块</b> 连接 ESP32 经典<b class='flag-5'>蓝牙</b>

    HC05STM32进行串口通讯实现与手机APP的数据透传

    HC05STM32手机透传1.实验工具:正点原子的精英版STM32F103ZET6,通用BLE蓝牙
    发表于 12-24 18:54 55次下载
    <b class='flag-5'>HC05</b>与<b class='flag-5'>STM32</b>进行<b class='flag-5'>串口</b>通讯实现与<b class='flag-5'>手机</b>APP的数据透传

    STM32 + HC05串口蓝牙设计简易的蓝牙音箱

    Android手机打开APP,设置好参数之后,选择音乐文件发送给蓝牙音箱设备端,HC05蓝牙收到数据之后,再传递给VS1053进行播放。程序里采用环形缓冲区,接收
    的头像 发表于 02-28 13:59 8781次阅读
    <b class='flag-5'>STM32</b> + <b class='flag-5'>HC05</b><b class='flag-5'>串口</b><b class='flag-5'>蓝牙</b>设计简易的<b class='flag-5'>蓝牙</b>音箱

    HC05蓝牙模块编程实例

    今天分享一个实践项目——HC05蓝牙模块的编程。
    的头像 发表于 05-26 16:01 3574次阅读
    <b class='flag-5'>HC05</b><b class='flag-5'>蓝牙</b><b class='flag-5'>模块</b>编程实例