【蓝牙显示波形】使用MSPM0G3519通过HC-04透传数据到手机显示波形

1. 引言

没错还是21年A题,用两天搞定所有,当天晚上就开始写文章了哈哈。此题最后的要求是在手机上显示一个周期的波形和thd以及各谐波幅值,由于技术力不足,不会自己写QT,同时也考虑到要节省时间,就选择了一个最简单的方式来在手机显示波形:HC-04+蓝牙调试器。

2. 蓝牙调试器的选择

怼!它的名字就叫做“蓝牙调试器” 神器!简单方便又好用,资料还多。这里特别感谢作者修道的基,下面附上作者账号以及此调试器的所有资料:
作者账号:修道的基
作者GitHub开源程序:ValuePack数据包
蓝牙调试器详细介绍:提高开发效率-蓝牙调试器
image

2.1 控件操作

注:这里只说接收,其他操作同理。

  1. 连接蓝牙
  2. 专业调试->点击加号(➕)->添加调试工程(横屏/竖屏)
  3. 通信设置->要接受几个不同变量的数据就增加加几个xx类型变量->通信模式->仅接收
  4. 编辑控件->添加你想要的控件(文本/可编辑文本/按钮/滑块/X-T一维波形图)->每一个控件都要链接一个刚刚添加的变量(要显示波形必须就要循环打印波形的数据)
  5. ARM发送数据,手机接收测试。(下面会提到)

3. 蓝牙调试器ValuePack数据包

这里既然看了有帮助,就顺便帮忙推推流:【功能实现总结】【STM32】【HAL库】 蓝牙显示采样波形 这个博主的文章也有很大帮助。

3.1 程序

我这是在M0上的程序,其实也就一个串口发送函数的区别,直接拿来用就行了,博主封装的很好。

ValuePack.c:

#include "ValuePack.h"

unsigned char *valuepack_tx_buffer;
unsigned short valuepack_tx_index;
unsigned char valuepack_tx_bit_index;
unsigned char valuepack_stage;

// 1. 开始将数据打包,需传入定义好的数组(需保证数组长度足以存放要发送的数据)
void startValuePack(unsigned char *buffer)
{
	valuepack_tx_buffer = buffer;
	valuepack_tx_index = 1;
	valuepack_tx_bit_index = 0;
	valuepack_tx_buffer[0] = PACK_HEAD;
	valuepack_stage = 0;
}

// 2. 向数据包中放入各类数据,由于数据包的顺序结构是固定的,因此注意严格以如下的顺序进行存放,否则会出现错误
void putBool(unsigned char b)
{
if(valuepack_stage<=1)
{
   if(b)
      valuepack_tx_buffer[valuepack_tx_index] |= 0x01<<valuepack_tx_bit_index;
	 else
			valuepack_tx_buffer[valuepack_tx_index] &= ~(0x01<<valuepack_tx_bit_index);

  valuepack_tx_bit_index++;
	if(valuepack_tx_bit_index>=8)
	{
		valuepack_tx_bit_index = 0;
		valuepack_tx_index++;
	}
	valuepack_stage = 1;
}
}

void putByte(char b)
{
if(valuepack_stage<=2)
{
	if(valuepack_tx_bit_index!=0)
	{	
		valuepack_tx_index++;
	  valuepack_tx_bit_index = 0;
	}
	valuepack_tx_buffer[valuepack_tx_index] = b;
	valuepack_tx_index++;
	
	valuepack_stage = 2;
}
}
void putShort(short s)
{
if(valuepack_stage<=3)
{
		if(valuepack_tx_bit_index!=0)
	{	
		valuepack_tx_index++;
	  valuepack_tx_bit_index = 0;
	}
	valuepack_tx_buffer[valuepack_tx_index] = s&0xff;
	valuepack_tx_buffer[valuepack_tx_index+1] = s>>8;
	
	valuepack_tx_index +=2;
	valuepack_stage = 3;
}
}
void putInt(int i)
{
if(valuepack_stage<=4)
{
		if(valuepack_tx_bit_index!=0)
	{	
		valuepack_tx_index++;
	  valuepack_tx_bit_index = 0;
	}
	
	valuepack_tx_buffer[valuepack_tx_index] = i&0xff;
	valuepack_tx_buffer[valuepack_tx_index+1] = (i>>8)&0xff;
	valuepack_tx_buffer[valuepack_tx_index+2] = (i>>16)&0xff;
	valuepack_tx_buffer[valuepack_tx_index+3] = (i>>24)&0xff;
	
	valuepack_tx_index +=4;
	
	valuepack_stage = 4;
}
}
int fi;
void putFloat(float f)
{
if(valuepack_stage<=5)
{
		if(valuepack_tx_bit_index!=0)
	{	
		valuepack_tx_index++;
	  valuepack_tx_bit_index = 0;
	}
	
	fi = *(int*)(&f);
	valuepack_tx_buffer[valuepack_tx_index] = fi&0xff;
	valuepack_tx_buffer[valuepack_tx_index+1] = (fi>>8)&0xff;
	valuepack_tx_buffer[valuepack_tx_index+2] = (fi>>16)&0xff;
	valuepack_tx_buffer[valuepack_tx_index+3] = (fi>>24)&0xff;
	valuepack_tx_index +=4;
	valuepack_stage = 5;
}
}

