MSP432蓝牙模块实现主从机通信

MSP432P401R实现HC05蓝牙模块主从机通信

对HC05蓝牙模块有什么不懂的可以看我这篇博客:HC05蓝牙模块(STM32)

一、进入AT模式更改参数

(一)连接电脑

USB转TTL和蓝牙模块连接好后,插上电脑。(这里仅用4根杜邦线连接即可)
在这里插入图片描述
进入AT模式的两种方法。

  • 方法一:先按住按键不放,再给模块上电。此时LED 2S闪一次,进入AT模式。波特率固定为38400

  • 方法二:模块直接上电。此时LED灯快闪(1s两次)。再按下按键,模块也会进入AT指令,此时LED还是快闪。这个时候的波特率和自己设置的一样,默认为9600。1位停止位,无奇偶校验。

(二)进入AT模式更改参数

在使用HC05蓝牙模块进行主从机通信前需要更改以下参数

  • 蓝牙角色
    先使用AT命令查看蓝牙角色
AT+ROLE?

再将两个蓝牙分别改为一主一从

AT+ROLE=<Param>

Param:参数取值如下:

0——从角色(Slave)

1——主角色(Master)

2——回环角色(Slave-Loop)

默认值:0(从机)

更改将两个蓝牙角色分别改为一主一从,否则无法实现主从机通信

  • 蓝牙密码
    在实现主从机通信中,蓝牙的密码必须一致
    操作和更改蓝牙角色一样
    蓝牙密码默认为1234,建议改为其他密码,防止比赛时误连

查询密码

AT+PSWD?

设置密码

AT+PSWD=<Param>

对于其他参数,可改可不改,不改也没有影响

二、代码解析

(一)串口

在MSP432中蓝牙通信时我使用了串口A1

串口初始化
不懂MSP432P401R串口通信的可以看我的这篇博客:MSP432 串口通信

void uart1_init(uint32_t baudRate)
{
#ifdef EUSCI_A_UART_7_BIT_LEN
	//固件库v3_40_01_02
	//默认SMCLK 48MHz 比特率
	const eUSCI_UART_ConfigV1 uartConfig =
		{
			EUSCI_A_UART_CLOCKSOURCE_SMCLK,				   // SMCLK Clock Source
			312,										   // BRDIV = 312
			8,											   // UCxBRF = 8
			1,											   // UCxBRS = 1
			EUSCI_A_UART_NO_PARITY,						   // No Parity
			EUSCI_A_UART_LSB_FIRST,						   // MSB First
			EUSCI_A_UART_ONE_STOP_BIT,					   // One stop bit
			EUSCI_A_UART_MODE,							   // UART mode
			EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION, // Oversampling
			EUSCI_A_UART_8_BIT_LEN						   // 8 bit data length
		};
	eusci_calcBaudDividers((eUSCI_UART_ConfigV1 *)&uartConfig, baudRate); //配置波特率
#else
	//固件库v3_21_00_05
	//默认SMCLK 48MHz 比特率
	const eUSCI_UART_Config uartConfig =
		{
			EUSCI_A_UART_CLOCKSOURCE_SMCLK,				   // SMCLK Clock Source
			312,										   // BRDIV = 312
			8,											   // UCxBRF = 8
			1,											   // UCxBRS = 1
			EUSCI_A_UART_NO_PARITY,						   // No Parity
			EUSCI_A_UART_LSB_FIRST,						   // MSB First
			EUSCI_A_UART_ONE_STOP_BIT,					   // One stop bit
			EUSCI_A_UART_MODE,							   // UART mode
			EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION, // Oversampling
		};
	eusci_calcBaudDividers((eUSCI_UART_Config *)&uartConfig, baudRate); //配置波特率
#endif
	// 1.配置GPIO复用
	MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P2, GPIO_PIN2 | GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION);
	MAP_UART_initModule(EUSCI_A1_BASE, &uartConfig); // 3.初始化串口
	MAP_UART_enableModule(EUSCI_A1_BASE);			 // 4.开启串口模块

	MAP_UART_enableInterrupt(EUSCI_A1_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT); // 5.开启串口相关中断
	MAP_Interrupt_enableInterrupt(INT_EUSCIA1);								 // 6.开启串口端口中断
}

串口中断服务函数

