jjzjj

基于STM32的双蓝牙通信

小鱼有点咸 2023-04-12 原文

首先我们应该让两个蓝牙间互相通信

1.准备两个蓝牙模块(主从一体),用USB转TTL连接到电脑,再打开两个串口分别连接两个蓝牙模块,上电同时按住蓝牙上的按键进入AT指令模式(指示灯慢闪),波特率设置为38400,发送AT 返回ok

2.在串口1中

发送AT+ORGL,恢复1的默认设置 返回ok

发送AT+ROLE=1,设置为主模式 返回ok

发送AT+PSWD="1234"(随便设置),设置密码

发送AT+UART=115200,0,0,设置波特率

3.在串口2中

发送AT+ORGL,恢复1的默认设置 返回ok

发送AT+ROLE=0,设置为从模式 返回ok

发送AT+PSWD="1234" 两个密码要一样

发送AT+UART=115200,0,0,两个波特率要一样

发送AT+ADDR?查询从蓝牙地址

4.在串口1中

发送AT+BIND="查询到的从蓝牙地址",记得把冒号换成逗号

5.重新上电,等待指示灯2秒闪1次,依次闪烁两下,即配对成功

然后就可以通过串口进行发送和接收数据了。


使用STM32ZET6进行两个蓝牙的发送与接收数据

串口1用的太多了,每次占用还得改很麻烦,我直接用串口2(发送),和串口3(接收),也可以两个板子进行通信,道理一样,

蓝牙1连串口2(PA2,3),蓝牙2连串口3(PB10,11),

蓝牙           板子

RX    ------   TX

TX    ------    RX

蓝牙用5v,否则可能供电不足

/************usart2.c************/
#include "sys.h"
#include "usart2.h"
#include "usart.h"  
#include "lcd.h"

static void NVIC_Config(void){
	NVIC_InitTypeDef NVIC_InitStructure;
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	NVIC_InitStructure.NVIC_IRQChannel=DEBUG_USART_IRQ;
	
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
	
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
	
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
	
	NVIC_Init(&NVIC_InitStructure);


}
/*****************************
函数名:USART_Config
参数:无
波特率修改在usart.h文件中
作用:初始化串口2
*****************************/
void USART_Config(void){
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	
	DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK,ENABLE);
	
	DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK,ENABLE);
	
	GPIO_InitStructure.GPIO_Pin=DEBUG_USART_TX_GPIO_PIN;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(DEBUG_USART_TX_GPIO_PORT,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin=DEBUG_USART_RX_GPIO_PIN;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
	GPIO_Init(DEBUG_USART_RX_GPIO_PORT,&GPIO_InitStructure);

	USART_InitStructure.USART_BaudRate=DEBUG_USART_BAUDRATE;
	USART_InitStructure.USART_WordLength=USART_WordLength_8b;
	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(DEBUG_USARTx,&USART_InitStructure);
	
	NVIC_Config();
	USART_ITConfig(DEBUG_USARTx,USART_IT_RXNE,ENABLE);
	USART_Cmd(DEBUG_USARTx,ENABLE);
}

/*****************************
函数名:USART2_SENDDATA
参数:数组地址,长度
作用:发送数组
调用示例:USART2_SENDDATA(s,10),s定义为 u8 s[]
*****************************/
void USART2_SENDDATA(u8 *USART2_SendDATA,u16 SIZE)
{
	u16 i = 0;
	for(i = 0;i < SIZE;i++)
	{
		USART_SendData(USART2,USART2_SendDATA[i]);
		LCD_ShowNum(30,70+i*15,USART2_SendDATA[i],2,16);
		while( USART_GetFlagStatus(USART2,USART_FLAG_TXE) == RESET);//发送完了标志位
	}
	
}



/************usart2.h************/
#ifndef __USART2_H
#define __USART2_H
#include "stm32f10x.h"
#include <stdio.h>


#define DEBUG_USARTx                     USART2   //蓝牙所用串口2
#define DEBUG_USART_CLK                  RCC_APB1Periph_USART2  //串口时钟
#define DEBUG_USART_APBxClkCmd           RCC_APB1PeriphClockCmd //串口时钟使能
#define DEBUG_USART_BAUDRATE             115200 //波特率设置·

#define DEBUG_USART_GPIO_CLK             RCC_APB2Periph_GPIOA   

#define DEBUG_USART_GPIO_APBxClkCmd       RCC_APB2PeriphClockCmd  //端口时钟

#define DEBUG_USART_TX_GPIO_PORT         GPIOA              //端口宏定义
#define DEBUG_USART_TX_GPIO_PIN          GPIO_Pin_2
#define DEBUG_USART_RX_GPIO_PORT         GPIOA
#define DEBUG_USART_RX_GPIO_PIN          GPIO_Pin_3

#define DEBUG_USART_IRQ                  USART2_IRQn
#define DEBUG_USART_IRQHandler           USART2_IRQHandler   //中断服务函数

