3.3 匿名,但皆知我姓名——ANO示波

3.3 匿名,但皆知我姓名——ANO示波

3.3.1 ANO匿名上位机简介

(1)ANO功能

学习过32基本都会接触到如XCOM串口助力手之类的上位机。那这里要谈的ANO匿名上位机与之有什么不同呢。匿名上位机,英文简称ANO是一款在开源飞控开发领域十分流行的上位机,具有虚拟示波器、远程调参、 姿态动画显示、航线规划等十分丰富的功能。支持串口、USB、网络多种通信方式。
在这里插入图片描述

图3.3.1.1 ANO

匿名上位机可以在其官网进行下载:http://www.anotc.com/wiki/%E5%8C%BF%E5%90%8D%E4%BA%A7%E5%93%81%E8%B5%84%E6%96%99/%E8%B5%84%E6%96%99%E4%B8%8B%E8%BD%BD%E9%93%BE%E6%8E%A5%E6%B1%87%E6%80%BB 或 “5、软件资料\(1)软件\匿名上位机V7\匿名上位机V7.zip”,解压后直接双击运行即可。

B站教程:
https://space.bilibili.com/351384919/search/video?keyword=V7
,这里使用了V7版本的匿名上位机。

(2)ANO示波

在这里插入图片描述

图3.3.1.2 ANO示波

如果要看程序中运行的某个变量的值,比如说采集到的陀螺仪的x轴角速度的值。简单的方法就是使用printf函数将角速度值打印到串口助手上,但这种方法往往有许多不便。而更高效的方法便是虚拟示波器器了,也就是ANO的“波型显示”功能。虚拟拟示波器相比于普通串口显示数据的主要优点是:

  1. 可以直观看到数据变化趋势
  2. 便于不同数据的对比
  3. 波型可以缩放,不同频率的信息都方便观察。
(3)ANO灵活格式帧

ANO功能多,相应的通信协议也不少,本节只介绍最常用的显示波形的部分。ANO通信协议主要参考“5、软件资料\(1)软件\匿名上位机V7\匿名通信协议V7.pdf” 或 如图3.3.1.1在ANO软件中鼠标移到软件界面左侧1处,显示隐藏界面-》“帮助信息” -》 “通信协议”打开通信协议文件。

在这里插入图片描述

图3.3.1.3

这里我们只用到“一、 通信帧格式介绍/2. 灵活格式帧”也就是波形显示的部分。其具体发送数据的协议如图3.3.1.4

在这里插入图片描述

图3.3.1.4

灵活格式帧,我们也可以叫做用户自定义帧,可以用于将程序中的变量发送到ANO中并显示波形。灵活格式帧共 10 帧,帧 ID 从 0xF1到 0xFA,每一帧最多可以携带 10 个数据,每一个数据可以分别设置为 U8、S16、U16、S32 的格式,但发送的数据类型要与ANO上设置的相一致。

该协议帧中:

  • HEAD:
    固定为0xAA
  • D_ADDR:
    固定为0xFF
  • ID:
    帧ID相当于数据帧的身份证号,ANO通信协议有上百种数据帧,对应的也有上百个帧ID。而灵活格式帧占其中的十种,此处只使用其中的一种灵活格式帧,所以也固定,为0xF1
  • LEN:
    要根据灵活格式帧中携带的变量的类型来确定,如果变量的类型都是S32类型的,那LEN=40(4*10);如果5个是U16,5个是S32,则为30 。
    鉴于u8、s16等可以强制类型转化为s16类型而不失真,这里计划10个变量都设置为s32类型,故LEN=40。
  • DATA:
    是存放10变量值数据的位置。关于数据的存储也是有许多道道的。
    • 整型(u8、s8、u16……)数据的二进制表示:
      不同类型的取值范围

      int8: -128 ~ 127
      int16: -32768 ~ 32767
      int32: -2147483648 ~ 2147483647

      uint8: 0 ~ 255
      uint16: 0 ~ 65535
      uint32: 0 ~ 4294967295
      几种数据类型分别占1、2、4个Byte,Byte 又称为 字节,Bit 又称为 位,Bit 是内存中最小的单位。
      以 int8 / uint8 为例:

      int8占1个字节,1字节(byte)占8位(bit)

      其中最高位代表符号位 1-负号;0-正号
      则1的二进制表示为:0 0 0 0 0 0 0 1,最大可表示127,即:0 1 1 1 1 1 1 1。
      而负数的表示:如-1的进制表示与直觉不同为1 1 1 1 1 1 1 1,是的负数是数值部分(低7位)是倒数的,随负数绝对值变大,低7位变小,可以表示的最小的负数为-128: 1 0 0 0 0 0 0 0。 其它字节长度的整形数据的二进制表示遵循类似的原则。

    • 可以看出不同数据类型在二进制表示方面(存储器、通信)并无不同,都是成字节的二进制位。之所以同几个字节数据可以变为不同类型数据,是读取方式不同的原因。

    • 另一方面,ANO协议要求发送的变量必须将低字节先发送,再发送高字节数据。比如要发送一个int16类型的数据:-2,其十六进制表示为:FF FE 。则要先发送低字节“FE”,再发送高字节“FF”。当然这只是DATA中数据发送顺序的规则,整体的灵活格式帧还是先发帧头,最后发帧尾。

  • SC与AC
    这是两个校验相关的字节,通过一定计算方式来计算。检验字节的作用是避免数据传输过程中出现的错误数据和导致的错误解析。无线数传相比有线通信,其稳定性大大降低,数据发送出去,并不能保证对侧能百分百接收到而且还都是对的。
    • SC(和校验 SUM CHECK 计算方法)
      从帧头 0xAA 字节开始,一直到 DATA 区结束,对每一字节进行累加操作,最终结果只取低 8 位
    • AC(附加校验 ADD CHECK 计算方法)
      计算和校验时,每进行一字节的加法运算,同时AC累加一次sc,最终结果只取低 8 位

