当前位置: 首页 > article >正文

STM32-笔记28-蓝牙模块

一、简介

 二、引脚

        HC-08 蓝牙模块是通过串口与单片机进行通信,这个模块既可以作为主机也可以作为从机(通过 AT 指令配置)。有些蓝牙模块不支持主机(如 HC-02 、HC-04),所以在使用时需要注意区分。 HC-08 蓝牙模块实物图如下所示:

        可以看到,HC-08 模块一共有 6 个引脚,下面详细介绍各个引脚的作用。

• STATE:状态输出引脚。未连接时,则为低电平。连接成功时,则为高电平。可以在程序中作指示引脚使用;

• RXD:串口接收引脚。接单片机的 TX 引脚(如果是5V MCU,需串联一个 220R 电阻);

• TXD:串口发送引脚。接单片机的 RX 引脚;

• GND:接地电源; • VCC:输入 3.2~6V 的电源(注意,上面一层邮票口的模块不能接 5V 的电源,需要底板降压至 3.3V);

• KEY:主机用于清除配对的从机地址记忆(需要拉高电平 200ms 以上)。 

        上面的「连接」是指模块通过蓝牙协议连接上主机或从机,并非物理意义上的连接。下同。  正常通信下,只需接 RXD、TXD、GND、VCC 四条线就够了。 蓝牙模块上还有一个 LED灯和一个小按键 (按键控制着引脚 KEY )。默认情况下,当 LED灯闪烁时表示蓝牙模块当前为从机,正在等待连接。而长亮的时候就代表已经有主机连接上该模块,可以正常进行透传通讯了。

        当按键按下后,主机将清除已被记录的从机地址。另外,也可使用 AT+CLEAR 指令,实现「主机清除已记录的从机地址」的功能。

        注意,在硬件接线的时候蓝牙模块的 TXD 要和单片机的 RXD 相连接,蓝牙模块的 RXD 要和单片机的 TXD 相连接,也就是所谓的「交叉接线」。

手把手教你玩转蓝牙模块(原理+驱动) | 良许嵌入式

三、蓝牙收发代码编写

复制项目文件19-串口打印功能,重命名为,32-蓝牙模式实现

重命名bluetooth

打开工程文件

加载文件

main.c

#include "sys.h"
#include "delay.h"
#include "led.h"
#include "uart1.h"
#include "bluetooth.h"

int main(void)
{
    HAL_Init();                         /* 初始化HAL库 */
    stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
    led_init();//初始化led灯
    bt_init(115200);
    uart1_init(115200);
    printf("hello word!\r\n");
    
//    led1_ON();
//    led1_OFF();
    uint8_t i = 0;
    while(1)
    { 
        bt_send("hello bt%d\r\n", i++);
        delay_ms(500);
        led1_ON();
        led2_OFF();
        delay_ms(500);
        led1_OFF();
        led2_ON();
        delay_ms(500);
    }
}

bluetooth.c

#include "sys.h"
#include "bluetooth.h"
#include "string.h"
#include "stdarg.h"

UART_HandleTypeDef uart2_handle;                                            /* uart2句柄 */

uint8_t uart2_rx_buf[ UART2_RX_BUF_SIZE];                                    /* uart2接收缓冲区 */
uint16_t uart2_rx_len = 0;                                                  /* uart2接收字符长度 */

 

/**
 * @brief       串口1初始化函数
 * @param       baudrate: 波特率, 根据自己需要设置波特率值
 * @retval      无
 */
void bt_init(uint32_t baudrate)
{
    /*uart2 初始化设置*/
    uart2_handle.Instance = USART2;                                         /* USART1 */
    uart2_handle.Init.BaudRate = baudrate;                                  /* 波特率 */
    uart2_handle.Init.WordLength = UART_WORDLENGTH_8B;                      /* 字长为8位数据格式 */
    uart2_handle.Init.StopBits = UART_STOPBITS_1;                           /* 一个停止位 */
    uart2_handle.Init.Parity = UART_PARITY_NONE;                            /* 无奇偶校验位 */
    uart2_handle.Init.HwFlowCtl = UART_HWCONTROL_NONE;                      /* 无硬件流控 */
    uart2_handle.Init.Mode = UART_MODE_TX_RX;                               /* 收发模式 */
    HAL_UART_Init(&uart2_handle);                                           /* HAL_UART_Init()会使能uart2 */
}


