STM32F4 基于USART串口的蓝牙通信

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

目录

一、硬件资源

连接方案

其他配置

二、实验原理

基本定义

USART介绍

USART工作原理

数据发送

数据接收

蓝牙HM-10配置

三、代码部分

usart.c

usart.h

Serial.c

Serial.h

main.c

结语


一、硬件资源

STM32F401,OLED,蓝牙hm10

STM32F4 基于USART串口的蓝牙通信,STM32F401开发,stm32,嵌入式硬件,单片机

连接方案

STM32F4 基于USART串口的蓝牙通信,STM32F401开发,stm32,嵌入式硬件,单片机

设备1的TX与设备2的RX连接,这样设备1发送的数据可以被设备2接收到。

STM32F4 基于USART串口的蓝牙通信,STM32F401开发,stm32,嵌入式硬件,单片机

由引脚复用表,我们选择PB6和PB7分别作为TX和RX,那么PB6接蓝牙的RX,PB7接蓝牙的TX。

其他配置

可以在手机上下载一个蓝牙BLE助手,用来与STM通信。进入软件后寻找要配对的蓝牙,注意要先将手机定位开启,然后就可以收发数据了。

二、实验原理

基本定义

波特率∶串口通信的速率。因此发生方和接收方要设置相同的波特率。

波特率计算公式: baud = fck/(16* USARTDIV)

起始位 : 标志一个数据帧的开始,固定为低电平

停止位∶用于数据帧间隔,固定为高电平。为下一次的起始位奠定基础。
数据位︰数据帧的有效载荷,1为高电平,0为低电平,低位先行

校验位:用于数据验证,根据数据位计算得来。保证数据在一定范围内的正确性。
STM32F4 基于USART串口的蓝牙通信,STM32F401开发,stm32,嵌入式硬件,单片机八位数据的格式

STM32F4 基于USART串口的蓝牙通信,STM32F401开发,stm32,嵌入式硬件,单片机在八位的基础上可以加一位奇偶校验位

以奇校验为例,就是九位数据位最终1的个数为奇数个,比如数据为0000 1001,有偶数个1,那么校验位为1,使得最终1的个数为奇数个。

当然,并不是说八位就一定无校验位,九位就一定有校验位,只不过8位恰好为一字节,为了方便我们这样设置。

USART介绍

USART (Universal Synchronous/Asynchronous Receiver/Transmitter)通用同步/异步收发器
可配置数据位长度(8/9)、停止位长度(0.5/1/1.5/2);可选校验位(无校验/奇校验/偶校验)

还可以选择硬件流控制,A发送数据,B接收数据,如果B还未处理完数据A就继续发送过来会导致数据丢失。硬件流控制就是B告诉A是否可以继续发送。

USART工作原理

STM32F4 基于USART串口的蓝牙通信,STM32F401开发,stm32,嵌入式硬件,单片机

简化后如下图

STM32F4 基于USART串口的蓝牙通信,STM32F401开发,stm32,嵌入式硬件,单片机

数据发送

发送数据时数据由数据线进入TDR,送入移位寄存器后右移(低位先行)送到TX,下一个数据发过来时要查看TXE(TX Empty)标志位,若为1,说明TDR已经空了,可以放入下一个数据。

数据接收

数据经RX进入后送至移位寄存器,先进入最高位,右移使得数据形式不变,之后进入RDR,全部进入后RXNE(RX Not Empty)置1,表示接收到数据。

由于设备不知道另一设备什么时候发数据,接收数据的方式有两种。第一,轮询模式,CPU一直查询是否有数据发来,占用CPU资源。第二,中断,有数据发来时暂停CPU任务,转而执行中断任务,涉及到中断函数和NVIC的配置。

蓝牙HM-10配置

蓝牙的设置由指令控制,具体的指令可以看配对的蓝牙说明书。

常见的设置指令如下

"AT+BAUD[P1]":设置波特率9600
"AT+PARI[P1]"):串口校验位设置
"AT+STOP[P1]:停止位设置
"AT+MODE[P1]":设置工作模式,2为透传+远控模
"AT+NAME[name]"):设置名字
"AT+ROLE[P1]" :设置主从模式,0从1主

如果要查询的话:格式为指令+"?",比如:"AT+BAUD?"用来查询蓝牙的波特率

三、代码部分

usart.c

这部分是对usart相关的配置,包括GPIO,USART和NVIC

#include "stm32f4xx.h"
#include "stdarg.h"
#include "stdio.h"

uint8_t RxFlag;
uint8_t RxData;

