使用高级收码方式实现PID调试

数据格式:

帧头+功能字+长度+数据+校验
帧头+FUN+LEN+DATA+SUM

  • FUN可以是 0xA1到0xAA,共10个,也就是说最多可以接受十个用户自定义的数据类型。(图一)
  • LEN为DATA的长度(不包括帧头、FUN、LEN、SUM),只是数据的字节长度和。比如该帧数据内容为3个int16型数据,那么LEN等于6
  • SUM是帧头一直到DATA最后一字节的所有字节的和,是内容的和,不是长度的和。uint8格式。(只保留低八位,高位舍去)。
  • 数据可以是uint8、int16、uint16、int32、float这几个常用格式,多字节数据高位在前。
  • 有20个数据存储器,每个存储器的数据可以分别设置为来自10个自定义帧的30个数据。(图二)

上位机格式设置

python 匿名上位机飞控 匿名上位机调试pid_python 匿名上位机飞控


一共10个帧,用哪个便使能哪个,然后自定义数据类型。

python 匿名上位机飞控 匿名上位机调试pid_pid_02

下面的数据容器设置中,数据位置和通道设置为一样。上面是通道几,下面的数据位置就设为多少。

python 匿名上位机飞控 匿名上位机调试pid_pid_03


根据自己定义的数据包的大小,其实就是数组的长度,最多可以发送20个数据。

#include “ANO_TC.c”

#include "ANO_TC.h"
#include "usart.h"
#include "control.h"


u8 send_flag;

u8 data_to_send[50] = {0};



//移植时,用户应根据自身应用的情况,根据使用的通信方式,实现此函数,这里就采用有线连接,发送至串口2了
void ANO_DT_Send_Data(uint8_t *dataToSend , uint8_t length)
{
	HAL_UART_Transmit(&huart1, (u8 *)dataToSend,length,1000);
	 while(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_TC) != SET); //等待发送结束

}

//通信协议函数
void ANO_DT_SendtoUSER(uint16_t data1, uint16_t data2, uint16_t data3,uint16_t data4)	
{
  u8 _cnt=0,sum = 0,i;
	data_to_send[_cnt++]=0xAA;
	data_to_send[_cnt++]=0xAA;
	data_to_send[_cnt++]=0xF1; //自定义帧1
	data_to_send[_cnt++]=0;    //这是len位,后面 _cnt-4来赋值

	data_to_send[_cnt++]=BYTE1(data1);
	data_to_send[_cnt++]=BYTE0(data1);//数据部分
		
	data_to_send[_cnt++]=BYTE1(data2);
	data_to_send[_cnt++]=BYTE0(data2);//数据部分
	
	data_to_send[_cnt++]=BYTE1(data3);
	data_to_send[_cnt++]=BYTE0(data3);//数据部分
	
	data_to_send[_cnt++]=BYTE1(data4);
	data_to_send[_cnt++]=BYTE0(data4);//数据部分
	
	data_to_send[3] = _cnt-4;//长度位
	
	for(i=0;i<_cnt;i++)
		sum += data_to_send[i];
	
	data_to_send[_cnt++]=sum;//校验位
	
	ANO_DT_Send_Data(data_to_send, _cnt);
}


//结合定时器,设置各个数据发送标志位,可以定期发送各种数据到上位机。
//Data_Exchange函数处理各种数据发送请求,比如想实现每5ms发送一次传感器数据至上位机,即在此函数内实现
//此函数每1ms调用一次
void ANO_DT_Data_Exchange(void)
{
	static uint8_t cnt 	= 0;
	cnt++;
	if(cnt>=10)//10MS
	{
		cnt = 0;
		send_flag = 1;
	}	
	
		HAL_GPIO_TogglePin(LED0_GPIO_Port,LED0_Pin);
	if(send_flag)
	{
		send_flag = 0;
	 // ANO_DT_SendtoUSER(Servo_pid.x_curr_posi,Servo_pid.y_curr_posi,Servo_pid.x_curr_angle,Servo_pid.y_curr_angle);
	
		ANO_DT_SendtoUSER(Position_y[0],Position_y[1],Position_y[2],Position_y[3]);
	}
}

#include “ANO_TC.h”

#ifndef __ANO_TC_H__
#define __ANO_TC_H__

#include "main.h"


//数据拆分宏定义,在发送大于1字节的数据类型时,比如int16、float等,需要把数据拆分成单独字节进行发送
#define BYTE0(dwTemp)       ( *( (char *)(&dwTemp)	  ) )
#define BYTE1(dwTemp)       ( *( (char *)(&dwTemp) + 1) )
#define BYTE2(dwTemp)       ( *( (char *)(&dwTemp) + 2) )
#define BYTE3(dwTemp)       ( *( (char *)(&dwTemp) + 3) )


void ANO_DT_Send_Data(uint8_t *dataToSend , uint8_t length);
void ANO_DT_SendtoUSER(uint16_t data1, uint16_t data2, uint16_t data3,uint16_t data4);
void ANO_DT_Data_Exchange(void);


#endif