static void NVIC_Config(void);
void USART_Config(void);
void USART2_SENDDATA(u8 *USART2_SendDATA,u16 SIZE);
//int fputc(int ch, FILE *f);

#endif 


/************usart3.c************/
#include "sys.h"
#include "usart3.h"
#include "usart.h"
#include "lcd.h"


u8 USART3_RX_BUF[USART3_REC_LEN]; //数组用来存储接收到的数据,而USART3_REC_LEN为最多能接收的字节限度
//u16 USART3_RX_STA=0;         		//接收状态标记	 0-14位为接收字节数,15位接收完成标志位
uint8_t len=0;//接收字符长度
uint8_t Flag=0;//接收状态标志
/*****************************
函数名:usart3_init
参数:u32 bound 为波特率
调用示例:usart3_init(115200)
作用:初始化串口3
*****************************/
void usart3_init(u32 bound)
{ 
	  GPIO_InitTypeDef GPIO_InitStructure;
	  NVIC_InitTypeDef NVIC_InitStructurea;
	  USART_InitTypeDef USART_InitStruct;
	 
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);//使能串口3
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); //使能GPIOB
	  USART_DeInit(USART3);//串口3复位 不是必要的一步
	
	  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
	  GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;
	  GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	  GPIO_Init(GPIOB,&GPIO_InitStructure);    //PB10设置为复用推挽输出
	
	  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
	  GPIO_InitStructure.GPIO_Pin=GPIO_Pin_11;
	  GPIO_Init(GPIOB,&GPIO_InitStructure);  //PB11设置为浮空输入	 
  
	  NVIC_InitStructurea.NVIC_IRQChannel=USART3_IRQn;
	  NVIC_InitStructurea.NVIC_IRQChannelCmd=ENABLE;
	  NVIC_InitStructurea.NVIC_IRQChannelPreemptionPriority=1;
	  NVIC_InitStructurea.NVIC_IRQChannelSubPriority=1;
	  NVIC_Init(&NVIC_InitStructurea);          //串口3中断的设置
		
		USART_ITConfig(USART3,USART_IT_RXNE,ENABLE);//串口3中断使能和中断类型设置
	
	  USART_InitStruct.USART_BaudRate=bound;//串口波特率
		USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//无硬件数据流控制
		USART_InitStruct.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;//收发模式
		USART_InitStruct.USART_Parity=USART_Parity_No;//无奇偶校验位
		USART_InitStruct.USART_StopBits=USART_StopBits_1;//一个停止位
		USART_InitStruct.USART_WordLength=USART_WordLength_8b;//字长为8位数据格式
	  USART_Init(USART3,&USART_InitStruct);                 //串口3的一些参数设置
		
		USART_Cmd(USART3,ENABLE);//串口3使能
	
	  
}
接收中断,接收·单个数据
//void USART3_IRQHandler(void){ //串口3中断服务程序(固定的函数名不能修改)	
//	u16 a;
//	
//if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET){  //接收中断(接收到的数据必须是0x0d 0x0a结尾)		
//	a =USART_ReceiveData(USART3);//读取接收到的数据
//	
//	//printf("%d",a); //把收到的数据发送回电脑	
//	LCD_ShowNum(30,70,a,2,16);
//} 
//}


/*****************************
函数名:USART3_IRQHandler
参数:无
作用:中断服务函数,接收数组
修改建议:修改if语句中的len== ;用来匹配自己定义的数组
*****************************/
__IO uint8_t usart_value=0;
void USART3_IRQHandler(void) 
{
	int j =0;
	if(USART_GetITStatus(USART3,USART_IT_RXNE)){
		usart_value=USART_ReceiveData(USART3);
		USART3_RX_BUF[len]=usart_value;
		len++;
		
	}
	if(len==10){
		Flag=1;//接收完毕
		display();
		len=0;
	}
	USART_ClearFlag(USART3,USART_IT_RXNE);
	

}
void display()
{
	int i=0;
	for(i=0;i<10;i++)
	{
			 LCD_ShowNum(100,70+i*15,USART3_RX_BUF[i],2,16);
	 }
}



/************usart3.c************/
#ifndef __USART3_H
#define __USART3_H
#include "stm32f10x.h"

#define USART3_REC_LEN  20
void usart3_init(u32 bound);
void USART3_IRQHandler();
void display();
#endif


/***************main.c******************/
#include "sys.h"
#include "delay.h"
#include "usart2.h"
#include "usart3.h"
#include "lcd.h"
#include "usart.h"


 
/************************************************
 双蓝牙串口收发数据
 串口2 PA2/3
 串口3 PB10/11
************************************************/