void Usart_init(void){
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//USART时钟初始化
	
	GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_USART1);//实现接口的复用功能
	GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1);
	
	GPIO_InitTypeDef GPIO_InitStruct;
	
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;//复用模式
	GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;//推挽输出
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStruct);
	
	USART_InitTypeDef USART_InitStruct;
	USART_InitStruct.USART_BaudRate = 9600;//波特率
	USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
	USART_InitStruct.USART_WordLength = USART_WordLength_8b;//字长
	USART_InitStruct.USART_StopBits = USART_StopBits_1;//一位停止位
	USART_InitStruct.USART_Parity = USART_Parity_No;//校验位
	USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//硬件流控制
	USART_Init(USART1, &USART_InitStruct);
	
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//开启RXNE标志位到NVIC输出
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置优先级为2
	
	NVIC_InitTypeDef NVIV_InitStruct;
	NVIV_InitStruct.NVIC_IRQChannel = USART1_IRQn;
	NVIV_InitStruct.NVIC_IRQChannelCmd = ENABLE;
	NVIV_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
	NVIV_InitStruct.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIV_InitStruct);
	USART_Cmd(USART1,ENABLE);
}

void Usart_SendByte(uint8_t byte){
	//等TDR的数据全部进入移位寄存器
	while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);

	USART_SendData(USART1, byte);
}
void Usart_SendArray(uint8_t* Array,uint16_t length){
	for(int i=0;i<length;i++){
		Usart_SendByte(Array[i]);
	}
	
}
void Usart_SendString(char* str){//字符串有结束标志位,不用长度
	for(int i=0;str[i] != '\0';i++){
		Usart_SendByte(str[i]);
	}
	
}
uint32_t Pow(uint32_t x){//求10的x次方
	uint32_t ans=1;
	for(uint8_t i=0;i<x;i++){
		ans*=10;
	}
	return ans;
}
	
	
void Usart_SendNumber(uint32_t Number,uint16_t Length){//为了发送大整数
	uint32_t ans=Pow(Length-1);
	for(int i=0;i<Length;i++){
		
		Usart_SendByte(Number / ans % 10+ '0');
		ans/=10;
	}
	
}
//先勾选Use Micro LIB为keil嵌入式平台优化的一个精简库
int fputc(int ch,FILE *f){//该函数为print函数的底层,prinf()函数重定向,将打印的东西输出到串口
	Usart_SendByte(ch);
	return ch;
}
void Usart_Printf(char *format, ...){//参数用来接收格式化字符串,...接收可变参数列表
	char String[100];
	va_list arg;//参数表,类型包含在stdarg头文件
	va_start(arg,format);
	vsprintf(String,format,arg);
	va_end(arg);//释放参数列表
	
	Usart_SendString(String);
	
}
uint8_t GetRxFlag(){
	if(RxFlag == 1){
		RxFlag=0;
		return 1;
	}
	return 0;
}
uint8_t GetRxData(){
	return RxData;
}
void USART1_IRQHandler(){//重写中断函数
	if(USART_GetITStatus(USART1,USART_IT_RXNE) == SET){
		RxData = USART_ReceiveData(USART1);
		RxFlag = 1;
		USART_ClearITPendingBit(USART1,USART_IT_RXNE);//对RXNE清零
	}
	
}
usart.h
#ifndef USART_H
#define USART_H

#include<stdio.h>
void Usart_init(void);
void Usart_SendByte(uint8_t byte);
void Usart_SendArray(uint8_t* Array,uint16_t length);
void Usart_SendString(char* str);
void Usart_SendNumber(uint32_t Number,uint16_t Length);
int fputc(int ch,FILE *f);
void Usart_Printf(char *format, ...);
uint8_t GetRxFlag(void);
uint8_t GetRxData(void);
	
	
#endif
Serial.c

这部分是对蓝牙的设置

#include "stm32f4xx.h"                  // Device header
#include "usart.h"
#include "Delay.h" 

void Serial_Init(){
	Usart_init();
	
	Usart_SendString("AT");
	Usart_SendString("AT+BAUD[0]");//设置波特率9600
	Usart_SendString("AT+PARI[0]");//无串口校验
	Usart_SendString("AT+STOP[0]");//一个停止位
	Usart_SendString("AT+MODE[2]");//工作模式,2为透传+远控模式
	Usart_SendString("AT+NAME[MLT-BT05]");
	Usart_SendString("AT+ROLE[1]");//设置主从模式,0从1主

}

Serial.h
#ifndef SERIAL_H
#define SERIAL_H

void Serial_Init();

#endif
main.c
#include "stm32f4xx.h"                  // Device header
#include "Delay.h"
#include "oled.h"
#include "usart.h"
#include "Serial.h"

uint8_t Data;

int main(void){
	OLED_Init();
	Serial_Init();//其中包含了usart的初始化
	OLED_ShowString(1,1,"RxData");
	
	while(1){
        //发送
		Usart_SendString("Hello!\r\n");
		
				
		//轮询模式
		/*if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == SET){//不断查询RXNE标志位
			Data = USART_ReceiveData (USART1);
			OLED_ShowHexNum(2,1,Data,2);
		}*/
        
        //中断模式
		/*if(GetRxFlag() == 1){//标志位为1,说明收到数据
			Data = GetRxData();
			Usart_SendByte(Data);
			OLED_ShowHexNum(1,8,Data,2);
			
		}*/
	}
}


结语

