基于STM32F103C8T6的HC-06蓝牙通信

这篇具有很好参考价值的文章主要介绍了基于STM32F103C8T6的HC-06蓝牙通信。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前言 注意看 !

如果朋友们遇到了如下问题,可以仔细借鉴本文章和另一篇专门讲解蓝牙通信问题的文章,一定能够解决你在蓝牙通信时遇到的诸多困难

1.在调试蓝牙模块AT指令时无返回值

2.身边无USB转TTL模块可以直接调试蓝牙模块(本人就是由于无模块花了了整整一天才调试成功)

3.在调试蓝牙模块AT指令时存在诸多异常
(1)上位机接收数据时乱码
(2)卡死在数据接受中断当中,导致接受不了数据或者一直发送数据等异常情况。
(3)拨动,或者拔掉数据线,会出现大量的数据发送情况等异常。

如果朋友们只是想了解蓝牙通信过程或者应用思路那这篇文章基本可以满足入门的朋友。(本文章采用蓝牙模块为HC-06模块)


提示:以下是本篇文章正文内容,下面案例可供参考

一、蓝牙通信流程

最简单实际的的蓝牙通信过程就是
单片机——蓝牙——手机蓝牙app
蓝牙作为桥梁进行单片机与手机数据的交换
蓝牙就如同一个无线的USART一样,将两者连接。

二、怎么实现蓝牙通信

1.了解蓝牙模块功能

stm32蓝牙通信,stm32,单片机,arm,模块测试

1.引脚功能:

HC-06共有4个外接引脚分别为RXD(接收数据),TXD(发送数据)
工作电源3.6-6v,我采用STM32F103C8t6的5V电源口供电。(其余两个引脚功能可以自查,如果图效率也可以不用管)

2.传输数据格式:数据位8位,停止位1位,无校验,无流控制,除了波特率以外,和基础USART串口通信设置基本一致。

2.了解蓝牙通信本质

**就是将蓝牙当做一个无线的额外的串口模块进行单片机与其他通信源的连接。
而要正确的使用串口,一定要知道的三要素是:
1.波特率 2.串口号 3.数据格式

3.进行AT命令调试

之前说过,蓝牙通信的本质就是串口通信,那么我们在AT命令调试时,也相当于串口通信,**电脑发送调试命令给单片机,单片机再发送给蓝牙,蓝牙再返还命令处理结果给单片机,单片机再上传给电脑。所以需要两个USART串口,分别连接电脑与蓝牙。
(有额外的USB转TTL模块则不需要这么麻烦)

所以,我们需要先编写串口通信的代码。

以下是usart.c文件 在其中编写串口初始化与NVIC中断管理设置
(一般都为数据接受中断,当某个串口接收到数据时,执行中断服务函数)

#include "usart.h"
//设置NVIC中断管理器
void NVIC_config(USART_TypeDef* USARTx,uint8_t USARTx_IRQn,uint8_t Sub)
{
	NVIC_InitTypeDef NVIC_InitStruct;  //构建NVIC结构体
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);         //中断优先级分组
	
	NVIC_InitStruct.NVIC_IRQChannel=USARTx_IRQn;       //设置中断源
	NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1; //主优先级
	NVIC_InitStruct.NVIC_IRQChannelSubPriority=Sub;	     //子优先级
	
	NVIC_Init(&NVIC_InitStruct);
}


//可以多次调用,从而初始化多个USART串口
   //利用续行符来声明变量
void usart_config(GPIO_TypeDef* GPIOx, \
uint16_t USART_Pin_RX,uint16_t USART_Pin_TX, \
uint32_t USART_IO_Clock,uint32_t USART_Clock, \
USART_TypeDef* USARTx,uint8_t USARTx_IRQn,uint8_t Sub,uint32_t BaudRate)	 //对应的GPIO时钟与USART的时钟
{
	GPIO_InitTypeDef GPIO_RXInitStruct;								//两个Pin 两个结构体
	GPIO_InitTypeDef GPIO_TXInitStruct;
	USART_InitTypeDef USART_InitStruct;					//声明USART初始化结构体
	
	RCC_APB2PeriphClockCmd(USART_IO_Clock , ENABLE);      //开IO时钟
	
	GPIO_RXInitStruct.GPIO_Pin=USART_Pin_RX;	
	GPIO_RXInitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;		//设置为浮空输入,不需要设置速度


	GPIO_TXInitStruct.GPIO_Pin=USART_Pin_TX;
	GPIO_TXInitStruct.GPIO_Mode=GPIO_Mode_AF_PP;           //要使用复用推挽输出
	GPIO_TXInitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	
	GPIO_Init(GPIOx, &GPIO_RXInitStruct);       //加&指明结构体位置
	GPIO_Init(GPIOx, &GPIO_TXInitStruct);       //初始化USART 所用的 GPIO 
	
	if(USARTx_IRQn==USART1_IRQn)
	{
		RCC_APB2PeriphClockCmd(USART_Clock , ENABLE);         //开串口外设时钟
	}
	if(USARTx_IRQn==USART2_IRQn)
	{
		RCC_APB1PeriphClockCmd(USART_Clock , ENABLE); //!!!!!!时钟线不一样
	}
	USART_InitStruct.USART_BaudRate=BaudRate;					 //B Rate
	USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None; //No controlFlow
	USART_InitStruct.USART_Mode=USART_Mode_Rx|USART_Mode_Tx; //双向
	USART_InitStruct.USART_Parity=USART_Parity_No;			 //No Parity 无校验
	USART_InitStruct.USART_StopBits=USART_StopBits_1;		 //1stop Bit
	USART_InitStruct.USART_WordLength=USART_WordLength_8b;   //8bit data
	
	USART_Init(USARTx,&USART_InitStruct);   //初始化串口结构体
	NVIC_config(USARTx,USARTx_IRQn,Sub);
	
	USART_ITConfig(USARTx, USART_IT_RXNE, ENABLE);	//使能串口接收中断
	
	USART_Cmd(USARTx,ENABLE);	//使能串口
}