// 3. 结束打包,函数将返回 数据包的总长度
unsigned short endValuePack()
{
  unsigned char sum=0;
	for(int i=1;i<valuepack_tx_index;i++)
	{
		sum+=valuepack_tx_buffer[i];
	}
	valuepack_tx_buffer[valuepack_tx_index] = sum;
	valuepack_tx_buffer[valuepack_tx_index+1] = PACK_TAIL;
	return valuepack_tx_index+2;
}

// 4. 发送数据
void sendBuffer(UART_Regs *uart, unsigned char *p, unsigned short length)
{
    for (int i = 0; i < length; i++) { 
        DL_UART_transmitDataBlocking(uart, (uint8_t)*p++);
    }
}

ValuePack.h:

#ifndef __VALUEPACK_H
#define __VALUEPACK_H

#include "headers.h"

// 本程序通过 USART 将数据包发送到手机上,不支持接收的功能

//  初始化 valuepack 一些必要的硬件外设配置
void initValuePack(int baudrate);

////////////////////////////////////////////////////////////////////////////////////////////
// 以下函数是按顺序调用的,先开始打包,然后依次存放数据,最后结束打包。结束打包后,使用串口将数组发送出去。

// 1. 开始将数据打包,需传入定义好的数组(需保证数组长度足以存放要发送的数据)

void startValuePack(unsigned char *buffer);

// 2. 向数据包中放入各类数据,由于数据包的结构是固定的,因此注意严格以如下的顺序进行存放,否则会出现错误

void putBool(unsigned char b);
void putByte(char b);
void putShort(short s);
void putInt(int i);
void putFloat(float f);

// 3. 结束打包,函数将返回 数据包的总长度
unsigned short endValuePack(void);

// 4. 发送数据

void sendBuffer(UART_Regs *uart, unsigned char *p, unsigned short length);

#define PACK_HEAD 0xA5   
#define PACK_TAIL 0x5A

#endif

调用:
!!!千万注意,要按蓝牙调试器上你设定的接收包的顺序来调用 !!!
我这里是在一个循环里发送的数据,目的是显示波形

                    for (uint16_t i = POINT ; i > 0; i --) {/* 利用基波和各个谐波幅值合成波形 */
                        wave_buf = harm_amp[0] * arm_sin_f32(0.030 * i) + 
                                   harm_amp[1] * arm_sin_f32(0.030 * i * 2) + 
                                   harm_amp[2] * arm_sin_f32(0.030 * i * 3) + 
                                   harm_amp[3] * arm_sin_f32(0.030 * i * 4) + 
                                   harm_amp[4] * arm_sin_f32(0.030 * i * 5);
                        wave_buf_printf = 20 * wave_buf + 150;
                        wave_data[i] = 400 * (harm_amp[0] * arm_sin_f32(0.065 * i) + 
                                              harm_amp[1] * arm_sin_f32(0.065 * i * 2) + 
                                              harm_amp[2] * arm_sin_f32(0.065 * i * 3) + 
                                              harm_amp[3] * arm_sin_f32(0.065 * i * 4) + 
                                              harm_amp[4] * arm_sin_f32(0.065 * i * 5));
                        /* 蓝牙 数据包 手机显示 */
                        Set_CurrentUART(UART2_IDX);
                        unsigned char buffer[50] = {0};
                        startValuePack(buffer);
                        putFloat(wave_data[i]);	// 波形
                        putFloat(harm_amp[0] / harm_amp[0]);	// V1
                        putFloat(harm_amp[1] / harm_amp[0]);	// V2
                        putFloat(harm_amp[2] / harm_amp[0]);	// V3
                        putFloat(harm_amp[3] / harm_amp[0]);	// V4
                        putFloat(harm_amp[4] / harm_amp[0]);	// V5
                        putFloat(thd * 100.0f);	// THD
                        sendBuffer(UART_2_INST, buffer, endValuePack());
                    }

3.2 HC-04

这个其实没什么好讲的,关键就是一个,找到这个官方的HC串口助手。

串口助手:HC-T串口助手V1.7.2(2023.3.10)

重要操作:测试指令、波特率查询、波特率设置、配对密码。 然后,然后就没了。

image

博客导航

博客导航

posted @ 2025-07-17 20:49  膝盖中箭卫兵  阅读(229)  评论(0)    收藏  举报
ORCID iD icon https://orcid.org/0000-0001-5102-772X