关于两个STM32F103系列单片机的蓝牙通信

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

   毕设做的是掌控小车,因此采用蓝牙通信作为小车和手部通信,前段时间做出实物,对其遇到的问题以及解决的方法做一些总结。一个主控芯片采用STM32F103ZET6,另一个主控芯片采用STM32F103C8T6,原因是本来准备了两个主控C8T6,不小心烧了一个。

1.两个蓝牙的配对

两个stm32蓝牙通信,单片机,stm32,嵌入式硬件

 需要准备的硬件:

2个HC-05主从一体,2个USB转TTL,杜邦线若干,USB拓展口(电脑USB口较少的)

AT指令集(在蓝牙模块进入AT指令模式后,需要在串口助手上发送AT指令):

对于HC-05这款蓝牙模块,其上有一个黑色的小按钮,在通电之前长按,插入电脑USB口后,原本快闪红灯变为慢闪后,即进入AT模式,此时可以在串口助手上发送AT指令。每发送一条AT指令后,串口助手会回馈一个OK或者其他,证明可以正常使用,若不能回复OK,大概有以下问题:

(1)检查连线,是否RXD连接的TXD,是否杜邦线连接正确。

(2)检查波特率是否正确,默认的波特率是38400

以下为两个蓝牙模块配对的过程:

 1.初始化蓝牙模块(需要开启两个串口助手对主从机进行配置,此处A为主机,B为从机)
蓝牙模块A的配置
AT+ORGL        

初始化蓝牙模块(当使用了此条AT指令后,自动退出AT模式,需重新进入AT模式)
AT+PSWD="xxxx"  

设置蓝牙配对密码(其中xxxx代表任意数字,主机从机的密码要一致)
AT+ROLE=1      

设置蓝牙模块A为主机 (1代表主机,0代表从机)


蓝牙模块B的配置
AT+ORGL        

初始化蓝牙模块(当使用了此条AT指令后,自动退出AT模式,需重新进入AT模式)
AT+PSWD="xxxx"  

设置蓝牙配对密码(其中xxxx代表任意数字,主机从机的密码要一致)
AT+ROLE=0      

设置蓝牙模块A为主机 (1代表主机,0代表从机)
2.查询从机地址并绑定
AT+ADDR?      

对从机进行地址查询,获得查询地址,我使用从机获得的的地址0022:12:0205FC
将获得的地址其中的冒号换成逗号即0022,12,0205FC
注意:在AT指令中所有的标点均为英文输入法下的
AT+BIND=0022,12,0205FC

 
在主机的串口助手窗口发送,使主机绑定从机地址
AT+BIND         

查看主机是否成功绑定从机地址
3.设置主机从机的波特率
AT+UART=115200,0,0    

设置主机的波特率为115200
AT+UART?            

查询主机波特率是否为115200
AT+UART=115200,0,0    

设置从机的波特率为115200
AT+UART?            

查询从机波特率是否为115200

配置完成后,拔出再重新通电,此时不用按住黑色小按钮,待两个蓝牙模块的红灯均变为慢闪时,即配对成功,此时在主机的串口助手上发送数字,在从机的串口助手上可以接收到,即实现了两个蓝牙模块的通信。

2.单片机的配置(仅为部分配置代码)

  根据上述两个蓝牙之间的通信,不难推断蓝牙通信就是无线的串口通信,STM32单片机配置时应注意配置两个单片机的串口,要有和蓝牙相同的波特率,同时将蓝牙连接至配置好的单片机所用的串口(RXD,TXD)上

我在小车上的串口配置,使用串口3

#include "usart3.h"
#include "sys.h"
#include "usart.h"
#include "tb6612.h"
#include "timer.h"


uint8_t Serial_RxFlag;
extern int USART3_Flag;
uint16_t R_Data;