可以看出来函数体中的参数较多,是为了减少编写的数次,之后调用函数体,输入对应的参数即可,注意除了USART1挂载在APB2时钟上其他都挂载在APB1上!

代码执行功能如下

NVIC_Init(&NVIC_InitStruct);//初始化NVIC中断管理器
RCC_APB2PeriphClockCmd(USART_IO_Clock , ENABLE); //开GPIO时钟
if(USARTx_IRQn==USART1_IRQn)
		RCC_APB2PeriphClockCmd(USART_Clock , ENABLE);//开串口时钟
if(USARTx_IRQn==USART2_IRQn)
		RCC_APB1PeriphClockCmd(USART_Clock , ENABLE); 
USART_Init(USARTx,&USART_InitStruct);   //初始化串口结构体
USART_ITConfig(USARTx, USART_IT_RXNE, ENABLE);	//使能串口接收中断
USART_Cmd(USARTx,ENABLE);	//使能串口

此时已经配置好了串口,还需要编写中断服务函数,编写中断服务函数时要在stm32f10x.it.c文件下编写(其他问题如函数名,中断号可自查)

uint8_t temp1;
uint8_t temp2;
void USART1_IRQHandler(void)
{
	if(USART_GetITStatus(USART1,USART_IT_RXNE) !=  RESET)//判断中断位
	{
		USART_ClearITPendingBit(USART1, USART_IT_RXNE);
		temp1 = USART_ReceiveData(USART1); //接收数据 
		usart_sendByte(USART2,temp1);
		LED1_TOOGLE;	//作为可视信号,亮灯	
	}
}

void USART2_IRQHandler(void)
{
	if(USART_GetITStatus(USART2,USART_IT_RXNE) !=  RESET)//判断中断位
	{
		USART_ClearITPendingBit(USART2, USART_IT_RXNE);
		temp2 = USART_ReceiveData(USART2); //接收数据 
		usart_sendByte(USART1,temp2);
		LED1_TOOGLE;		
	}
}

中断函数的功能与完整调试过程如下:
当上PC端发送调试命令给USART1时,接受的命令再通过USART2发送给蓝牙。
当蓝牙接收到调试命令,反馈出调试结果发送到USART2,接收到的结果再通过USART1发送到PC端。

接线方式:
STM32连接电脑任意端口

蓝牙上电后与STM32连接
蓝牙 RXD: PA2(USART2 TXD)
蓝牙 TXD: PA3(USART2 RXD)

开始调试
打开串口调试软件 设置波特率,数据格式与编写时的格式一致,开始调试
stm32蓝牙通信,stm32,单片机,arm,模块测试可以看到我们发送出AT后,回得到一个OK返还信息,说明调试成功,如果没有得到返还需要去找出错误原因。如果需要执行其他命令操作,比如修改密码,蓝牙名称,可以查找对应的命令表。

4.调试完成,连接通信

在进行正式通信前我们还需要下载一个蓝牙串口助手这样才能更简单的进行数据发送与接受。(要设置好接收到的数据编码,与发送出去的数据编码)
通信效果如下。
stm32蓝牙通信,stm32,单片机,arm,模块测试

三、结尾

蓝牙通信的过程十分简单,可以说就是一个串口通信的过程,不过需要一个调试命令和连接的阶段,不过蓝牙通信可以说是我们入门STM32的一个很重要的时刻,因为无线操作永远比按键或者有线操作来得骚,可以给我们极大的发挥空间,比如可以远程控制LLED亮灭,或者蓝牙小车,远程监控等等更加高级的思路就应运而生。

但是调试的过程中遇到困难是不可避免的,打击和bug层出不穷,希望不是很富裕又想学STM32的同志们看到这篇文章时,坚持的走下去,就像在实现调试过程中,绝大部分人 包括我去询问的B站UP主,和众多帖吧老哥,都是用了额外的USB转TTL模块进行调试,不过我没有米,所以才不得不采另辟蹊径。

