[STM32]STM32双机蓝牙串口通信

1|0[STM32]STM32双机蓝牙串口通信

期末考完力,虽然GPA--,但也终于有空搓一搓32了

1|1蓝牙模块配置

我们先配置蓝牙模块,需要主从兼容,配置过程可以参考这个博客:https://blog.csdn.net/m0_59113542/article/details/122028037?spm=1001.2014.3001.5506

1|2cubeMX配置

然后就是MX里的配置。PS: 两块单片机烧的是同一个程序

尝龟配置省略~

蓝牙串口模块部分:

开启USART1,Baud Rate设置成9600,并且使能全局中断

为了方便测试,我们需要配置OLED:

开启SPI1,设置为全双工模式,让PC15为推挽输出,取名为OLED_RES;PA4也为推挽输出,取名为SPI1_NSS;PB10同上,取名为OLED_DC。

然后还可以配置一下按键方便测试:

设置PB14,PB13,PB12为外部中断,下降沿触发(根据自己PCB个性化设置),同时别忘记使能EXTI line中断

然后尝龟配置,生成代码~

1|3代码部分

先来到usart.h,加入如下代码:

/* USER CODE BEGIN 0 */ #include "string.h" #include "main.h" uint8_t aRxBuffer; uint8_t Uart_RxBuff[256]; uint8_t Uart_Rx_Cnt; uint8_t Uart_RxFlag; uint8_t cAlmStr[] = "Warning!\r\n"; int rxUpdateFlag = 0; int startReadFlag = 0; /* USER CODE END 0 */ /* USER CODE BEGIN 1 */ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { /* Prevent unused argument(s) compilation warning */ UNUSED(huart); if(huart == &huart1 && rxUpdateFlag == 0) { if(Uart_Rx_Cnt >= 255) // 溢出判断 { Uart_Rx_Cnt = 0; memset(Uart_RxBuff,0x00,sizeof(Uart_RxBuff)); HAL_UART_Transmit(&huart1, (uint8_t *)&cAlmStr, sizeof(cAlmStr),0xFFFF); } else // 没有溢出 { if(aRxBuffer == '@') { startReadFlag = 1; } if(startReadFlag == 1) { Uart_RxBuff[Uart_Rx_Cnt++] = aRxBuffer; // 接收数据转存 if((Uart_RxBuff[Uart_Rx_Cnt-1] == 0x0A)&&(Uart_RxBuff[Uart_Rx_Cnt-2] == 0x0D)) //判断结束 { startReadFlag = 0; rxUpdateFlag = 1; // 数据更新 } } } } HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1); //再开启接收中??? } /* USER CODE END 1 */

这部分代码主要是按一定格式(后面会说明)接收不定长数据

然后就是usart.h:

/* USER CODE BEGIN Prototypes */ extern uint8_t aRxBuffer; extern uint8_t Uart_RxBuff[256]; extern uint8_t Uart_Rx_Cnt; extern uint8_t Uart_RxFlag; extern int rxUpdateFlag; /* USER CODE END Prototypes */

这个就是声明外部变量,方便main.c里面调用。

然后就是main.c:

/* USER CODE BEGIN Includes */ #include "string.h" #include "stdio.h" #include "u8g2.h" #include "screen.h" /* USER CODE END Includes */ /* USER CODE BEGIN PV */ char rxStr[256]; char drawBuffer[256]; int32_t tick; /* USER CODE END PV */ /* USER CODE BEGIN 2 */ tick = HAL_GetTick(); HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1); oledInit(); /* USER CODE END 2 */ /* USER CODE BEGIN 3 */ if(rxUpdateFlag == 1) // 收到新数据,开始处理数据 { strcpy(rxStr, (char *)Uart_RxBuff); memset(Uart_RxBuff,0x00,sizeof(Uart_RxBuff)); // flag置位 rxUpdateFlag = 0; Uart_Rx_Cnt = 0; } u8g2_FirstPage(&u8g2); do { u8g2_DrawStr(&u8g2, 0, 15, rxStr); u8g2_DrawStr(&u8g2, 0, 30, drawBuffer); }while(u8g2_NextPage(&u8g2)); /* USER CODE END 3 */ /* USER CODE BEGIN 4 */ void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if(GPIO_Pin == GPIO_PIN_14) // KEY_1 { if(HAL_GetTick() - tick > 200) // 消抖是个好习惯 { HAL_UART_Transmit(&huart1, (uint8_t *)"@1\r\n", sizeof("@1\r\n"), HAL_MAX_DELAY); strcpy(drawBuffer, "KEY1 send ok!"); tick=HAL_GetTick(); } } if(GPIO_Pin == GPIO_PIN_13) // KEY_2 { if(HAL_GetTick() - tick > 200) { HAL_UART_Transmit(&huart1, (uint8_t *)"@2\r\n", sizeof("@1\r\n"), HAL_MAX_DELAY); strcpy(drawBuffer, "KEY2 send ok!"); tick=HAL_GetTick(); } } if(GPIO_Pin == GPIO_PIN_12) // KEY_3 { if(HAL_GetTick() - tick > 200) { HAL_UART_Transmit(&huart1, (uint8_t *)"@3\r\n", sizeof("@1\r\n"), HAL_MAX_DELAY); strcpy(drawBuffer, "KEY3 send ok!"); tick=HAL_GetTick(); } } } /* USER CODE END 4 */

之后,我们只要按下按键就可以啦~

注:消息发送格式:"@XXXXXX\r\n"


__EOF__

本文作者Asaka
本文链接https://www.cnblogs.com/Asaka-QianXiang/p/17537731.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   Akasa  阅读(567)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示