3.3.2 硬件设计

本小节用到的硬件资源有:
(1)AT32飞控USART3
  USART3_TX_PC4
  USART3_RX_PC5
(2)一对汇承蓝牙串口模块

3.3.3 下载验证

在详细讲解ANO程序前先来操作一下ANO软件,有一个硬性认知。
进入“2、飞控例程\3_ANO”,打开工程并编译。

按住BOOT按键,给飞控上电,进入Bootloader(同时进入USB的DFU模式)。编译例程,双击“Download_tool_ISP”文件夹下的“1_Download_by_usb.bat”,开始下载程序。

该例程的功能为:使用ANO匿名上位机显示波形。

连接好蓝牙模块,打开ANO软件。

    1. 连接设置
      进入连接设置
      在这里插入图片描述

图3.3.3.1

    1. 下拉选择串口设备,并设置波特率为230400

在这里插入图片描述

图3.3.3.2

    1. 打开连接,可以看到“接收计数”处数字一直升高,且“错误码率”拉接0。
      在这里插入图片描述

图3.3.3.3

    1. 打开“协议通信”界面,可以在左侧隐藏栏,或右下角处点击进入。
      在这里插入图片描述

图3.3.3.4

    1. 例程使用了0xF1灵活数据帧的10个数据,且第个数据都是int32类型的。选中如图3.3.3.5中的1中的“格式设置”,之后:
      “自定义帧数据配置”设置:在“自定义帧数据配置”(也就是灵活数据帧)处,展开“用户帧”下的F1项,选中F1对应的“使能该帧”,数据类型都选为“Int32”,传输缩放都先为1.0E+0(这里其实只有缩小系数,只能将数据缩小到10的n次方)。
      “数据容器配置”进行设置:ANO最多能同时显示20路数据波形,这里的UserData_1~UserData_20表示的就是ANO转化为20路波形的源数据,这里只使用其中的前10个,并分另设置为0xF1灵活格式帧中的10个数据。
      在这里插入图片描述

图3.3.3.5

    1. 打开“波形显示”界面,可以在左侧隐藏栏,或右下角处点击进入。
      在这里插入图片描述

图3.3.3.6

    1. 如图3.3.3.7,点击1处“设置”,点击使用“用户数据波形”,点击“确定”,再勾选上4处要显示的数据。
      在这里插入图片描述

图3.3.3.7

此时,波形便可以正常显示了,如下图。选中“全显”可以显示已经接收到的所有数据。在波形上按住鼠标左键向右下拉,可以放大该区域波形;按住右键可以拖动波形;波形上按住鼠标左键向左上拉,恢复之前大小。
在这里插入图片描述

图3.3.3.8

3.3.4 软件设计

本节例程在上一节的基础上进行修改,初始化部分相同,只是在串口调用时加入ANO协议。

打开“qy_math/qy_ANO_task.c”

/**
  **************************************************************************
  * qy_ANO_task
  * @brief    ANO匿名上位机文件
  * @writer   清月默默
  * @time	  2023.12.6
  **************************************************************************
  */

#include "qy_common_header.h"

TaskHandle_t ANO_handler;						//任务句柄
void ANO_task_function(void *pvParameters);		//任务函数