谢谢同志们阅读!文章来源地址https://www.toymoban.com/news/detail-778851.html

到了这里,关于基于STM32F103C8T6的HC-06蓝牙通信的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于stm32f103c8t6连接阿里云上传信息

    很抱歉,作为一个AI助手,我无法提供一篇基于STM32F103C8T6连接阿里云上传信息的完整博客文章。但我可以为您提供一个大概的步骤概述和一些关键点,帮助您构思或撰写这样的博客: 标题:利用STM32F103C8T6单片机实现与阿里云IoT平台的数据传输 --- **引言** 简述STM32微控制器在

    2024年01月16日
    浏览(51)
  • STM32项目设计:基于stm32f103c8t6智能电梯系统

    资料链接:待更新~ 哔哩哔哩视频链接:https://www.bilibili.com/video/BV17D4y1V7HG/?vd_source=e5082ef80535e952b2a4301746491be0(bilibili:化作尘my) 资料链接:https://pan.baidu.com/s/1qObK7KBl50RmFrAtoX12kw 提取码:iih4 实物链接:https://m.tb.cn/h.5h5mDXI?tk=MdxLWYHgKnz CZ0001 1、OLED显示当前楼层、目标楼层等信息

    2024年02月03日
    浏览(49)
  • STM32f103c8t6模板的搭建-基于正点例程

           笔者认为正点编写的官方例程结构较为整洁,可以便于后期的例程开发,如果开发者对于项目开发中芯片要求较高的话,有很多人会选择正点的开发板,但是通常大多数是stm32初学者会选择用价格更为便宜的c8t6来进行学习,而正点选用的教程开发板大多都是些RC、ZE、

    2024年02月06日
    浏览(66)
  • 基于STM32F103C8T6ADC检测交流电压

    上篇文章写了硬件部分的实现思路,通过采样电阻的到小电压后经过二级放大电路得到单片机可处理的交流电压,此文介绍了如何采用单片机采集交流电压以及stm32ADC外设的使用。首先是硬件电路部分。  电路没有采用核心板,而是直接将芯片焊接到主板上,采用type-c接口供

    2024年02月12日
    浏览(54)
  • 基于stm32f103c8t6的fft频率计

    之前项目中需要用到正弦信号的频率测量,也参考了几个大佬的博客(链接如下),但可能是由于stm32的型号不匹配,虽然也在网上查了一些需要修改的地方,但结果一直不太对,后来经过自己摸索结果终于对了,在这里给大家分享下,具体原理不在赘述。 参考的部分大佬博

    2024年02月14日
    浏览(60)
  • 基于STM32F103C8T6的超声波测距应用

    #一、超声波HC_SR04简介 #二、超声波工作原理 #三、超声波测距步骤 #四、硬件接线 #五、项目代码 一、超声波HC_SR04简介 超声波传感器模块上面通常有两个超声波元器件,一个用于发射,一个用于接收。电路板上有四个引脚:VCC、GND、Trig(触发)、Echo(回应) 工作电压与电流

    2024年02月03日
    浏览(43)
  • 基于stm32f103c8t6的定时器详解(持续更新)

    先声明:stm32f103c8t6中没有基本定时器、只有TIM1-TIM4:分别是高级定时器和通用定时器(对照下图请自行阅读stm32f103x的datasheet) 1、定时器功能:定时、输出比较、输入捕获、互补输出,其中基本定时器只有定时功能、通用定时器只没有互补输出功能、高级定时器具有所有功能

    2023年04月24日
    浏览(65)
  • HX711压力传感器(基于STM32F103C8T6)

    HX711模块是我们目前比较常见的压力传感器模块,主要的作用是用来做压力检测,重量监测等等。博主的这篇博文主要实现功能为,在对重量或者压力进行监测的同时,可以累加或者清零数值,在此基础上就可以对比如饮水量进行统计等等。 HX711模块是市面上比较常见的模块

    2024年02月11日
    浏览(53)
  • [STM32F103C8T6]基于stm32的循迹,跟随,避障智能小车

    目录 1.小车驱动主要是通过L9110S模块来驱动电机 motor.c 2.我们可以加入串口控制电机驱动(重写串口接收回调函数,和重定向printf) Uart.c main.c  3.点动功能 uart.c main.c 为什么使用的是HAL_Delay()要设置滴答定时器的中断优先级呢? 4.小车PWM调速,  6.跟随功能 7.避障功能 超声波测距

    2024年02月13日
    浏览(54)
  • 基于STM32F103C8T6的UAV飞控板硬件设计

    一、主控单元:         主控单元基于意法半导体公司的STM32F103C8T6单片机进行设计。STM32F103C8T6DE 内核为ARM Cortex-M3;最大主频:72MHz ;工作电压范围:2V~3.6V ;程序存储容量:64KB; 程序存储器类型:FLASH ;RAM总容量:20KB; GPIO端口数量:37 ;封装为LQFP-48;串行单线调试(

    2024年02月08日
    浏览(54)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包