匿名上位机V7波形显示教程-简单能用

匿名上位机V7波形显示教程-简单能用

  • 匿名上位机V7下位机数据格式
  • 根据匿名上位机V7的手册说明文档,编写对应的指令
  • 在主函数中初始化ANDmessage驱动
  • 连接匿名上位机V7

匿名上位机V7下位机数据格式

在这里插入图片描述
DATA区域内容:
举例说明DATA区域格式,例如上文,需要发送ABC三个数据,AB为int16 型,C为int32 型,那么ABC三个数据共2+2+4=8字节,那么LEN字节为8,帧ID 为0xF1,DATA区域依次放入ABC三个数据,然后计算SC、AC,完成后将本帧发送至上位机即可。

根据匿名上位机V7的手册说明文档,编写对应的指令

stm32程序使用H库,串口和其他的初始化就不在这里解说各位大佬一定很熟悉了,这里主要生成驱动匿名上位机的代码。

粘贴生成.h头文件
ANDmessage.h

#ifndef  _ANDmessage_H
#define  _ANDmessage_H
//#include "stm32f205xx.h"
#include <string.h>
#include "main.h"//目标地址宏定义
#define FRAME_HEADER 		  0XAA   //<匿名协议固定帧头
#define GENERAL_OUTPUT_ADDR	  0XFF   //<广播型输出
#define HOST_ADDR			  0XAF   //<向上位机输出
#define PRO_ADDR			  0X05   //<拓空者PRO飞控
#define SHUCHUAN_ADDR		  0X10   //<匿名数传
#define GUANGLIU_ADDR		  0X22   //<匿名光流
#define UWB_ADDR			  0X30   //<匿名UWB
#define IMU_ADDR			  0X60   //<匿名凌霄IMU
#define LINGXIAO_ADDR		  0X61   //<匿名凌霄飞控#define HWTYPE            0X01   //<用于存储下位机的类型信息
#define ID_INFO5 		  0X05   //<预留位
#define ID_INFO6	      0X06   //<预留位
#define ID_INFO7		  0X07   //<预留位
#define ID_INFO8		  0X08   //<预留位
#define ID_INFO9		  0X09   //<预留位
#define ID_INFO10		  0X0A   //<预留位#define ANO_BLACK         0X00  //<字符黑色打印
#define ANO_RED           0X01  //<字符红色打印
#define ANO_GREEN         0X02  //<字符绿色打印//32位数据进行四个字节剥离拆分,从低位到高位
#define BYTE0(temp)	   (*(char*)(&temp))
#define BYTE1(temp)	   (*((char*)(&temp)+1))
#define BYTE2(temp)	   (*((char*)(&temp)+2))
#define BYTE3(temp)	   (*((char*)(&temp)+3))typedef struct 							
{uint16_t par_id;                 //<参数idint32_t  par_val;                //<参数值
}par_struct;/****通信帧对象结构体****/
typedef struct
{uint8_t head;					 //<帧头uint8_t target_addr;			 //<目标地址uint8_t function_id;			 //<该帧要实现某功能的功能码iduint8_t data_len;				 //<数据长度uint8_t data[40];				 //<数据内容,协议最高只支持40字节数据  uint8_t sum_check;				 //<和校验uint8_t add_check;				 //<附加校验par_struct* parameter;           //<参数
}ano_frameStruct;/*共同点:形参都含ano_frameStruct*类型指针*/
extern void ano_frame_reset(ano_frameStruct* frame);
extern void ano_check_calculate(ano_frameStruct* frame);
extern uint8_t ano_check(ano_frameStruct* frame);
extern void frame_turn_to_array(ano_frameStruct* frame,uint8_t*str);
//.....extern void ano_send_string(uint8_t color,char* str);
extern void ano_send_message(char* str,int32_t value);
extern void ano_send_flexible_frame(uint8_t id,int32_t x_coordinate,int32_t y_coordinate);
extern void ano_frame_init(void);#endif

粘贴生成.c文件
ANDmessage.c