char USART_RX_BUF[ANO_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.
//接收状态
//bit15,	接收完成标志
//bit14,	接收到0x0d
//bit13~0,	接收到的有效字节数目
u16 USART_RX_STA=0;       //接收状态标记



/* ANO任务函数 */
void ANO_task_function(void *pvParameters)
{
	
	while(1)
	{	
		if(USART_RX_STA&0x8000)		//接收完成
		{					   
			printf("\r\n您发送的消息为:\r\n\r\n");
			ANO_tx_buffer(USART_RX_BUF, sizeof(USART_RX_BUF));
			printf("\r\n\r\n");		//插入换行
			USART_RX_STA=0;
		}

		Uart_to_Computer();		//ANO显示波形
		
		vTaskDelay(20);
	}
}


/**
  * @brief  ANO串口中断回调函数
  * @param  无
  * @retval 无
  */
void ANO_IRQ_Function(void)			
{
	u8 res;
	
	if(ANO_UART->sts_bit.rdbf)		/********** 为串口接收中断	 **********/	
	{
		res = ANO_UART->dt;		//得到 数据寄存器(USART_DT) 的值
		
		if((USART_RX_STA&0x8000)==0)//接收未完成
		{
			if(USART_RX_STA&0x4000)//接收到了0x0d
			{
				if(res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
				else USART_RX_STA|=0x8000;	//接收完成了 
			}else //还没收到0X0D
			{	
				if(res==0x0d)USART_RX_STA|=0x4000;
				else
				{
					USART_RX_BUF[USART_RX_STA&0X3FFF]=res;
					USART_RX_STA++;
					if(USART_RX_STA>(ANO_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收	  
				}		 
			}
		}  		 			
	}
	
	
}




这里保留了串口接收部分的程序,只是将串口发送改为发送ANO波形显示的灵活格式帧,即行38的Uart_to_Computer()函数。

(1) Uart_to_Computer()函数

定义在“ANO.c”中,为了方便程序调试,加入了ANO_tx_type_x(x = 0、1、2……)宏用于选择发送哪类数据。

/*
	() 临时类型
	(1)测试数据
	(2)阅读试验
	(3)ICM24688数据
	(4)BMP280数据
	(5)AT32飞控数据
	(6)AT32核心板数据
*/
#define ANO_tx_type_1


void Uart_to_Computer(void)
{

#ifdef ANO_tx_type_1
	static uint16 num = 0;
	
    var[0] = num++;
    var[1] = num++;
    var[2] = num++;

    var[3] = num++;
    var[4] = num++;
    var[5] = num++;
	var[6] = num++;

    var[7] = num++;
    var[8] = num++;
    var[9] = num++;
#endif

#ifdef ANO_tx_type_2
……
#endif	

    GFP_usart_senddata1(var);  //虚拟示波器函数
}


该函数赋值var[]数组中十个元素,并将var数组指针作为参数调用了GFP_usart_senddata1()函数。

(2)GFP_usart_senddata1()函数

同样定义在“ANO.c”中,如下:


void GFP_usart_senddata1(int32_t *var)
{
    char DataTosend__[46];
    uint8_t _vcnt=0;uint8_t i=0;uint8_t sc=0;uint8_t ac=0;

    DataTosend__[_vcnt++]=0xAA; //帧头
    DataTosend__[_vcnt++]=0xFF; //目标地址
    DataTosend__[_vcnt++]=0xF1; //帧ID(使用第1帧)
    DataTosend__[_vcnt++]=40;       //长度  4*10+1

    for(i=0;i<10;i++)
    {
        DataTosend__[_vcnt++]=BYTE0(var[i]);//发送4次单字节a(由低到高)
        DataTosend__[_vcnt++]=BYTE1(var[i]);//
        DataTosend__[_vcnt++]=BYTE2(var[i]);//发送4次单字节a(由低到高)
        DataTosend__[_vcnt++]=BYTE3(var[i]);//

    }

    for(i=0;i<DataTosend__[3]+4;i++)//校验计算
    {
        sc+=DataTosend__[i];//和校验计算
        ac+=sc;                         //附加校验计算
    }

    DataTosend__[_vcnt++]=sc;//校验同样发送出去用于接收方对比校验
    DataTosend__[_vcnt++]=ac;


    ANO_tx_buffer(DataTosend__, _vcnt);
}

该函数便是灵活格式帧的协议函数了。
行3:
此例程使用的灵活格式帧的共使用46个字节,故这里定义一个长度46的char类型数组。

行6~9:
加入了ANO协议的前四个字节,可以发现与之前所讲的协议规则相对应。

图3.3.4.1

行20~24:
写入DATA数据内容,且低字节在前。

行20~27:
进行和校验与附加校验字节值的计算,并添加到DataTosend__[]数组中。

行30:
至此DataTosend__[]数组中便已经保存有帧完整的灵活格式帧了,这里使用ANO_tx_buffer()函数将该协议帧通过串口(蓝牙模块)发送到计算机上的ANO软件中。

于是,ANO的波形显示界面就开始显示设置好的变量的值了。

格式帧的共使用46个字节,故这里定义一个长度46的char类型数组。

行6~9:
加入了ANO协议的前四个字节,可以发现与之前所讲的协议规则相对应。

图3.3.4.1

行20~24:
写入DATA数据内容,且低字节在前。

行20~27:
进行和校验与附加校验字节值的计算,并添加到DataTosend__[]数组中。

行30:
至此DataTosend__[]数组中便已经保存有帧完整的灵活格式帧了,这里使用ANO_tx_buffer()函数将该协议帧通过串口(蓝牙模块)发送到计算机上的ANO软件中。

于是,ANO的波形显示界面就开始显示设置好的变量的值了。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值