水比赛专用 您所在的位置:网站首页 电脑调试器是什么样的 水比赛专用

水比赛专用

2024-07-10 13:34| 来源: 网络整理| 查看: 265

文章目录 1、蓝牙调试器介绍2、功能体验3、程序移植4、实现效果5、源码 做比赛的时候免不了要做一些页面方面的展示,亦或者一些遥控什么的方面的远程启动,常见的无线通信方式如蓝牙,wifi等是很多大学生竞赛中的常客,因此这里我就把我之前用的很熟的一款蓝牙调试器给分享下,同时也算是做个记录吧!

该调试器是某大佬做的,我只是应用,这里特别感谢这位大佬,提供了这么好用的工具,yyds!,原文链接如下:https://www.jianshu.com/p/1a8262492619

1、蓝牙调试器介绍

此蓝牙调试器为上面提到的大佬一个月开发的,其基于安卓设备,通过安卓设备的蓝牙通信功能实现单片机的无线调试。编写这款软件的目的主要是为了盈利, 嗯,当然是为了广大的单片机开发爱好者,拯救他们于繁琐的调试步骤之中,常用的logo如下: 在这里插入图片描述

这个我们要用的时候直接去应用市场下载即可,经过我个人总结,该调试器支持的功能如下所示:

1、普通的串口收发显示2、类似普通蓝牙调试器的按钮收发3、支持自定义功能的界面开发,界面支持摇杆,按钮,开关等常见的设备4、支持对话框等页面

基本就是有的东西都有了,可以当成一些遥控来用了,这里再次感谢作者!

2、功能体验

首先是这个蓝牙连接这里,这里有个老大的bug,这是我对这个软件唯一不满的地方了,这里要打开定位才能用,对于我一个平时不怎么开定位的人来说,真是太难受了!,这里一定要注意,不然不太能搜到设备! 在这里插入图片描述

下面来看下一个基本的蓝牙调试器应该有的页面普通按钮页面,这里也就是比较常规 在这里插入图片描述 然后是对话框,对话框也是很基本的功能了 在这里插入图片描述 好,下面就是重点这个可以自己编辑的页面了,下面是我之前做的一个项目的页面,基本就是托快快来实现这个页面的编辑,然后就是一些绑定数据了,所以在进行这个页面的编辑之前最重要的还是先设置我们的数据

在这里插入图片描述 这里作者将数据按照类型来分类,因为他们所占的字节不一样,作者这样设置就可以方便的处理数据了,其中数据包的构成作者在这个下图的数据包结构设置一栏中已经进行了说明,是可以很清楚的看到的。 在这里插入图片描述 当然就是接收数据包也是需要编辑的,接收数据包也是跟发送数据包一样的布局设置 在这里插入图片描述 然后这里作者还指出了蓝牙收发一个特点就是这里讲到的延时,蓝牙数据量确实是比较小的,所以发送大量数据自然就会产生一定的延时,这里作者已经提到了,所以这个系统不太适合就是需要迅速反馈的系统的! 在这里插入图片描述 同时作者还提供了一些例程代码,主要是包含轮询,中断还有DMA三种方式进行的收发,源码在我上面贴的作者的链接中可以找到这里不再进行赘述,下面我将用HAL库的方式对他进行移植,以方便我们后续的开发设计!

3、程序移植

首先我们需要定义好用到的串口,串口参数这里保持默认即可! 这里注意:

蓝牙是用AT指令开发的,默认的波特率是9600,可以先用串口助手对波特率进行相应的修改蓝牙的AT指令类似esp8266的,基本上去淘宝店的资料页都能找到怎么用AT指令进行设置HC-05,HC-06这种的都有一个按键,设置AT指令的时候别忘了按下那个按键

在这里插入图片描述 之后是开启DMA,前面已经说过了,要移植肯定是移植DMA的,移植常规轮询方法和中断方法的都没什么意思,所以这里首选DMA,这才是最高效的方案! 在这里插入图片描述 下面我嫩来认识下.h文件,这个文件其实就是每次修改工程要改的东西了,其实挺重要的就是,这里作者提供了宏参数供我们修改,这里的宏参数要和设置的一样,这样才能确保我们通信的正常,因为这个决定了我们每次数据包的大小! 在这里插入图片描述 下面就是数据接收函数了,数据接收函数就是要注意这个接收函数的这里计算数据长度的这个变量! 在这里插入图片描述 数据发送函数,直接使用官方的库函数即可,不用这么啰嗦,因为CUBEMX都帮我们配置好了 在这里插入图片描述 之后就可以在主函数中调用来实现效果了!

4、实现效果

在初始化中我们需要开启DMA接收这个参数,这样才可以接受DMA的数据,因为DMA开的是循环,所以我们后面就可以不用关注他了 在这里插入图片描述 这里我们要读取数据,需要定义数据结构体,并周期性的读取数据,官方给的要求是每秒不低于十次,这里可以根据自己的需要进行设置! 在这里插入图片描述 将程序下载到开发板,并根据我们之前在手机上位机中设置的摇杆,开关灯,移动摇杆开关等,就可以看到数据变化了! 在这里插入图片描述

5、源码

注意本源码适用于串口2,需要修改为其他串口请根据我前面提到的方法去修改!

valuepack.h