void usart3_init(u32 bound)
{ 
	  GPIO_InitTypeDef GPIO_InitStructure;
	  NVIC_InitTypeDef NVIC_InitStructurea;
	  USART_InitTypeDef USART_InitStruct;
	 
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);//
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); //
	  USART_DeInit(USART3);//
	
	  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);          //
		
		USART_ITConfig(USART3,USART_IT_RXNE,ENABLE);//
	
	  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;//
	  USART_Init(USART3,&USART_InitStruct);                 //
		
		USART_Cmd(USART3,ENABLE);//
	

}
void USART3_IRQHandler(void)
{

	if (USART_GetITStatus(USART3, USART_IT_RXNE) == 1)
	{
		R_Data = USART_ReceiveData(USART3);//ÕâÐбíʾÊÕµ½µÄÊý¾Ý
		
		if(R_Data=='A') USART3_Flag=1;
		if(R_Data=='B') USART3_Flag=2;
		if(R_Data=='C') USART3_Flag=3;
		if(R_Data=='D') USART3_Flag=4;
		if(R_Data=='E') USART3_Flag=5;
		USART_ClearITPendingBit(USART3, USART_IT_RXNE);
	}
}


可以参考一个老哥的https://blog.csdn.net/hbzdsXCV/article/details/129278918?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522168240123616800186542106%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=168240123616800186542106&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-5-129278918-null-null.142^v86^wechat,239^v2^insert_chatgpt&utm_term=%E4%B8%A4%E4%B8%AA%E5%8D%95%E7%89%87%E6%9C%BA%E7%9A%84%E8%93%9D%E7%89%99%E9%80%9A%E4%BF%A1&spm=1018.2226.3001.4187

手部采集部分,使用串口2

#include "usart2.h"


u8  USART2_RX_BUF[USART2_REC_LEN]; //½ÓÊÕ»º³å,×î´óUSART_REC_LEN¸ö×Ö½Ú.Ä©×Ö½ÚΪ»»Ðзû 
u16 USART2_RX_STA;         		//½ÓÊÕ״̬±ê¼Ç	

void uart2_Init(u32 baudrate)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
    
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	//ʹÄÜUSART2£¬GPIOAʱÖÓ

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PA.2
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//¸´ÓÃÍÆÍìÊä³ö
    GPIO_Init(GPIOA, &GPIO_InitStructure);//³õʼ»¯GPIOA.2

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//PA3
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//¸¡¿ÕÊäÈë
    GPIO_Init(GPIOA, &GPIO_InitStructure);//³õʼ»¯GPIOA.3  

    //Usart1 NVIC ÅäÖÃ
    NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;//ÇÀÕ¼ÓÅÏȼ¶3
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;		//×ÓÓÅÏȼ¶3
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQͨµÀʹÄÜ
    NVIC_Init(&NVIC_InitStructure);	//¸ù¾ÝÖ¸¶¨µÄ²ÎÊý³õʼ»¯VIC¼Ä´æÆ÷

    //USART ³õʼ»¯ÉèÖÃ

    USART_InitStructure.USART_BaudRate = baudrate;//´®¿Ú²¨ÌØÂÊ
    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(USART2, &USART_InitStructure); //³õʼ»¯´®¿Ú2
    USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//¿ªÆô´®¿Ú½ÓÊÜÖжÏ
    USART_Cmd(USART2, ENABLE);                    //ʹÄÜ´®¿Ú2
}

void USART2_IRQHandler(void)                	//´®¿Ú2ÖжϷþÎñ³ÌÐò
{
	u8 Res;

    if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)  //½ÓÊÕÖжÏ(½ÓÊÕµ½µÄÊý¾Ý±ØÐëÊÇ0x0d 0x0a½áβ)
    {
        Res =USART_ReceiveData(USART2);	//¶ÁÈ¡½ÓÊÕµ½µÄÊý¾Ý

        if((USART2_RX_STA&0x8000)==0)//½ÓÊÕδÍê³É
        {
            if(USART2_RX_STA&0x4000)//½ÓÊÕµ½ÁË0x0d
            {
                if(Res!=0x0a)USART2_RX_STA=0;//½ÓÊÕ´íÎó,ÖØÐ¿ªÊ¼
                else USART2_RX_STA|=0x8000;	//½ÓÊÕÍê³ÉÁË 
            }
            else //»¹Ã»ÊÕµ½0X0D
            {	
                if(Res==0x0d)USART2_RX_STA|=0x4000;
                else
                {
                    USART2_RX_BUF[USART2_RX_STA&0X3FFF]=Res ;
                    USART2_RX_STA++;
                    if(USART2_RX_STA>(USART2_REC_LEN-1))USART2_RX_STA=0;//½ÓÊÕÊý¾Ý´íÎó,ÖØÐ¿ªÊ¼½ÓÊÕ	  
                }		 
            }
        }   		 
    } 

} 
static u8 USART2_TX_BUF[200];

