【蓝牙显示波形】使用MSPM0G3519通过HC-04透传数据到手机显示波形
1. 引言
没错还是21年A题,用两天搞定所有,当天晚上就开始写文章了哈哈。此题最后的要求是在手机上显示一个周期的波形和thd以及各谐波幅值,由于技术力不足,不会自己写QT,同时也考虑到要节省时间,就选择了一个最简单的方式来在手机显示波形:HC-04+蓝牙调试器。
2. 蓝牙调试器的选择
怼!它的名字就叫做“蓝牙调试器” 神器!简单方便又好用,资料还多。这里特别感谢作者修道的基,下面附上作者账号以及此调试器的所有资料:
作者账号:修道的基
作者GitHub开源程序:ValuePack数据包
蓝牙调试器详细介绍:提高开发效率-蓝牙调试器

2.1 控件操作
注:这里只说接收,其他操作同理。
- 连接蓝牙
- 专业调试->点击加号(➕)->添加调试工程(横屏/竖屏)
- 通信设置->要接受几个不同变量的数据就增加加几个xx类型变量->通信模式->仅接收
- 编辑控件->添加你想要的控件(文本/可编辑文本/按钮/滑块/X-T一维波形图)->每一个控件都要链接一个刚刚添加的变量(要显示波形必须就要循环打印波形的数据)
- 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)
重要操作:测试指令、波特率查询、波特率设置、配对密码。 然后,然后就没了。

博客导航
本文来自博客园,作者:膝盖中箭卫兵,转载请注明原文链接:https://www.cnblogs.com/hai-feng-dev/p/18990332

浙公网安备 33010602011771号
https://orcid.org/0000-0001-5102-772X