这样我们就可以通过蓝牙做一些小设计了,比如控制灯的开关,手机发送给STM  'o',STM接收到数据后判断,如果为'o',则打开灯,收到 'f'则关灯。文章来源地址https://www.toymoban.com/news/detail-798768.html

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

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

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

相关文章

  • 基于STM32F4开发的智能台灯

    写这篇博客的目的有2个,首先是记录一下学习STM32大半年来的第一个自己动手开发的项目,整理一下开发过程和思路;其次也是希望可以和更多的同行交流开发经验,有什么问题可以多多讨论,集思广益,共同进步~ 开发的智能台灯功能有2个: 1.手动模式:可通过按键调节

    2024年02月05日
    浏览(16)
  • 【stm32开发笔记】基于HAL库的STM32F4添加DSP库

    本文分两种方法添加DSP库:1.CubeMX直接配置ioc添加; 2.KEIL内添加; 简述:补齐全部lib库-添加DSP包-使能DSP勾选-添加头文件及魔术棒配置-测试 1.补齐lib库。( 如果使用直接默认添加的库,是不支持FPU的,所以需要补齐后找到所需的lib文件进行替换,在MX的工程管理栏,选择复制所

    2024年02月16日
    浏览(20)
  • GD32F30x系列---串口通信(USART)基础配置(中断接收模式)

    GD32F30x系列USART数据帧可以通过全双工或半双工、同步或异步进行传输,且支持DMA功能,目前我们这里先不使用DMA,下一节再使用DMA与其对比。 其他的原理与解析就不再赘述,大家可以自行搜索相关资料,要多看数据手册。 1、创建一个usart.c文件和usart.h文件到对应的文件夹中

    2024年02月12日
    浏览(14)
  • 「STM32入门」USART串口通信

    通信的目的:将一个设备的数据传送到另一个设备,扩展硬件系统 通信协议:制定通信的规则,通信双方按照协议规则进行数据收发 本文将介绍USART  概念解释 TX、RX分别是Transmit和Receive的缩写,代表发送、接受数据 全双工的含义是发送线路和接受线路互不影响,可以同时进

    2024年02月06日
    浏览(18)
  • 基于STM32F103C8T6的HC-06蓝牙通信

    如果朋友们 遇到了如下问题 ,可以仔细借鉴本文章和另一篇专门讲解 蓝牙通信问题 的文章,一定能够解决你在蓝牙通信时遇到的诸多困难 1.在调试蓝牙模块AT指令时无返回值 2.身边 无USB转TTL模块 可以直接调试蓝牙模块(本人就是由于无模块花了了整整一天才调试成功)

    2024年02月03日
    浏览(30)
  • 【STM32】STM32F4中USB的CDC虚拟串口(VCP)使用方法

    最近在学习STM32的USB功能,主要是想要使用虚拟串口(VCP)功能,来解决串口传输速率较低的问题,达到于上位机高效通信的目的。 使用芯片:STM32F407ZGT6 使用函数:HAL库 使用工具:STM32CubeMX + Keil uVision5 串口工具:VOFA 主要配置内容: 调试模式为Serial; 使用外部时钟 设置为

    2024年02月21日
    浏览(21)
  • STM32CubeMX实现USART串口通信

    硬件:stm32f103c8t6核心板 软件:STM32CubeMX 6.6.1 keil5 mdk 这里就不再详细介绍了,详细请参考上一篇博客: https://blog.csdn.net/qq_55894922/article/details/127232999?spm=1001.2014.3001.5501 若点击 Manage embedded software packages 后,出现失败,则需要随便点击其它任一选项,进行下载一些文件,比如点

    2023年04月17日
    浏览(17)
  • STM32入门学习之USART串口通信:

    1.串口通信简介:通用异步收发传输器UART(Universal Asynchronous Receiver/Transmitter)是负责处理数据总线和串口之间的串/并通信的设备。UART通信规定了数据帧的格式:起始位、数据位、校验位、停止位等。UART异步通信只需要通信双方设置好数据帧的格式和波特率即可完成通信。因为

    2024年02月16日
    浏览(23)
  • STM32F4_串口通信详解

    目录 1. 串口相关介绍及使用 1.1 串口设置的一般步骤: 1.1.1 串口时钟和GPIO时钟使能 1.1.2 设置引脚复用器映射 1.1.3 GPIO端口模式设置 1.1.4 串口参数初始化 1.1.5 开启中断并且初始化NVIC,使能中断 1.1.6 使能串口 1.1.7 串口数据发送与接收 1.1.8 串口状态 1.1.9 获取中断状态 1.1.10 中

    2024年02月11日
    浏览(21)
  • 调试STM32F4 USB3300 USB_HS虚拟串口

    参考了csdn上面的几篇文章,经历了一个多小时的调试排除找bug,终于成功了! 通过STM32cubeMx配置USB phy芯片 1. 2. 3. 4. 5.生成代码出来,打开工程,编译下载通过。 在上电之前,电脑得先安装ST的USB 虚拟串口驱动 点击前往下载--STSW-STM32102 - STM32虚拟COM端口驱动程序 - STMicroelect

    2024年02月02日
    浏览(18)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包