51单片机之蓝牙模块的使用

接线方法

1. 电源连接

VCC:连接到5V电源(如果使用3.3V供电的单片机,请确保模块也兼容3.3V)。

GND:连接到地(GND)。

注意:虽然HC-05/HC-06模块可以接受3.3V至6V的电压输入,但其I/O电平为3.3V。如果你的单片机工作在5V电平,建议使用电平转换器以避免损坏模块。

2. 串行通信连接

TXD(HC-05/HC-06的发送端):连接到单片机的RXD(接收端),通常是P3.0引脚。

RXD(HC-05/HC-06的接收端):连接到单片机的TXD(发送端),通常是P3.1引脚。由于HC-05/HC-06的RXD引脚需要3.3V逻辑电平,而51单片机的TXD输出为5V,因此需要一个分压电路来将5V降到3.3V。

微信小程序搜索蓝牙调试助手,一般用的HCBLE串口助手,这个后面调试代码可以用。用于手机和蓝牙通信

该代码主要作用是手机发送数据给蓝牙,蓝牙把数据传递给单片机,单片机使用定时器和中断去检测串口是否有数据,然后控制led的亮灭,简单实验。

code:

c 复制代码
#include <REGX52.H>

sbit LED = P2^1; // 定义LED连接的引脚

void UART_Init() {
    TMOD = 0x20; // 设置定时器1为模式2,8位自动重装
    TH1 = 0xFD;  // 波特率设置为9600bps(适用于11.0592MHz晶振)
    SCON = 0x50; // 8位数据, 1位停止位, REN使能
    TR1 = 1;     // 启动定时器1
}

void UART_ISR() interrupt 4 {
    if (RI) { // 如果是接收中断
        char receivedData = SBUF; // 读取接收缓冲区
        RI = 0; // 清除接收中断标志位
        
        // 根据接收到的数据控制LED
        if(receivedData == '1') {
            LED = 0; // 打开LED
        } else if(receivedData == '0') {
            LED = 1; // 关闭LED
        }
        
        // 回发数据
        SBUF = receivedData; // 将接收到的数据发送回去
        while(!TI); // 等待发送完成
        TI = 0; // 清除发送中断标志位
    }
}

void main() {
    UART_Init(); // 初始化UART
    EA = 1; // 开启全局中断
    ES = 1; // 开启串口中断
    
    while(1) {
        // 主循环可以添加其他任务
    }
}

3.代码解释

UART_Init函数是初始化定时器

  1. TMOD = 0x20;

    TMOD 是定时器模式寄存器(Timer Mode Register),用于设置定时器的工作模式。

    0x20 的二进制表示为 0010 0000。

    高四位(TMOD[7:4])对应定时器1的配置:0010 表示模式2,即8位自动重装载模式。

    低四位(TMOD[3:0])对应定时器0的配置,这里没有使用定时器0,所以保持为0。

    物理意义:将定时器1设置为模式2,8位自动重装载模式。在这种模式下,定时器计数溢出后会自动从TH1重新加载初始值,这有助于产生稳定的波特率。

  2. TH1 = 0xFD;

    TH1 是定时器1的高字节寄存器(Timer High byte Register for Timer 1)。

    0xFD 对应十进制的253。在12MHz晶振下,为了获得9600bps的波特率,需要设置定时器1的重装载值为253(即0xFD)。

    物理意义:设置定时器1的重装载值为253,这样当定时器1溢出时,它会自动重载这个值,从而生成9600bps的波特率。

  3. SCON = 0x50;

    SCON 是串行控制寄存器(Serial Control Register),用于配置串口通信的模式和状态。

    0x50 的二进制表示为 0101 0000。

    第7位(SM0)和第6位(SM1)为 01,表示选择串口工作在模式1(8位UART,可变波特率)。

    第5位(SM2)为 0,表示禁用多机通信模式。

    第4位(REN)为 1,表示允许接收数据。

    其余位与当前配置无关。

    物理意义:配置串口工作在模式1,允许接收数据,并设置为8位数据、1位停止位的格式。

  4. TR1 = 1;

    TR1 是定时器1的运行控制位(Timer Run Control bit for Timer 1)。

    将其设置为 1 表示启动定时器1。

    物理意义:启动定时器1,使其开始计数并生成所需的波特率信号。