// Uart1接收中断
void EUSCIA1_IRQHandler(void)
{
    uint32_t status = MAP_UART_getEnabledInterruptStatus(BLUETOOTH_UART);
    if (status & EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG) //接收中断
    {
        MAP_UART_clearInterruptFlag(BLUETOOTH_UART, EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG); // 清除中断标志位

        Bluetooth_Uart_Rx_Temp = MAP_UART_receiveData(BLUETOOTH_UART); // 临时接收

        if (Bluetooth_Uart_Rx_Index < BLUETOOTH_UART_RX_LENGTH_MAX) // 接收缓冲是否溢出
        {
            SW_Timer_Tick = HAL_GetTick() + 20; // 软件定时复位20ms

            Bluetooth_Uart_Rx_Buffer[Bluetooth_Uart_Rx_Index] = Bluetooth_Uart_Rx_Temp; // 放入缓存
            Bluetooth_Uart_Rx_Index++;                                                  // 索引加1
        }
        else // 强制标记接收完成
        {
            SW_Timer_Tick = HAL_GetTick() - 1;
        }
    }
}

编写串口printf函数
注意:这里要引入#include "stdarg.h"的头文件,因为va_list等的定义在该头文件中

//串口1,printf 函数
//确保一次发送数据不超过USART3_MAX_SEND_LEN字节
void printf_uart1(char *fmt, ...)
{
	uint16_t i, j;
	va_list ap;
	va_start(ap, fmt);
	vsprintf((char *)UART1_TX_BUF, fmt, ap);
	va_end(ap);
	i = strlen((const char *)UART1_TX_BUF); //此次发送数据的长度
	for (j = 0; j < i; j++)					//循环发送数据
	{
		MAP_UART_transmitData(EUSCI_A1_BASE, UART1_TX_BUF[j]);
	}
}

(二)定时器32

不懂MSP432P401R串口通信的可以看我的这篇博客:MSP432 定时器32

这里的定时器32是用来定时20ms用来控制串口的接收数据

定时器32初始化

void Tim32_1_Int_Init(uint32_t aar, uint8_t psc)
{
    MAP_Timer32_initModule(TIMER32_1_BASE, psc, TIMER32_32BIT, TIMER32_PERIODIC_MODE);

    MAP_Timer32_setCount(TIMER32_1_BASE, aar);

    MAP_Timer32_enableInterrupt(TIMER32_1_BASE);

    MAP_Timer32_startTimer(TIMER32_1_BASE, false); //连续计数模式 false

    MAP_Interrupt_enableInterrupt(INT_T32_INT2);
}

定时器32服务函数

/* Timer32 ISR */
static vu32 uwTick = 0;
void T32_INT2_IRQHandler(void)
{
    MAP_Timer32_clearInterruptFlag(TIMER32_1_BASE);

    /*开始填充用户代码*/

    uwTick++; // 1ms加1

    /*结束填充用户代码*/
}

// 对外开发函数
u32 HAL_GetTick(void)
{
    return uwTick;
}

(三)主函数

主机给从机发送消息使用printf_uart1("{1}");即可
注意:发送的数据必须是以“{”开头,以“}”结尾,否则从机接收数据就会报错

int main(void)
{
    SysInit();          // 第3讲 时钟配置
    uart0_init(115200); // 第7讲 串口配置
    uart1_init(9600);   // 第7讲 串口配置(蓝牙)
		delay_init();

    // 不分频,ARR为48000,周期为48000000 / 48000 = 1ms 作为时基
    Tim32_1_Int_Init(48000, TIMER32_PRESCALER_1);

    printf("[Log] Init Completed! \r\n");
		printf("[Log] Uart1 接收数据的格式为 \"{\" + u8 + \"}\" \r\n");

    MAP_Interrupt_enableMaster(); // 开启总中断

    while (1)
    {
//				printf_uart1("{1}");
//				delay_ms(1000);
        Bluetooth_Check_Data_Task();
				
        if (Bluetooth_Rx_Data_Analysis_State)
        {
            // 打印一下接收数据
            printf("[Bluetooth Data] x1: %c\r\n", Bluetooth_Rx_Data[0]); //, Bluetooth_Rx_Data[1]);
						printf("%c\r\n", Bluetooth_Rx_Data[0]); //, Bluetooth_Rx_Data[1]);
            // 清除解析完成状态 清除缓存
            Bluetooth_Rx_Data_Analysis_State = 0;
            memset(Bluetooth_Rx_Data, 0, sizeof(Bluetooth_Rx_Data));
        }
    }
}

三、实验现象

在这里插入图片描述
在这里插入图片描述

文章在这里就结束了,最后我会附上完整工程,如有不懂的地方,欢迎评论区留言,我都会一 一解答

  • 15
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 22
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 22
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

命运从未公平

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值