首页 > 其他分享 >[STM32]STM32双机蓝牙串口通信

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

时间:2023-07-08 19:44:44浏览次数:45  
标签:CODE HAL Uart uint8 STM32 RxBuff USER 串口 双机

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

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

蓝牙模块配置

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

cubeMX配置

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

尝龟配置省略~

蓝牙串口模块部分:

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

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

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

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

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

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

代码部分

先来到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"

标签:CODE,HAL,Uart,uint8,STM32,RxBuff,USER,串口,双机
From: https://www.cnblogs.com/Asaka-QianXiang/p/17537731.html

相关文章

  • [Raspberry Pi]树莓派多线程下串口收发数据
    [RaspberryPi]树莓派多线程下串口收发数据鼠鼠用的是python开发树莓派,因为python是最优美的语言!少废话,直接上代码:importthreadingimportserialimportcv2ser=serial.Serial("/dev/ttyAMA0",115200)ser.timeout=5ifnotser.isOpen:ser.open()#打开串口......
  • 使用STM32的usb虚拟串口CDC_Transmit_FS打印freertos的任务列表vTaskList
    创建一个任务,打印信息后,把自己删除/*USERCODEENDHeader_func_showSysInfo*/voidfunc_showSysInfo(voidconst*argument){/*USERCODEBEGINfunc_showSysInfo*//*Infiniteloop*/for(;;){osDelay(1000);chartaskList[200];......
  • stm32芯片焊接区分第一脚
    辨认引脚:芯片的第一脚,正放芯片,面对型号字符,然后,在芯片的左下方为第一脚。也可以把芯片的缺口朝左放置,左下角也就是第一脚了。许多厂家会在第一脚旁边打上一个小圆点作为标记。知道了第一脚之后,按照反时针方向去走,依次是第2至第40引脚。(1脚与40脚遥遥相对)。 两个圆点......
  • STM32IO口模拟IIC时序
    正点原子IIC讲解:https://www.bilibili.com/video/BV1o8411n7o9/?spm_id_from=333.337.search-card.all.click&vd_source=e35b16eeaf19ae2b23ff9587a735ee20一、IIC总线1.物理层(1)支持多设备,一个IIC通讯总线中可以连接多个IIC设备,支持多个通讯主机及多个通讯从机;(2)两条线:双......
  • STM32下USB的使用
    一、介绍USB,即通用串行总线(UniversalSerialBus),包括USB协议和USB硬件两个方面,支持热插拔功能USB2.0使用四根线:VCC(5V)、GND、D+(3.3V)和D-(3.3V)(注:五线模式多了一个DI脚用于支持OTG模式,OTG为USB主机+USB设备双重角色)在USB主机上,D-和D+都接15K的电......
  • 正点原子内存管理实验室,keil mdk 和stm32cubeide gcc的函数替换
    https://www.cnblogs.com/RegressionWorldLine/p/11968467.html转载记录下 STM32.ld链接文件分析及一次bug解决过程问题描述原子板的代码中含有一个关于使用外部SRAM的功能,由于本人的开发板的SRAM只有512K,因此稍微修改了一下代码,同时使用GCC进行编译,但是这里却报错了,源码如......
  • RV1126调试-修改默认调试串口
    背景RK系列的SDK给的默认的调试串口都是uart2/1500000波特率,本次调试设备已经把console调试口改为了uart0,所以需要修改下uboot和内核,然后把波特率设为常用的115200。注:本次调试的SDK版本为原厂的V2.2版本1.uboot修改1)修改rv1126-evb.dts和rv1126-u-boot.dtsi把uart2改成uart......
  • STM32F10x 模拟空调内外机通讯
    1)内机为主 发送3A8000DB后由SMT32转成PWM0011101000010000000006ms为高        22ms   为低          46ms   为导码    2)外机为辅 收到内机发的PWM后,返加对就应的波形,同时将收到的波形加在前面。   ......
  • QT 记串口的用法
    QSerialPort用法一、在.pro文件添加serialportQT+=coreguiserialport二、头文件#include<QSerialPort>#include<QSerialPortInfo>三、开启串口1voidWidget::on_pushButton_clicked()//自己写的按钮为例2{3QSerialPortInfoinfo;4QLis......
  • 串口 RS232 RS485
    一、 接口的物理结构  1. RS232接口:RS232接口连接器使用DB-25的25芯插头座。一些设备与PC机连接的RS-232接口,因为不使用对方的传送控制信号,只需三条接口线,即“发送数据”、“接收数据”和“信号地”。所以采用DB-9的9芯插头座,传输线采用屏蔽双绞线。2. RS485接口:RS48......