clike 复制代码
总结
这段代码的主要目的是初始化51单片机的UART模块,以实现基于串行通信的功能。具体步骤包括:

设置定时器1为模式2(8位自动重装载模式),以便生成稳定的波特率。
根据系统晶振频率和所需的波特率(9600bps),设置定时器1的重装载值。
配置串口工作模式为模式1(8位UART,可变波特率),并允许接收数据。
启动定时器1,使整个串口通信系统开始工作。
通过这些配置,你的单片机可以通过串口与外部设备(如蓝牙模块HC4)进行数据交换。
  • void UART_ISR() interrupt 4
  • interrupt 4:表示这是一个中断服务程序,对应的中断向量号为4。在51单片机中,中断向量号4对应的是串行口中断。
    UART_ISR:这是你为这个中断服务程序起的名字,你可以根据需要更改这个名字。
    RI 是接收中断标志位(Receive Interrupt Flag)。当串口接收到一个字节的数据时,硬件会自动将这个标志位置位(设置为1)。
    这个条件语句检查是否发生了接收中断。如果发生了接收中断,则执行大括号内的代码块。
  • char receivedData = SBUF;
    SBUF 是串行数据缓冲寄存器(Serial Buffer Register),用于存储接收到的数据或要发送的数据。
    这行代码从 SBUF 中读取接收到的数据,并将其存储在变量 receivedData 中。
  • RI = 0;
    清除接收中断标志位。每次处理完接收中断后,必须手动清除这个标志位,以便能够响应下一次接收中断。
  • SBUF = receivedData;:将接收到的数据写入 SBUF,准备通过串口发送出去。
  • while(!TI);:等待发送完成。
  • TI 是发送中断标志位(Transmit Interrupt
    Flag),当数据发送完成后,硬件会自动将这个标志位置位(设置为1)。这里使用一个循环来等待 TI 变为1,即等待数据发送完成。 TI =
    0;:清除发送中断标志位。每次发送完数据后,必须手动清除这个标志位,以便能够响应下一次发送中断。
clike 复制代码
总结
这段代码实现了一个简单的串行通信中断服务程序,其功能包括:

接收数据:当串口接收到一个字节的数据时,触发接收中断,并从中断服务程序中读取该数据。
控制LED:根据接收到的数据(字符 '1' 或 '0')来控制连接到P2.1引脚的LED的状态。
回发数据:将接收到的数据通过串口发送回去,以便在蓝牙设备上显示接收到的数据。
通过这种方式,你可以实现通过蓝牙模块发送指令来控制单片机上的LED,并且可以看到发送的数据被回传到蓝牙设备上进行验证。这种机制对于调试和双向通信非常有用。
相关推荐
雷门大师姐4 小时前
14.DS18B20温度传感器
单片机·嵌入式硬件
触角010100016 小时前
OLED屏幕开发全解析:从硬件设计到物联网显示实战 | 零基础入门STM32第五十二步
驱动开发·stm32·单片机·嵌入式硬件·物联网
蓑衣客VS索尼克6 小时前
无感方波开环强拖总结
经验分享·单片机·学习
傍晚冰川8 小时前
【江协科技STM32】ADC数模转换器-学习笔记
笔记·科技·stm32·单片机·嵌入式硬件·学习
c-u-r-ry309 小时前
009---基于Verilog HDL的单比特信号边沿检测
嵌入式硬件·fpga开发
土豆198910219 小时前
简记_ MCU管脚的防静电处理
嵌入式硬件
Whappy00110 小时前
第三节:基于Winform框架的串口助手小项目---串口操作《C#编程》
linux·单片机·c#
盐析大白兔12 小时前
STM32G431RBT6--(3)片上外设及其关系
stm32·单片机·嵌入式硬件
Joshua.X12 小时前
电脑总显示串口正在被占用处理方法
嵌入式硬件·串口·信息与通信·故障排查·232·485