void u2_printf(char* fmt,...)  
{     
	u16 i,j; 
	va_list ap; 
	va_start(ap,fmt);
	vsprintf((char*)USART2_TX_BUF,fmt,ap);
	va_end(ap);
	i=strlen((const char*)USART2_TX_BUF);		//´Ë´Î·¢ËÍÊý¾ÝµÄ³¤¶È
	for(j=0;j<i;j++)							//Ñ­»··¢ËÍÊý¾Ý
	{
		while((USART2->SR&0X40)==0);			//Ñ­»··¢ËÍ,Ö±µ½·¢ËÍÍê±Ï   
		USART2->DR=USART2_TX_BUF[j];  
	} 
}

3.实现两个蓝牙的通信

在配置好两个单片机的串口之后,其实关于蓝牙通信就已经解决的差不多了,最后剩下的关键只有串口发送函数和串口接收函数的使用,在主机使用串口发送函数,在从机使用串口接收函数,注意串口发送和接收的串口。

4.遇到的问题及解决方案

开始由于好久没捣鼓过32了,而且我这个电脑ST-LINK一直没有调过来,因此后来改成用串口烧录,对于c8t6的串口烧录(使用TTL转USB烧录),烧录时应用跳线帽将BOOT0置1,待烧录完成后将BOOT0置0,才可正常工作,而期间BOOT1一直置0。

5.完整版代码

链接:https://pan.baidu.com/s/1Nar8uLibDYbWvmrfeW7pBg?pwd=rx1l 
提取码:rx1l

这是本人第一次在CSDN上发表文章,本人才学疏浅,写下此文也是希望能帮到别人,谢谢。文章来源地址https://www.toymoban.com/news/detail-546510.html

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

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

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