#include "stm32f4xx_hal.h"
#include "main.h"
#include "usart.h"
#include "ANDmessage.h"static par_struct      send_parameter;       //<发送帧中的参数;	
static par_struct      rec_parameter;        //<接收帧的参数;
static ano_frameStruct send_frame_struct;    //<(发送)通信帧结构体
__IO ano_frameStruct   rec_frame_struct;     //<(接收)通信帧结构体,因不止在本.c文件使用,故不用static修饰/*** @brief   初始化通信帧结构体,使用前必须调用* @param   无输入参数* @retval  无返回**/
void ano_frame_init(void)
{/*参数结构体初始化*/send_frame_struct.parameter=&send_parameter;rec_frame_struct.parameter=&rec_parameter;send_frame_struct.parameter->par_id=0;send_frame_struct.parameter->par_val=0;rec_frame_struct.parameter->par_id=0;rec_frame_struct.parameter->par_val=0;send_frame_struct.head=rec_frame_struct.head=FRAME_HEADER;//帧头固定是0XAAsend_frame_struct.target_addr=rec_frame_struct.target_addr=HOST_ADDR;send_frame_struct.function_id=0XFF;//<协议中没有定义的功能ID,这样初始化目的是为了启动瞬间不做任何动作memset(send_frame_struct.data,0,40);//<缓存默认全部置0memset(rec_frame_struct.data,0,40);
}/*** @brief   复位通信帧结构体,ano_frame_init()必须要运行过一次* @param   通信帧结构体对象* @retval  无返回**/
void ano_frame_reset(ano_frameStruct* frame)
{frame->function_id=0XFF;						frame->data_len=0;memset(frame->data,0,40);frame->add_check=0;frame->sum_check=0;
}/*** @brief   通信帧中参数结构体内成员的配置* @param   通信帧结构体对象,参数ID与参数值* @retval **/
void ano_par_struct_config(ano_frameStruct* frame,uint16_t id,int32_t val)
{frame->parameter->par_id=id;frame->parameter->par_val=val;
}/*** @brief   通信帧校验计算* @param   通信帧结构体对象* @retval  无返回值**/
static void ano_check_calculate(ano_frameStruct* frame)
{frame->sum_check=0;frame->add_check=0;//除去和校验,附加校验及数据部分,有4个部分4个字节,长度固定for(uint32_t i=0;i<4;i++){frame->sum_check+= *(uint8_t*)(&frame->head+i);frame->add_check+=frame->sum_check;}//获取数据长度部位,把数据部分全加上for(uint32_t i=0;i<frame->data_len;i++){frame->sum_check+=*((uint8_t*)(frame->data)+i);frame->add_check+=frame->sum_check;} }/*** @brief   通信帧校验检查(接收上位机通信帧时用)* @param   通信帧结构体对象* @retval   1:校验成功 0:校验失败**/
static uint8_t ano_check(ano_frameStruct* frame)
{uint8_t sum_check=0;uint8_t add_check=0;for(uint32_t i=0;i<4;i++){sum_check+= *(uint8_t*)(&frame->head+i);add_check+=sum_check;}for(uint32_t i=0;i<frame->data_len;i++){sum_check+=*((uint8_t*)(frame->data)+i);add_check+=sum_check;}//如果计算与获取的相等,校验成功if((sum_check==frame->sum_check)&&(add_check==frame->add_check))return 1;elsereturn 0;
}/*** @brief  匿名串口发送* @param  字符串,数据字节个数* @retval */
static void ano_usart_send(uint8_t*str,uint16_t num)
{uint16_t cnt=0;do{HAL_UART_Transmit(&huart1,((uint8_t*)(str))+cnt,1,1000);cnt++;}while(cnt<=num);
}/*** @brief   通信帧结构体转化为线性数组* @param   要转换的通信帧,缓存数组* @retval **/
static void frame_turn_to_array(ano_frameStruct* frame,uint8_t*str)
{memcpy(str,(uint8_t*)frame,4);memcpy(str+4,(uint8_t*)frame->data,frame->data_len);memcpy(str+4+frame->data_len,(uint8_t*)(&frame->sum_check),2);
}/*** @brief  向上位机发送ASCII字符串* @param  color:希望上位机显示的字符串颜色,str:要发送的字符串* @retval 无返回值*/
void ano_send_string(uint8_t color,char* str)
{uint8_t i=0,cnt=0;uint8_t buff[46];										memset(send_frame_struct.data,0,40);send_frame_struct.function_id=0XA0;           //<信息输出--字符串(功能码0XA0)send_frame_struct.data[cnt++]=color;          //<选择上位机打印的颜色/*字符串数据直接存入数据部分*/while(*(str+i)!='\0'){send_frame_struct.data[cnt++]=*(str+i++);if(cnt>40)                                //<若字符串长度超过40,强制结束break;}send_frame_struct.data_len=cnt;               //<记录下数据部分长度ano_check_calculate(&send_frame_struct);      //<计算校验和frame_turn_to_array(&send_frame_struct,buff); //<通信帧转线性数组ano_usart_send(buff,6+send_frame_struct.data_len);
}/*** @brief  向上位机发送ASCII字符串+数字组合* @param  value:32位的数值,str:要发送的字符串* @retval */
void ano_send_message(char* str,int32_t value)
{uint8_t i=0,cnt=0;uint8_t buff[46];										memset(send_frame_struct.data,0,40);send_frame_struct.function_id=0XA1;	          //信息输出--字符串+数字/*协议规定VAL在前,先对要求的32位数据进行截断*/send_frame_struct.data[cnt++]=BYTE0(value);send_frame_struct.data[cnt++]=BYTE1(value);send_frame_struct.data[cnt++]=BYTE2(value);send_frame_struct.data[cnt++]=BYTE3(value);/*再轮到字符串数据*/while(*(str+i)!='\0'){send_frame_struct.data[cnt++]=*(str+i++);if(cnt>40)break;}send_frame_struct.data_len=cnt;				  //<记录下数据部分长度ano_check_calculate(&send_frame_struct);	  //<计算校验和frame_turn_to_array(&send_frame_struct,buff); //<通信帧转线性数组ano_usart_send(buff,6+send_frame_struct.data_len);
}/*** @brief  发送灵活格式帧* @param  id:0xF1~0XFA,x_coordinate:x轴坐标值 ,y_coordinate:y轴坐标值*         !!!要传多少个参数完全可以自己进行计算,最高只支持40字节的数据,低位先输出*         一般10个以内够用,40个字节限制,一个32位数据占4个字节,可以发送10个* @retval */
void ano_send_flexible_frame(uint8_t id,int32_t x_coordinate,int32_t y_coordinate)
{uint8_t buff[46];memset(send_frame_struct.data,0,40);send_frame_struct.function_id=id;send_frame_struct.data_len=8;			   //<根据自己的参数数填写							/*第一个x_coordinate数据从低位到高位截断*/send_frame_struct.data[0]=BYTE0(x_coordinate);send_frame_struct.data[1]=BYTE1(x_coordinate);send_frame_struct.data[2]=BYTE2(x_coordinate);send_frame_struct.data[3]=BYTE3(x_coordinate);/*第二个数据y_coordinate从低位到高位截断*/send_frame_struct.data[4]=BYTE0(y_coordinate);send_frame_struct.data[5]=BYTE1(y_coordinate);send_frame_struct.data[6]=BYTE2(y_coordinate);send_frame_struct.data[7]=BYTE3(y_coordinate);/*第N个数据xxx从低位到高位截断*///......用户自行添加ano_check_calculate(&send_frame_struct);frame_turn_to_array(&send_frame_struct,buff);ano_usart_send(buff,6+send_frame_struct.data_len);
}

在主函数中初始化ANDmessage驱动

在这里插入图片描述

简单测试程序。在循环函数中添加一个变量发送给匿名上位机的数据,填写了一个随着时间变化一直自加的数据
在这里插入图片描述

连接匿名上位机V7

选择连接设置
在这里插入图片描述

打开自己的硬件和程序所写的串口端号和波特率,后打开连接
在这里插入图片描述

1.打开 协议解析 图标
2.选择扳手,弹出高级收码设置。
3.我们使用自定义的F1头帧,勾选使能该帧
4.数据容量配置,自行修改数据位 观察是否是我们需要的数值,1数据位表示8bit;2数据位表示16bit,以此类推
在这里插入图片描述
打开数据波形,弹出以下
在这里插入图片描述
波形显示框图
在这里插入图片描述
注意勾选要显示的波形,如果不清楚全勾选就行。注意左下角要显示“波形刷新中”才行。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/147780.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

选择排序算法:简单但有效的排序方法

在计算机科学中&#xff0c;排序算法是基础且重要的主题之一。选择排序&#xff08;Selection Sort&#xff09;是其中一个简单但非常有用的排序算法。本文将详细介绍选择排序的原理和步骤&#xff0c;并提供Java语言的实现示例。 选择排序的原理 选择排序的核心思想是不断地从…

NestJs和Vite使用monorepo管理项目中,需要使用共享的文件夹步骤

NestJs和Vite使用monorepo管理项目中,需要使用共享的文件夹步骤 1 首先需要将nest-cli打包的功能通过webpack接管 nest-cli.json文件内容 {"$schema": "https://json.schemastore.org/nest-cli","collection": "nestjs/schematics",…

FPGA project : TFT_LCD

实验目标&#xff1a; 驱动TFT_LCD显示十色彩条。 重点掌握的知识&#xff1a; 1&#xff0c;液晶显示器&#xff0c;简称LCD(Liquid Crystal Display)&#xff0c;相对于上一代CRT显示器(阴极射线管显示器)&#xff0c;LCD显示器具有功耗低、体积小、承载的信息量大及不伤眼…

Python入门教程48:Pycharm永久镜像源的pip配置方法

国内几个好用的Python镜像服务器地址&#xff1a; 清华大学镜像站&#xff1a;https://pypi.tuna.tsinghua.edu.cn/simple/阿里云镜像站&#xff1a;https://mirrors.aliyun.com/pypi/simple/中科大镜像站&#xff1a;https://pypi.mirrors.ustc.edu.cn/simple/中国科技大学镜…

入门运维之MySQL管理

一、系统数据库 Mysql数据库安装完成后,自带了以下四个数据库,具体作用如下: 1.1常用工具 1.1.1 mysql 该mysql不是指mysql服务,而是指mysql的客户端工具。 语法 :mysql [options] [database] 选项 :-u, --user=name #指定用户名-p, --password[=name] #指定密码-h,…

若依不分离+Thymeleaf select选中多个回显

项目中遇到的场景&#xff0c;亲测实用 表单添加时&#xff0c;select选中多个&#xff0c;编辑表单时&#xff0c;select多选回显&#xff0c;如图 代码&#xff1a; // 新增代码 <label class"col-sm-3 control-label">通道&#xff1a;</label><…

博途SCL区间搜索指令(判断某个数属于某个区间)

S型速度曲线行车位置控制,停靠位置搜索功能会用到区间搜索指令,下面我们详细介绍区间搜索指令的相关应用。 S型加减速行车位置控制(支持点动和停车位置搜索)-CSDN博客S型加减速位置控制详细算法和应用场景介绍,请查看下面文章博客。本篇文章不再赘述,这里主要介绍点动动和…

二十六、设置时序电路初始状态的方法(初始值设置)(时序电路置数)2

方法2 在理解方法1的化简(1)这个方法后,又可以想到输入触发器R和S两个输入端的信号也无非就是0和1。那么直接用LOAD这个信号接在R和S两个输入端上即可。 先用开关判断触发器的R和S是低电平触发还是高电平触发(下图触发器可以直接看出为低电平触发,但是实际用管子搭建的触…

Jmeter+jenkins接口性能测试平台实践整理

最近两周在研究jmeter&#xff0b;Jenkin的性能测试平台测试dubbo接口&#xff0c;分别尝试使用maven&#xff0c;ant和Shell进行构建&#xff0c;jmeter相关设置略。 一、Jmeterjenkins&#xff0b;Shell&#xff0b;tomcat 安装Jenkins,JDK,tomcat,并设置环境变量&#xff0…

Flutter+SpringBoot实现ChatGPT流实输出

FlutterSpringBoot实现ChatGPT流式输出、上下文了连续对话 最终实现Flutter的流式输出上下文连续对话。 这里就是提供一个简单版的工具类和使用案例&#xff0c;此处页面仅参考。 服务端 这里直接封装提供工具类&#xff0c;修改自己的apiKey即可使用&#xff0c;支持连续…

BASH shell脚本篇5——文件处理

这篇文章介绍下BASH shell中的文件处理。之前有介绍过shell的其它命令&#xff0c;请参考&#xff1a; BASH shell脚本篇1——基本命令 BASH shell脚本篇2——条件命令 BASH shell脚本篇3——字符串处理 BASH shell脚本篇4——函数 在Bash Shell脚本中&#xff0c;可以使用…

visual studio禁用qt-vsaddin插件更新

visual studio里qt-vsaddin插件默认是自动更新的&#xff0c;由于qt-vsaddin插件新版本的操作方式与老版本相差较大&#xff0c;且新版本不稳定&#xff0c;容易出Bug&#xff0c;所以需要禁用其自动更新&#xff0c;步骤如下&#xff1a;     点击VS2019菜单栏上的【扩展】–…

【计算机网络】高级IO之select

文章目录 1. 什么是IO&#xff1f;什么是高效 IO? 2. IO的五种模型五种IO模型的概念理解同步IO与异步IO整体理解 3. 阻塞IO4. 非阻塞IOsetnonblock函数为什么非阻塞IO会读取错误&#xff1f;对错误码的进一步判断检测数据没有就绪时&#xff0c;返回做一些其他事情完整代码myt…

热点文章采集-热点资讯采集工具免费

在信息时代&#xff0c;掌握热点资讯、了解热门时事、采集热门文章是许多自媒体从业者和信息追踪者的重要任务。然而&#xff0c;这并不是一项容易的任务。信息的海洋庞大而繁杂&#xff0c;要从中捞取有价值的热点和文章需要耗费大量时间和精力。 热点资讯采集&#xff1a;信息…

基于体素场景的摄像机穿模处理

基于上一篇一种基于体素的射线检测 使用射线处理第三人称摄像头穿模问题 基于体素的第三人称摄像机拉近简单处理 摄像机移动至碰撞点处 简单的从角色身上发射一条射线到摄像机&#xff0c;中途遇到碰撞就把摄像机移动至该碰撞点 public void UpdateDistance(float defaultDist…

FOC程序cubemx配置-ADC配置

具体配置步骤大家参考&#xff1a;这篇文章 我配置后用keil5自带的仿真工具查看引脚波形&#xff0c;在这里写一下遇到的问题。 1、波形仿真的时候出现 Unknown Signal&#xff1a;参考 这篇文章 2、生成的波形并不完全互补。 PS&#xff1a;出现以上这种情况时&#xff0…

使用Visual Studio调试排查Windows系统程序audiodg.exe频繁弹出报错

VC常用功能开发汇总&#xff08;专栏文章列表&#xff0c;欢迎订阅&#xff0c;持续更新...&#xff09;https://blog.csdn.net/chenlycly/article/details/124272585C软件异常排查从入门到精通系列教程&#xff08;专栏文章列表&#xff0c;欢迎订阅&#xff0c;持续更新...&a…

多线程基础篇(多线程案例)

文章目录 多线程案例1、单例模式1&#xff09;饿汉模式2&#xff09;懒汉模式3&#xff09;线程安全吗&#xff1f;&#xff1f;4&#xff09;解决懒汉模式线程安全问题5&#xff09;解决懒汉模式内存可见性问题 2、阻塞队列1) 阻塞队列是什么&#xff1f;2) 生产者消费者模型1…

操作系统原理-习题汇总

临近毕业&#xff0c;整理一下过去各科习题及资料等&#xff0c;以下为操作系统原理的习题汇总&#xff0c;若需要查找题目&#xff0c;推荐CtrlF或commandF进行全篇快捷查找。 操作系统原理 作业第一次作业选择题简答题 第二次作业选择题简答题 第三次作业选择题简答题 第四次…

Oracle - 多区间按权重取值逻辑

啰嗦: 其实很早就遇到过类似问题&#xff0c;也设想过&#xff0c;不过一致没实际业务需求&#xff0c;也就耽搁了&#xff1b;最近有业务提到了&#xff0c;和同事讨论&#xff0c;各有想法&#xff0c;所以先把逻辑整理出来&#xff0c;希望有更好更优的解决方案&#xff1b;…