int main(void)
 {		
		u8 s[10]={1,2,3,4,5,6,7,8,9,10};
		NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
		delay_init();	    	 //延时函数初始化
		uart_init(115200);	 //串口初始化为115200
		usart3_init(115200);
		USART_Config(); 
		LCD_Init();
		POINT_COLOR=RED; 
		LCD_ShowString(10,30,200,16,16,"Elite STM32");
		//USART_SendData(USART2,'A');//发送单个数值
		USART2_SENDDATA(s,10);
		LCD_ShowString(20,50,200,16,16,"Send");
		LCD_ShowString(90,50,200,16,16,"Receive");
		//while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET); //检查发送中断标志位
		while(1)
		{	
/*不使用中断服务函数*/
//			s=USART_ReceiveData(USART3);
//			printf("t:%d\r\n",s);
//			LCD_ShowNum(30,70,s,2,16);
//			LCD_ShowString(30,90,200,16,16,"STM32F10X");
//			delay_ms(500);
		}	 
	
}
	

参照注释,这里我用了LCD显示,你们用的时候需要添加LCD的库

 作者能力有限,才疏学浅,在学习过程中碰到很多问题,写下既是帮自己记忆,也是希望能帮到别人,希望大家批评指正。

有关基于STM32的双蓝牙通信的更多相关文章

  1. ruby-on-rails - Rails 应用程序之间的通信 - 2

    我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此

  2. 叮咚买菜基于 Apache Doris 统一 OLAP 引擎的应用实践 - 2

    导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵

  3. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  4. STM32读取串口传感器数据(颗粒物传感器,主动上传) - 2

    文章目录1.开发板选择*用到的资源2.串口通信(个人理解)3.代码分析(注释比较详细)1.主函数2.串口1配置3.串口2配置以及中断函数4.注意问题5.源码链接1.开发板选择我用的是STM32F103RCT6的板子,不过代码大概在F103系列的板子上都可以运行,我试过在野火103的霸道板上也可以,主要看一下串口对应的引脚一不一样就行了,不一样的就更改一下。*用到的资源keil5软件这里用到了两个串口资源,采集数据一个,串口通信一个,板子对应引脚如下:串口1,TX:PA9,RX:PA10串口2,TX:PA2,RX:PA32.串口通信(个人理解)我就从串口采集传感器数据这个过程说一下我自己的理解,

  5. MIMO-OFDM无线通信技术及MATLAB实现(1)无线信道:传播和衰落 - 2

     MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO

  6. kvm虚拟机安装centos7基于ubuntu20.04系统 - 2

    需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc

  7. ruby-on-rails - (Ruby,Rails) 基于角色的身份验证和用户管理...? - 2

    我正在寻找用于Rails的优质管理插件。似乎大多数现有的插件/gem(例如“restful_authentication”、“acts_as_authenticated”)都围绕着self注册等展开。但是,我正在寻找一种功能齐全的基于管理/管理角色的解决方案——但不是简单地附加到另一个非基于角色的解决方案。如果我找不到,我想我会自己动手......只是不想重新发明轮子。 最佳答案 RyanBates最近做了两个关于授权的railscast(注意身份验证和授权之间的区别;身份验证检查用户是否如她所说的那样,授权检查用户是否有权访问资源

  8. ruby - 在 Rakefile 中动态生成 Rake 测试任务(基于现有的测试文件) - 2

    我正在根据Rakefile中的现有测试文件动态生成测试任务。假设您有各种以模式命名的单元测试文件test_.rb.所以我正在做的是创建一个以“测试”命名空间内的文件名命名的任务。使用下面的代码,我可以用raketest:调用所有测试require'rake/testtask'task:default=>'test:all'namespace:testdodesc"Runalltests"Rake::TestTask.new(:all)do|t|t.test_files=FileList['test_*.rb']endFileList['test_*.rb'].eachdo|task|n

  9. ruby - 如何使用 Ruby 基于字母数字字符串生成颜色? - 2

    我想要像“嘿那里”这样的东西变成,例如,#316583。我希望将任意长度的字符串“归结”为十六进制颜色。我不知道从哪里开始。我在想,每个字符串的MD5散列都是不同的-但如何将该散列转换为十六进制颜色数字? 最佳答案 你可以只取几位前几位:require'digest/md5'color=Digest::MD5.hexdigest('Mytext')[0..5] 关于ruby-如何使用Ruby基于字母数字字符串生成颜色?,我们在StackOverflow上找到一个类似的问题:

  10. 【自动驾驶环境感知项目】——基于Paddle3D的点云障碍物检测 - 2

    文章目录1.自动驾驶实战:基于Paddle3D的点云障碍物检测1.1环境信息1.2准备点云数据1.3安装Paddle3D1.4模型训练1.5模型评估1.6模型导出1.7模型部署效果附录show_lidar_pred_on_image.py1.自动驾驶实战:基于Paddle3D的点云障碍物检测项目地址——自动驾驶实战:基于Paddle3D的点云障碍物检测课程地址——自动驾驶感知系统揭秘1.1环境信息硬件信息CPU:2核AI加速卡:v100总显存:16GB总内存:16GB总硬盘:100GB环境配置Python:3.7.4框架信息框架版本:PaddlePaddle2.4.0(项目默认框架版本为2.3

随机推荐