相关文章

  • 【单片机】STM32单片机,定时器的输入捕获,基于捕获的频率计,STM32F103

    【单片机】STM32单片机,定时器的输入捕获,基于捕获的频率计,STM32F103

    下面的定时器都具有输入捕获能力: 查看另一篇文章:https://qq742971636.blog.csdn.net/article/details/131471539 外部计数频率计的缺点:需要两个定时器配合,最高能测量的频率是否有限制我没具体尝试。 基于捕获的频率计的缺点:最高能测量的频率有限制。 TIM3_CH1 PWM PA6 10KHZ。 输入

    2024年02月14日
    浏览(17)
  • (STM32F103单片机)DHT11温湿度传感器

    (STM32F103单片机)DHT11温湿度传感器

    目录   一,产品介绍 二,产品亮点 三,产品参数 四,引脚连接及通信说明  五,原理讲解 六,源码 1,DHR11.C 2.DHR11.H 3,main.c DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高

    2023年04月08日
    浏览(13)
  • STM32F103单片机控制继电器开关小风扇和加热片

    STM32F103单片机控制继电器开关小风扇和加热片

       在智能衣柜中,使用异味传感器检测柜内异味值,当异味值大于设定值时会自动开启小风扇,小风扇起到一个排污去浊的功能,再加上温湿度传感器检测柜内的温度和湿度,当温湿度达到设定值时,加热片自动发热,起到一个降温除霉的作用。想要使小风扇和加热片自动

    2024年02月02日
    浏览(34)
  • 【单片机】STM32F103C8T6 最小系统板原理图

    【单片机】STM32F103C8T6 最小系统板原理图

    STM32F103C8T6是一款基于ARM Cortex-M3内核的32位微控制器,由STMicroelectronics(ST)公司生产。它是STMicroelectronics的STM32系列微控制器中的一员,被广泛应用于嵌入式系统和电子设备中。 STM32F103C8T6单片机的主要特点和资源包括: 内存资源: Flash存储器:64 KB SRAM(静态随机访问存储器

    2024年02月12日
    浏览(11)
  • 【单片机】STM32单片机,RTC实时时钟,STM32F103C8T6,程序,万年历,数字时钟

    【单片机】STM32单片机,RTC实时时钟,STM32F103C8T6,程序,万年历,数字时钟

    我以STM32F103C8T6为例,但STM32F103的RTC是通用的,STM32F103C8T6有一个原理图: https://qq742971636.blog.csdn.net/article/details/131288390 用纽扣电池给VBAT供电(要共地),即可实现掉电后依旧走时的能力。 主要特性(来源于STM32中文参考手册V10.pdf): 记得加标准库文件: 串口接收:

    2024年02月11日
    浏览(20)
  • 【单片机】STM32单片机频率计程序,外部脉冲计数程序,基于脉冲计数的频率计程序,STM32F103

    【单片机】STM32单片机频率计程序,外部脉冲计数程序,基于脉冲计数的频率计程序,STM32F103

    两种方法用于在单片机中实现频率计的功能。 第一种方法是通过定时器来衡量信号的周期,然后将周期转换为频率。在这种方法中,你可以使用单片机的定时器模块来测量输入信号的周期,定时器会产生一个计数值,你可以根据这个计数值来推算出输入信号的周期,并通过简

    2024年02月11日
    浏览(15)
  • stm32F103单片机pwm控制伺服驱动器进而控制步进电机

    stm32F103单片机pwm控制伺服驱动器进而控制步进电机

    1.需要一台步进电机,私服驱动器,stm32单片机;先按照说明文档,连接好硬件相关线路,对应好sign+,sign-,puls+,puls-线路,其中sign只是个io口拉高拉低操作,puls是pwm波形输出口,虽然有两根线,但只是需要控制一个IO口输出波形即可; 采用主从模式,TIM1为主定时器,tim3未从定

    2024年02月04日
    浏览(12)
  • STM32F103ZET6 封装 LQFP-144 ST意法 单片机芯片

    STM32F103ZET6 封装 LQFP-144 ST意法 单片机芯片

    STM32F103ZET6 是意法半导体(STMicroelectronics)生产的一款基于 ARM Cortex-M3 内核的 32 位微控制器。它具有高性能、低功耗的特点,广泛应用于各种嵌入式系统和工业应用中。STM32F103ZET6 的主要特点如下: 内核:ARM Cortex-M3,工作频率最高可达 72MHz。 存储器:64KB SRAM,512KB FLASH。 外

    2024年04月22日
    浏览(12)
  • STM32F103RCT6开发板M3单片机教程06--定时器中断

    STM32F103RCT6开发板M3单片机教程06--定时器中断

    除非特别说明,本章节描述的模块应用于整个 STM32F103xx 微控制器系列,因为我们使用是 STM32F103RCT6开发板是mini最小系统板。 本教程使用是( 光明谷SUN_STM32mini开发板 )   首先了解一下是STM32F10X定时器(Timer)   注: 小容量产品是指闪存存储器容量在16K至32K字节之间的STM32F101

    2024年02月04日
    浏览(46)
  • 【单片机】STM32单片机,定时器,多路PWM,TIM1、TIM2、TIM3、TIM4,STM32F103

    【单片机】STM32单片机,定时器,多路PWM,TIM1、TIM2、TIM3、TIM4,STM32F103

    下图是定时器相关引脚: 在《STM32中文参考手册V10.pdf》有写: TIM1 的PWM是带互补输出的,较为高级和复杂,有兴趣可以参考其他介绍文章,这里的代码让7个引脚输出PWM。 调用: 这里没有重映射,注意不能把PA9 PA10 初始化成串口去了。 timer.c timer.h 调用: 这里没有重映射。

    2024年02月11日
    浏览(15)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包