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

news2025/1/13 5:57:03

匿名上位机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;                 //<参数id
	int32_t  par_val;                //<参数值
}par_struct;

/****通信帧对象结构体****/
typedef struct
{
	uint8_t head;					 //<帧头
	uint8_t target_addr;			 //<目标地址
	uint8_t function_id;			 //<该帧要实现某功能的功能码id
	uint8_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;//帧头固定是0XAA
	send_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);//<缓存默认全部置0
	memset(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;
	else
	 return 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.coloradmin.cn/o/1058116.html

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

相关文章

Altium Designer 批量添加元器件后缀

Altium Designer 批量添加元器件后缀 方法一方法二可能出现的问题要注意 方法一 您可以使用 Altium Designer 中的“批量修改元器件名称”功能来批量添加元器件后缀。具体步骤如下&#xff1a; 1.为了方便显示 操作流程&#xff0c;我这里复制了几个原理图的文件&#xff0c;粘…

【漏洞复现】用友GPR-U8 slbmbygr SQL注入漏洞

文章目录 一、漏洞描述二、网络空间搜索引擎搜索三、漏洞利用 一、漏洞描述 用友GRP-U8是面向政府及行政事业单位的财政管理应用。北京用友政务软件有限公司GRP-U8 SQL注入漏洞。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/fe260ff4d6d14abeb0e576e4bbf3c385.png 二…

计算机组成原理期末复习

第一章 上机前的准备&#xff1a;建立数学模型、确定计算方法和编制解题程序n位操作码有 2 n 2^n 2n种不同操作主储存器&#xff08;主存/内存&#xff09;包括存储体M、各种逻辑部件及控制电路。储存体有多个储存单元&#xff0c;储存单元有多个储存元件&#xff0c;每个存储…

SDL2绘制ffmpeg解析的mp4文件

文章目录 1.FFMPEG利用命令行将mp4转yuv4202.ffmpeg将mp4解析为yuv数据2.1 核心api: 3.SDL2进行yuv绘制到屏幕3.1 核心api 4.完整代码5.效果展示 本项目采用生产者消费者模型&#xff0c;生产者线程&#xff1a;使用ffmpeg将mp4格式数据解析为yuv的帧&#xff0c;消费者线程&am…

latex表格内容换行

问题描述&#xff1a; 在用latex表格中编写公式时&#xff0c;可能出现公式太长&#xff0c;表格中后面的内容不能在文档中呈现&#xff0c;如下图1&#xff0c;故要进行行内内容的换行&#xff0c;使内容呈现完全而传统的\换行后,换行内容会顶格&#xff0c;如图2。 解决方…

PE文件之导入表

1. 导入表 2. 显示导入表信息的例子 ; 作用: 将RVA地址转成FOA即文件偏移 ; 参数: _pFileHdr 指向读到内存中文件的基址指针 ; _dwRVA 目标RVA地址 ; 返回: 目标RVA转成文件偏移的值 RVA2FOA PROC USES esi edi edx, _pFileHdr:PTR BYTE, _dwRVA:DWORDmov esi, _pFil…

饲料微生物检验 采样.

声明 本文是学习GB-T 42959-2023 饲料微生物检验 采样. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本文件规定了以微生物检验为目的的采样原则、采样人员、设备和材料、采样方案、采样步骤和采样 报告。 本文件适用于以微生物检验为目的…

Can‘t pickle <class ‘__main__.Test‘>: it‘s not the same object as __main__.Test

目录 原因1 类名重复了 案例1 变量名和类名重复 原因1 类名重复了 检查项目代码&#xff0c;是不是其他地方有同名类。 案例1 变量名和类名重复 转自&#xff1a;python3报错Cant pickle <class __main__.Test>: its not the same object as __main__.Test解决 - 知乎…

接口日志,统一记录(AOP+自定义注解)

需求 指定接口&#xff0c;记录请求的日志。 接口日志的核心内容包括&#xff1a;请求方法&#xff0c;接口路径&#xff0c;请求参数等。 方案 采用的方案是&#xff1a;AOP 自定义注解 说明&#xff1a; 在需要记录日志的接口上&#xff0c;加上自定义注解ApiLog&…

样品运输与贮存

声明 本文是学习GB-T 42959-2023 饲料微生物检验 采样. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本文件规定了以微生物检验为目的的采样原则、采样人员、设备和材料、采样方案、采样步骤和采样 报告。 本文件适用于以微生物检验为目的…

如何限制文件只能通过USB打印机打印,限制打印次数和时限并且无法在打印前查看或编辑内容

在今天这个高度信息化的时代&#xff0c;文档打印已经成为日常工作中不可或缺的一部分。然而&#xff0c;这也带来了诸多安全风险&#xff0c;如文档被篡改、知识产权被侵犯以及信息泄露等。为了解决这些问题&#xff0c;只印应运而生。作为一款独特的软件工具&#xff0c;只印…

《视觉 SLAM 十四讲》V2 第 4 讲 李群与李代数 【什么样的相机位姿 最符合 当前观测数据】

P71 文章目录 4.1 李群与李代数基础4.1.3 李代数的定义4.1.4 李代数 so(3)4.1.5 李代数 se(3) 4.2 指数与对数映射4.2.1 SO(3)上的指数映射罗德里格斯公式推导 4.2.2 SE(3) 上的指数映射SO(3),SE(3),so(3),se(3)的对应关系 4.3 李代数求导与扰动模型4.3.2 SO(3)上的李代数求导…

S-Clustr(影子集群)僵尸网络@Мартин.

公告 项目地址:https://github.com/MartinxMax/S-Clustr/tree/V1.0.0 1.成功扩展3类嵌入式设备,组建庞大的"僵尸网络" |——C51[开发中] |——Arduino |——合宙AIR780e[开发中] 2.攻击者端与服务端之间通讯过程全程加密,防溯源分析 3.Generate一键自动生成Arduino…

将数组和减半的最少操作【贪心2】

题目&#xff1a;将数组和减半的最少操作 贪心思路&#xff1a;每次挑选最大的数来减半。 解法&#xff1a;贪心大根堆 class Solution { public:int halveArray(vector<int>& nums) {priority_queue<double> heap;double sum 0.0;for(int& x : nums){hea…

Linux性能优化--性能工具:系统内存

3.0.概述 本章概述了系统级的Linux内存性能工具。本章将讨论这些工具可以测量的内存统计信息&#xff0c;以及如何使用各种工具收集这些统计结果。阅读本章后&#xff0c;你将能够&#xff1a; 理解系统级性能的基本指标&#xff0c;包括内存的使用情况。明白哪些工具可以检索…

vtk 动画入门 1 代码

实现效果如图&#xff1a; #include <vtkAutoInit.h> //VTK_MODULE_INIT(vtkRenderingOpenGL2); //VTK_MODULE_INIT(vtkInteractionStyle); VTK_MODULE_INIT(vtkRenderingOpenGL2); VTK_MODULE_INIT(vtkInteractionStyle); //VTK_MODULE_INIT(vtkRenderingFreeType); #in…

lv8 嵌入式开发-网络编程开发 01什么是互联网

目录 1 计算机网络的定义与分类 1.1 按照网络的作用范围进行分类 1.2 按照网络的使用者进行分类 2 网络的网络 2.1 名词解释 2.2 边缘与核心 3 互联网基础结构发展的三个阶段 3.1 第一阶段&#xff1a;1969 – 1990 3.2 第二阶段&#xff1a;1985 – 1993 3.3 第三阶…

Python大数据之PySpark(四)SparkBaseCore

文章目录 SparkBase&Core环境搭建-Spark on YARN扩展阅读-Spark关键概念[了解]PySpark角色分析[了解]PySpark架构后记 SparkBase&Core 学习目标掌握SparkOnYarn搭建掌握RDD的基础创建及相关算子操作了解PySpark的架构及角色 环境搭建-Spark on YARN Yarn 资源调度框…

UE中制作棋盘格材质效果

在UE中通过这个小技巧制作棋盘格材质效果&#xff0c;可以快速预览UV拉伸情况&#xff0c;方便调试导入的模型。 1.操作步骤 1.1 首先新建材质&#xff0c;Shading Model&#xff08;着色模式&#xff09;设置为Unlit&#xff08;无光照&#xff09;&#xff1a; 1.2 我们…

管道-匿名管道

一、管道介绍 管道&#xff08;Pipe&#xff09;是一种在UNIX和类UNIX系统中用于进程间通信的机制。它允许一个进程的输出直接成为另一个进程的输入&#xff0c;从而实现数据的流动。管道是一种轻量级的通信方式&#xff0c;用于协调不同进程的工作。 1. 创建和使用管道&#…