ANO匿名上位机V7协议&STM32
说明:以下程序为自己编写,若有误欢迎各位指出。
基于ANO匿名V7上位机的通信协议编写的代码
文章目录
- ANO匿名上位机V7协议&STM32
- 前言
- 一、Ano V7上位机功能介绍
- 1,基本数据接收
- 2,协议通信
-
- 3,数据波形显示
- 4,飞控参数
-
- 二、程序
-
前言
提示:以下内容需用到C语言中的指针、结构体、枚举、及大小端储存方式,需提前知晓其中的基本用法&高级用法。
一、Ano V7上位机功能介绍
1,基本数据接收
注:使用基本收发时需开启显示功能
2,协议通信
界面如下所示,会显示出协议数据中的所有数据
a,格式设置
点击右边的边框,展开格式设置界面,用于配置用户数据,可用于波形显示
其中用户帧是从F1~FA共10帧
而每一帧里面可以携带10个数据,数据类型可为"uint8_t"、“uint16_t”、“int16_t”、“uint32_t"和"int32_t”
要使用那个帧就勾上使能该帧,否则该帧的数据无效
若要传输小数则需改变后面的传输缩放"1.0E+0"表示没缩放,"1.0E+1"表示缩放10倍
数据容器配置界面中,一共有20个用户的数据容器,可用于显示波形,只需要设置容器对应的数据位就行,后面会显示当前数据位的数据值
b,协议通信
协议通信界面可以进行发送命令、发送读取命令、发送写入命令
3,数据波形显示
在波形显示界面要配置需要显示的数据,右击波形名称,选择用户数据,找到对应的用户数据,并且在需要显示的数据前打勾
其他详细操作请自行体会。
4,飞控参数
其中我们需要用到PID参数,Ano给我们留了18组PID
a,读取设备信息
在ANO V7上位机中,飞控参数界面需要指定的设备才能使用
所以,我们在连接串口后点击“读取信息”,会读取设备信息,此处我们只是借用“拓空者飞控”的ID
b,读取参数
点击读取参数,会显示出PID参数,直接点击参数值可进行更改,然后点击写入参数即可
二、程序
1,协议解析程序
MyAno.c
#include "MyAno.h"
#include "string.h"
#include "usart.h"
#include "math.h"
_ano MyAno = {0};
_Para MPara = {0};
void Ano_Init(void)
{
MyAno.Head = 0xAA;
MyAno.Addr = 0xFF;
MyAno.Lenth = 0;
}
static void SendParaData(uint8_t Id,int32_t para)
{
Ano_Set_Mdata(0xE2,(uint16_t *)&Id,2,1);
Ano_Set_Mdata(0xE2,(int32_t *)¶,4,2);
Ano_SendMdata();
}
static void SendCheckAnalysis(uint8_t id,uint8_t *sumcheck,uint8_t *addcheck)
{
Ano_Set_Mdata(0x00,(uint8_t *)&id,1,1);
Ano_Set_Mdata(0x00,(uint8_t *)sumcheck,1,2);
Ano_Set_Mdata(0x00,(uint8_t *)addcheck,1,3);
Ano_SendMdata();
}
static uint8_t Receive_CheckData(uint8_t *_da)
{
uint8_t i = 0;
uint8_t sumcheck = 0,addcheck = 0;
for(i = 0;i < _da[3] + 4;i++)
{
sumcheck += _da[i];
addcheck += sumcheck;
}
if((sumcheck == _da[_da[3] + 4]) && (addcheck == _da[_da[3] + 5]))
return 1;
else
return 0;
}
static uint8_t Send_CheckData(_ano *ano)
{
uint8_t i = 0;
uint8_t sumcheck = 0,addcheck = 0;
for(i = 0;i < ano->Lenth + 4;i++)
{
sumcheck += ano->SendBuff[i];
addcheck += sumcheck;
}
memcpy(ano->SendBuff + 4 + ano->Lenth,(uint8_t*)&sumcheck,sizeof(sumcheck));
memcpy(ano->SendBuff + 5 + ano->Lenth,(uint8_t*)&addcheck,sizeof(addcheck));
if(sumcheck == ano->SendBuff[ano->SendBuff[3] + 4] && addcheck == ano->SendBuff[ano->SendBuff[3] + 5])
return 1;
else
return 0;
}
__weak void ControlOrder(uint8_t _Ord)
{
switch (_Ord)
{
case Stop:
Ano_SendString("程序停止运行!\r\n",Color_Red);
break;
case Operation:
Ano_SendString("程序开始运行!\r\n",Color_Green);
break;
case Store:
Ano_SendString("参数储存成功!\r\n",Color_Green);
break;
}
}
__weak void ParaOfReturn_Set(uint16_t _id)
{
memset(MyAno.SendBuff,0x00,sizeof(MyAno.SendBuff));
MyAno.Lenth = 0;
switch (_id)
{
case 1: SendParaData((uint8_t )_id,(int32_t)HWTYPE); break;
case PID_1_P: SendParaData((uint8_t )_id,(int32_t)MPara.PID_Par1_P); break;
case PID_1_I: SendParaData((uint8_t )_id,(int32_t)MPara.PID_Par1_I); break;
case PID_1_D: SendParaData((uint8_t )_id,(int32_t)MPara.PID_Par1_D); break;
case PID_2_P: SendParaData((uint8_t )_id,(int32_t)MPara.PID_Par2_P); break;
case PID_2_I: SendParaData((uint8_t )_id,(int32_t)MPara.PID_Par2_I); break;
case PID_2_D: SendParaData((uint8_t )_id,(int32_t)MPara.PID_Par2_D); break;
case PID_3_P: SendParaData((uint8_t )_id,(int32_t)MPara.PID_Par3_P); break;
case PID_3_I: SendParaData((uint8_t )_id,(int32_t)MPara.PID_Par3_I); break;
case PID_3_D: SendParaData((uint8_t )_id,(int32_t)MPara.PID_Par3_D); break;
default: SendParaData((uint8_t )_id,(int32_t)0x00); break;
}
}
__weak void ParaRead_Set(uint16_t _id,int32_t _val)
{
switch (_id)
{
case PID_1_P: MPara.PID_Par1_P = _val; break;
case PID_1_I: MPara.PID_Par1_I = _val; break;
case PID_1_D: MPara.PID_Par1_D = _val; break;
case PID_2_P: MPara.PID_Par2_P = _val; break;
case PID_2_I: MPara.PID_Par2_I = _val; break;
case PID_2_D: MPara.PID_Par2_D = _val; break;
case PID_3_P: MPara.PID_Par3_P = _val; break;
case PID_3_I: MPara.PID_Par3_I = _val; break;
case PID_3_D: MPara.PID_Par3_D = _val; break;
}
}
void Ano_DataAnalysis(uint8_t *_da)
{
uint16_t HeadID = 0;
int32_t DataVal = 0;
MPara.OrderState = 1;
if(_da[0] == 0xAA && (_da[1] == 0xFF || _da[1] == 0x05))
{
if(_da[2] == 0xE0)
{
if(_da[4] == 0x10 && _da[5] == 0x00)
ControlOrder(_da[6]);
SendCheckAnalysis((uint8_t )0xE0,(uint8_t *)&(_da[_da[3] + 4]),(uint8_t *)&(_da[_da[3] + 5]));
MPara.OrderState = 0;
}
else if(_da[2] == 0xE1)
{
if(Receive_CheckData(_da))
{
HeadID = *(uint16_t*)(&_da[4]);
ParaOfReturn_Set(HeadID);
MPara.OrderState = 0;
}
}
else if(_da[2] == 0xE2)
{
if(Receive_CheckData(_da))
{
HeadID = *(uint16_t*)(&_da[4]);
DataVal = *(int32_t*)(&_da[6]);
ParaRead_Set(HeadID,DataVal);
SendCheckAnalysis((uint8_t )0xE2,(uint8_t *)&(_da[_da[3] + 4]),(uint8_t *)&(_da[_da[3] + 5]));
MPara.OrderState = 0;
}
}
}
}
void Ano_Set_Mdata(uint8_t id,void *data,uint8_t len,uint8_t num)
{
MyAno.ID = id;
memcpy(MyAno.SendBuff,(uint8_t*)&MyAno,3);
memcpy(MyAno.SendBuff + 4 + MyAno.Lenth,(uint8_t*)data,len);
MyAno.Lenth += len;
memcpy(MyAno.SendBuff + 3,(uint8_t*)&MyAno.Lenth,1);
}
void Ano_SendMdata(void)
{
uint8_t check;
check = Send_CheckData(&MyAno);
if(check)
{
HAL_UART_Transmit(&huart2,MyAno.SendBuff,MyAno.Lenth + 6,100);
memset(MyAno.SendBuff,0,sizeof(MyAno.SendBuff));
MyAno.Lenth = 0;
}
else
{
memset(MyAno.SendBuff,0,sizeof(MyAno.SendBuff));
MyAno.Lenth = 0;
}
}
void Ano_Send_Data(uint8_t id, void *Data, uint8_t lenth)
{
static uint8_t check;
MyAno.ID = id;
MyAno.Lenth = lenth;
memcpy(MyAno.SendBuff,(uint8_t*)&MyAno,4);
memcpy(MyAno.SendBuff + 4,(uint8_t*)Data,lenth);
check = Send_CheckData(&MyAno);
if(check)
{
HAL_UART_Transmit(&huart2,MyAno.SendBuff,MyAno.Lenth + 6,100);
memset(MyAno.SendBuff,0x00,sizeof(MyAno.SendBuff));
MyAno.Lenth = 0;
}
}
void Ano_SendString(const char *str,uint8_t color)
{
uint8_t i = 0;
Ano_Set_Mdata(0xA0,(uint8_t*)&color,1,1);
while (*(str + i) != '\0')
{
Ano_Set_Mdata(0xA0,(uint8_t*)(str+i++),1,2);
}
Ano_SendMdata();
}
void Ano_SendStringVal(const char *str,int32_t Val)
{
uint8_t i = 0;
Ano_Set_Mdata(0xA0,(int32_t*)&Val,4,1);
while (*(str + i) != '\0')
{
Ano_Set_Mdata(0xA1,(uint8_t*)(str+i++),1,2);
}
Ano_SendMdata();
}
int16_t Ano_Show_Sin(float x)
{
return 100*sin(2*x);
}
float Ano_Show_Cos(float x)
{
return 100*cos(2*x);
}
float Ano_Show_SQU(float x)
{
if(x > 0 && x < 3.14f)
return 10;
else
return -10;
}
void Show_Test(void)
{
int16_t y1,y2,y3;
uint8_t nul = 0;
static float x = 0;
x += 0.01f;
if(x > 3.14f)
x = -3.14f;
y1 = Ano_Show_Sin(x);
y2 = Ano_Show_Cos(x);
y3 = Ano_Show_SQU(x);
Ano_Set_Mdata(0xF1,(int16_t*)&y1,sizeof(y1),1);
Ano_Set_Mdata(0xF1,(int16_t*)&y2,sizeof(y2),2);
Ano_Set_Mdata(0xF1,(int16_t*)&y3,sizeof(y3),3);
Ano_Set_Mdata(0xF1,(uint8_t*)&nul,sizeof(nul),4);
Ano_SendMdata();
}
MyAno.h
#ifndef __MYANO_H
#define __MYANO_H
#include "stm32f3xx_hal.h"
#define Color_Black 0
#define Color_Red 1
#define Color_Green 2
enum AnoID
{
Stop = 0x00,
Operation,
Store,
HWTYPE = 0x05,
PID_1_P = 11,
PID_1_I,
PID_1_D,
PID_2_P,
PID_2_I,
PID_2_D,
PID_3_P,
PID_3_I,
PID_3_D
};
typedef struct
{
uint8_t Head;
uint8_t Addr;
uint8_t ID;
uint8_t Lenth;
uint8_t SendBuff[1024];
uint8_t ReceiveBuf[10];
}_ano;
typedef struct
{
uint8_t OrderState;
int16_t PID_Par1_P;
int16_t PID_Par1_I;
int16_t PID_Par1_D;
uint16_t PID_Par2_P;
uint16_t PID_Par2_I;
uint16_t PID_Par2_D;
uint16_t PID_Par3_P;
uint16_t PID_Par3_I;
uint16_t PID_Par3_D;
}_Para;
extern _ano MyAno;
extern _Para MPara;
static void SendParaData(uint8_t Id,int32_t para);
static void SendCheckAnalysis(uint8_t id,uint8_t *sumcheck,uint8_t *addcheck);
static uint8_t Receive_CheckData(uint8_t *_da);
static uint8_t Send_CheckData(_ano *ano);
void Ano_Init(void);
void Ano_Send_Data(uint8_t id, void *Data, uint8_t lenth);
void Ano_Set_Mdata(uint8_t id,void *data,uint8_t len,uint8_t num);
void Ano_SendMdata(void);
void Ano_DataAnalysis(uint8_t *_da);
void Ano_SendString(const char *str,uint8_t color);
void Ano_SendStringVal(const char *str,int32_t Val);
void Show_Test(void);
__weak void ControlOrder(uint8_t _Ord);
__weak void ParaOfReturn_Set(uint16_t _id);
__weak void ParaRead_Set(uint16_t _id,int32_t _val);
#endif
2,调用说明
注:需先调用"Ano_Init"参数初始化函数,在确定回传参数与实际参数的关系,然后把"Ano_DataAnalysis"扔进串口回调函数中,传入一个完整的一帧数据进行解析。
串口接收回调函数的示例:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == huart2.Instance)
{
MPara.OrderState = 1;
if(UsartBuffer[0] == 0xAA)
{
UsartBuffer[Usart1_RxCnt++] = RxBuffer;
if((Usart1_RxCnt == 8 && UsartBuffer[2] == 0xE1) || (Usart1_RxCnt == 12 && UsartBuffer[2] == 0xE2) || (Usart1_RxCnt == 17 && UsartBuffer[2] == 0xE0))
{
Ano_DataAnalysis((uint8_t *)&UsartBuffer);
Usart1_RxCnt = 0;
memset(UsartBuffer,0x00,sizeof(UsartBuffer));
}
}
else
{
Usart1_RxCnt = 0;
memset(UsartBuffer,0x00,sizeof(UsartBuffer));
UsartBuffer[Usart1_RxCnt++] = RxBuffer;
}
HAL_UART_Receive_IT(&huart2, (uint8_t *)&RxBuffer, 1);
}
}
注:在发送数据的时候写一个判断语句,进行判断接收命令的状态
if(MPara.OrderState == 0)
{
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)