/**
 * @brief       uart2接收缓冲区清除
 * @param       无
 * @retval      无
 */
void uart2_rx_clear(void)
{
    memset(uart2_rx_buf, 0, sizeof(uart2_rx_buf));                          /* 清空接收缓冲区 */
    uart2_rx_len = 0;                                                       /* 接收计数器清零 */
}

/**
 * @brief       串口1中断服务函数
 * @note        在此使用接收中断及空闲中断,实现不定长数据收发
 * @param       无
 * @retval      无
 */
void USART2_IRQHandler(void)
{
    uint8_t receive_data = 0;   
    if(__HAL_UART_GET_FLAG(&uart2_handle, UART_FLAG_RXNE) != RESET){        /* 获取接收RXNE标志位是否被置位 */
        if(uart2_rx_len >= sizeof(uart2_rx_buf))                            /* 如果接收的字符数大于接收缓冲区大小, */
            uart2_rx_len = 0;                                               /* 则将接收计数器清零 */
        HAL_UART_Receive(&uart2_handle, &receive_data, 1, 1000);            /* 接收一个字符 */
        uart2_rx_buf[uart2_rx_len++] = receive_data;                        /* 将接收到的字符保存在接收缓冲区 */
    }

    if (__HAL_UART_GET_FLAG(&uart2_handle, UART_FLAG_IDLE) != RESET)        /* 获取接收空闲中断标志位是否被置位 */
    {
        printf("recv: %s\r\n", uart2_rx_buf);                               /* 将接收到的数据打印出来 */
        uart2_rx_clear();
        __HAL_UART_CLEAR_IDLEFLAG(&uart2_handle);                           /* 清除UART总线空闲中断 */
    }
}
void bt_send(char * format, ...)//不定长传入参数...
{
    uint8_t send_buf[128] ={0};//传入一个字符串
    va_list arg;//创建一个参数列表
    va_start(arg, format);//把format字符串里面的东西丢到arg里
    vsprintf((char *)send_buf, format, arg);//把arg里面的东西通过预定的这个格式传到send_buf里面
    va_end(arg);
    HAL_UART_Transmit(&uart2_handle, send_buf, sizeof(send_buf), 100);
}

bluetooth.h

#ifndef __BLUETOOTH_H__
#define __BLUETOOTH_H__

#include "stdio.h"
#include "sys.h"


/* UART收发缓冲大小 */
#define UART2_RX_BUF_SIZE            128
#define UART2_TX_BUF_SIZE            64


void bt_init(uint32_t bound);            /* 串口初始化函数 */
void bt_send(char * format, ...);//不定长传入参数...

#endif



http://www.kler.cn/a/465050.html

相关文章:

  • Tableau数据可视化与仪表盘搭建-安装教程
  • 【踩坑记录】uni-app 微信小程序调试不更新问题解决指南
  • C#调用Lua
  • JavaVue-Get请求 数组参数(qs格式化前端数据)
  • 深入理解 Android 中的 ApplicationInfo
  • MinGW 和 MinGW-w64 的介绍与配置
  • SQL 总结
  • 125个Docker的常用命令
  • 数据库-MySQL-limit优化(全面 易理解)
  • 小米15震撼发布:手机吊起一人一椅,创新极限测试
  • 基于微信小程序的面部动作检测
  • 百度二面,MySQL 怎么做权重搜索?
  • SQL 中的 EXISTS
  • 开源自荐 - NoteGen 一款专注于记录和写作的跨端 AI 笔记
  • Web3的核心理念:去中心化如何改变互联网结构
  • Linux和ROS(Robot Operating System)在底层实现上的差异
  • 记一次 dockerfile 的循环依赖错误
  • 【three.js】场景搭建
  • [极客大挑战 2019]Secret File
  • 小程序组件 —— 22 组件案例 - 轮播区域绘制
  • Ansible Jinja2 语法简介及使用
  • Oracle 数据库使用SPM固定执行计划
  • 在Ubuntu系统中生成授信域名https证件文件
  • 利用Python爬虫获取店铺所有商品:技术实践与应用指南
  • Netty学习 - 编译Netty4.2
  • 【TextIn—智能文档解析与DocFlow票据AI自动化处理:赋能企业文档数字化管理与数据治理的双重利器】