/* * valuepack.c * * Created on: Mar 31, 2022 * Author: LX */ #include "valuepack.h" #include "dma.h" #include "usart.h" //DMA下进行的数据传输 unsigned char bits[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; const unsigned int VALUEPACK_INDEX_RANGE = VALUEPACK_BUFFER_SIZE 3) + TX_BYTE_NUM + (TX_SHORT_NUM rdi = rdIndex % VALUEPACK_BUFFER_SIZE; rdii = rdi + 1; if (vp_rxbuff[rdi] == PACK_HEAD) { if (vp_rxbuff[(rdi + RXPACK_BYTE_SIZE + 2) % VALUEPACK_BUFFER_SIZE] == PACK_TAIL) { // 计算校验和 sum = 0; for (short s = 0; s // 提取数据包数据 一共有五步, bool byte short int float // 1. bool #if RX_BOOL_NUM > 0 idc = (uint32_t)rx_pack_ptr->bools; idl = (RX_BOOL_NUM + 7) >> 3; for (idi = 0; idi if (rdii >= VALUEPACK_BUFFER_SIZE) rdii -= VALUEPACK_BUFFER_SIZE; (*((unsigned char *)idc)) = vp_rxbuff[rdii]; rdii++; idc++; } #endif // 3.short #if RX_SHORT_NUM > 0 idc = (uint32_t)(rx_pack_ptr->shorts); idl = RX_SHORT_NUM if (rdii >= VALUEPACK_BUFFER_SIZE) rdii -= VALUEPACK_BUFFER_SIZE; (*((unsigned char *)idc)) = vp_rxbuff[rdii]; rdii++; idc++; } #endif // 5.float #if RX_FLOAT_NUM > 0 idc = (uint32_t)(&(rx_pack_ptr->floats[0])); idl = RX_FLOAT_NUM rdIndex++; err++; } } else { rdIndex++; err++; } } else { rdIndex++; err++; } } last_index = this_index; return isok; } void sendBuffer(unsigned char *p, unsigned short length) { // DMA_DeInit(DMA1_Channel4); // dma.DMA_DIR = DMA_DIR_PeripheralDST; // dma.DMA_M2M = DMA_M2M_Disable; // dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // dma.DMA_PeripheralBaseAddr = (uint32_t) & (USART1->DR); // dma.DMA_Priority = DMA_Priority_High; // dma.DMA_BufferSize = length; // dma.DMA_MemoryBaseAddr = (uint32_t)p; // dma.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; // dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; // dma.DMA_MemoryInc = DMA_MemoryInc_Enable; // dma.DMA_Mode = DMA_Mode_Normal; // DMA_Init(DMA1_Channel4, &dma); // DMA_Cmd(DMA1_Channel4, ENABLE); HAL_UART_Transmit_DMA(&huart2,p,length); } unsigned short loop; unsigned char valuepack_tx_bit_index; unsigned char valuepack_tx_index; void sendValuePack(TxPack *tx_pack_ptr) { int i; vp_txbuff[0] = 0xa5; sum = 0; // 由于结构体中不同类型的变量在内存空间的排布不是严格对齐的,中间嵌有无效字节,因此需要特殊处理 valuepack_tx_bit_index = 0; valuepack_tx_index = 1; #if TX_BOOL_NUM > 0 for (loop = 0; loop valuepack_tx_bit_index = 0; valuepack_tx_index++; } } if (valuepack_tx_bit_index != 0) valuepack_tx_index++; #endif #if TX_BYTE_NUM > 0 for (loop = 0; loop vp_txbuff[valuepack_tx_index] = tx_pack_ptr->shorts[loop] & 0xff; vp_txbuff[valuepack_tx_index + 1] = tx_pack_ptr->shorts[loop] >> 8; valuepack_tx_index += 2; } #endif #if TX_INT_NUM > 0 for (loop = 0; loop i = *(int *)(&(tx_pack_ptr->floats[loop])); vp_txbuff[valuepack_tx_index] = i & 0xff; vp_txbuff[valuepack_tx_index + 1] = (i >> 8) & 0xff; vp_txbuff[valuepack_tx_index + 2] = (i >> 16) & 0xff; vp_txbuff[valuepack_tx_index + 3] = (i >> 24) & 0xff; valuepack_tx_index += 4; } #endif for (unsigned short d = 1; d #if RX_BOOL_NUM > 0 unsigned char bools[RX_BOOL_NUM]; #endif #if RX_BYTE_NUM > 0 char bytes[RX_BYTE_NUM]; #endif #if RX_SHORT_NUM > 0 short shorts[RX_SHORT_NUM]; #endif #if RX_INT_NUM > 0 int integers[RX_INT_NUM]; #endif #if RX_FLOAT_NUM > 0 float floats[RX_FLOAT_NUM]; #endif char space; // 无意义,只为了不让结构体为空,结构体为空会报错。 } RxPack; // 初始化 valuepack 包括一些必要的硬件外设配置 //void initValuePack(int baudrate); // 需要保证至少每秒执行10次该函数 // 该函数的主要过程是先解析接收的缓冲区,如果接收到完整的RX数据包,则解析RX数据包中的数据,然后开始串口发送TX数据包 。 // 接收到数据包时 返回 1 ,否则返回 0 unsigned char readValuePack(RxPack *rx_pack_ptr); // 发送数据包 void sendValuePack(TxPack *tx_pack_ptr); #define PACK_HEAD 0xa5 #define PACK_TAIL 0x5a #endif /* VALUEPACK_H_ */


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有