ANO匿名上位机V7协议&STM32

2023-05-16

ANO匿名上位机V7协议&STM32

说明:以下程序为自己编写,若有误欢迎各位指出。

基于ANO匿名V7上位机的通信协议编写的代码

文章目录

  • ANO匿名上位机V7协议&STM32
  • 前言
  • 一、Ano V7上位机功能介绍
    • 1,基本数据接收
    • 2,协议通信
      • a,格式设置
      • b,协议通信
    • 3,数据波形显示
    • 4,飞控参数
      • a,读取设备信息
      • b,读取参数
  • 二、程序
    • 1,协议解析程序
    • 2,调用说明


前言

提示:以下内容需用到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;
}

/**	
 * 函数名:	发送ID对应的参数
 * 形	参:	Id - 参数ID
 * 			para - 参数数据
 *	返回值:	无
**/
static void SendParaData(uint8_t Id,int32_t para)
{
	Ano_Set_Mdata(0xE2,(uint16_t *)&Id,2,1);	//加载ID
	Ano_Set_Mdata(0xE2,(int32_t *)&para,4,2);	//加载参数数据
	Ano_SendMdata();	//发送数据
}

/**
 * 函数名:	发送数据校验帧0x00
 * 形	参:	id - 帧的ID	
 * 			sumcheck 和校验数据
 * 			addcheck 附加校验数据
 * 返回值:无
**/
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();
}

/**	
 *	函数名:	接收数据校验检测
 *	形	参:	_da数据
 *	返回值:	1校验成功	0校验失败 
**/
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;
}

/**	
 *	函数名:	发送数据和校验&附加校验计算
 *	形	参:	ano结构体
 *	返回值:	1->校验成功 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));
	/* 其中 ano->SendBuff[3] 表示数据长度 */
	if(sumcheck == ano->SendBuff[ano->SendBuff[3] + 4] && addcheck == ano->SendBuff[ano->SendBuff[3] + 5])
		return 1;
	else
		return 0;
}

/**
 * 函数名:	控制指令
 * 形 参:	_Ord命令
 * 返回值:	无
**/
__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;
	}
}

/**
 * 函数名:	参数回传设置
 * 形 参:	_id参数的ID
 * 返回值:	无
**/
__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;	//参数回传(第一组PID)

		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;	//参数回传(第二组PID)

		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;	//参数回传(第三组PID)

		default: SendParaData((uint8_t )_id,(int32_t)0x00);	break;	//若为其他参数则返回0	
	}
}

/**
 * 函数名:	参数数据读取设置
 * 形 参:	_id参数的ID
 * 			_val参数数据
 * 返回值:	无
**/
__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;	//参数回传硬件版本(此处借用拓空者)
	}
}

/**	
 *	函数名:	接收数据解析
 *	形	参:	_da数据(需为完整的一帧数据)
 *	返回值:	无
**/
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)		//判断CID和CMD0
				ControlOrder(_da[6]);	//控制指令(通过CMD1来控制程序)
			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]);//(uint8_t)(_da[4] + (_da[5] << 8));
				ParaOfReturn_Set(HeadID);	//参数回传
				MPara.OrderState = 0;	//命令回传结束
			}
		}
		else if(_da[2] == 0xE2)	//判断功能码(写参数)
		{
			if(Receive_CheckData(_da))
			{
				HeadID =  *(uint16_t*)(&_da[4]);// (uint8_t)(_da[4] + (_da[5] << 8));		//(*(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;	//命令回传结束
			}
		}
	}	
}

/**	
 *	函数名:	多数据配置函数(结合Ano_SendMdata多数据发送函数使用)
 *	形	参:	id->功能码(0xF1-0xFA) *data->发送的数据 len->数据长度(sizeof) num->用于指示第几个数据(可去除)
 *	返回值:	无
**/
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);
}

/**	
 *	函数名:	多数据发送(结合Ano_Set_Mdata多数据配置函数使用)
 *	形	参:	id->功能码(0xF1-0xFA) *data->发送的数据 len->数据长度(sizeof) num->用于指示第几个数据(可去除)
 *	返回值:	无
**/
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;
	}
}

/**	
 *	函数名:	发送数据函数
 * 	形	参:	id->功能码(0xF1-0xFA) *Data->发送的数据 lenth->数据长度(sizeof)
 *	返回值:	无
**/
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;
	}	
}

/**
 * 函数名:	发送LOGO信息
 * 形 参:	字符串\数字
 * 返回值:	无
**/
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();	//发送数据
}

/**
 * 函数名:	发送LOGO信息+数据信息
 * 形 参:	字符串\数字
 * 返回值:	无
**/
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)	//SIN函数
{
	return 100*sin(2*x);
}

float Ano_Show_Cos(float x)	//COS函数
{
	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);		//数据*10发送
	y2 = Ano_Show_Cos(x);		//数据*10发送
	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

	PID_2_P,
	PID_2_I,
	PID_2_D,		//第二组PID

	PID_3_P,
	PID_3_I,
	PID_3_D			//第三组PID
};

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;		//第一组PID

	uint16_t PID_Par2_P;
	uint16_t PID_Par2_I;
	uint16_t PID_Par2_D;	//第二组PID

	uint16_t PID_Par3_P;
	uint16_t PID_Par3_I;
	uint16_t PID_Par3_D;	//第三组PID
	/* data */
}_Para;

extern _ano MyAno;		//声明外部变量
extern _Para MPara;		//参数

/****** 用户不可调用函数 ******/
static void SendParaData(uint8_t Id,int32_t para);		//发送ID对应的参数
static void SendCheckAnalysis(uint8_t id,uint8_t *sumcheck,uint8_t *addcheck);		//发送数据校验帧0x00
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)  //判断是否是USART1
  {
    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(使用前将#替换为@)

ANO匿名上位机V7协议&STM32 的相关文章

  • 从零开始的c语言学习生活

    大家好 xff0c 我是一名c语言萌新 xff0c 今天开始我要csdn上记录我的学习 1 基本数据类型 xff1a 整数 浮点数 缺省 bool 2 构造数据类型 xff1a 结构体 共用体 枚举 数组 xff08 1 xff09 整数类
  • 将无符号的10进制的数转换为16进制,并打印输出

    将一个数转换成相应的进制 xff0c 一般是除这个数并取它的余数 若转换成16进制 xff0c 则除16取余 第一种方法是直接取余将得到的值存入数组中 相应代码如下 xff1a include lt stdio h gt include l
  • ROS指令集1(设置ROS_PACKAGE_PATH)

    ROS指令集 添加环境变量 局部环境变量 xff0c 添加后立即生效 xff0c 终端关闭后实效 span class token builtin class name echo span span class token environm
  • 字符串查找函数strstr

    函数结构 xff1a char strstr const char str1 const char str2 功能 xff1a 在字符串str1中查找是否存在str2字符串 返回值 xff1a 该函数返回str2在str1中首次出现的地址
  • 内存操作函数(memcpy,memmove,memset)

    前言 xff1a C 语言中对字符和字符串的处理很是频繁 xff0c 但是 C 语言本身是没有字符串类型的 xff0c 字符串通常放在 常量字符串 中或者字符数组 中 字符串常量 适用于那些对它不做修改的字符串函数 memcpy 函数 me
  • matlab关于GPU警告报错

    电脑配置 xff1a RTX3050 xff0c i5十二代 xff0c CUDA11 6 matlab2020a 报错信息 运行神经网络训练时 xff0c 显示警告信息 xff1a Warning The CUDA driver must
  • 错误使用 network/subsasgn>network_subsasgn net.b{2} must be a 2-by-1 matrix.解决方法

    使用生物算法优化bp时出现以下报错 1 错误使用 network subsasgn gt network subsasgn net b 2 must be a 2 by 1 matrix 2 出错 索引 第 14 行 net 61 netw
  • 网络基础(网络发展背景(IP地址,端口,协议,字节序))

    了解网络发展背景 对局域网 广域网的概念有基本认识 了解网络协议的意义 重点理解 TCP IP 五层结构模型 学习网络传输的基本流程 理解封装和分用 在 IP 数据包头部中 有两个 IP 地址 分别叫做源 IP 地址 和目的 IP 地址 端
  • 网络编程套接字

    能够实现一个简单的 udp 客户端 服务器 实现一个简单的 tcp 客户端 服务器 单连接版本 多进程版本 多线程版本 套接字编程 主要讲解的就是如何编写一个网络通信程序 1 网络通信的数据中都会包含一个完整的五元组 sipsportdip
  • 网络基础2

    网络基础2 应用层 amp 传输层典型协议 应用层 自定制协议 私有协议 xff0c HTTP协议 传输层 UDP amp TCP协议 应用层 负责应用程序之间的数据沟通 应用层协议其实是面向程序员的协议 xff0c 因为应用程序是程序员写
  • ubuntu服务器通过iso进行系统升级

    ubuntu服务器通过iso进行系统升级 1 添加iso文件源 xff1a sudo mount t iso9660 o loop ubuntu 18 04 6 live server amd64 iso media cdrom 挂在镜像文
  • ROS学习(1):gazebo保存加载世界

    roslaunch文件分析 xff08 古月居大神提供 xff0c 来源于ROS机器人开发实践视频 xff09 96 view mbot gazebo play ground launch lt launch gt lt 设置launch文
  • connect to host port 22: Connection refused

    Windows 使用SSH连接树莓派 xff1a 提示 xff1a 这里简述项目相关背景 xff1a 今天练习发现使用MobaXterm可以正常连接到树莓派 xff0c 但是使用windows终端就不可以连接 xff0c 显示connect
  • 8本游戏开发书籍推荐

    很多刚刚接触游戏开发的朋友经常问我 xff1a 如何开始学习游戏开发 xff1f 我从事游戏开发行业很多年了 xff0c 坦率地讲 xff0c 开发游戏充满挑战性 xff0c 需要开发人员具备大量的技能与积极的创新精神 希望这篇小文能帮助朋
  • windows通过SSH控制树莓派

    windows通过SSH控制树莓派 xff1a 因学习需要在windows系统下对树莓派进行SSH连接 xff0c 包括SSH密钥生成 密钥传输及公钥保存等 Windows下密钥的产生 在Windows下使用 ssh keygen生成公钥和
  • raspistill command not found

    raspistill command not found xff1a 提示 xff1a 这里简述项目相关背景 xff1a 今天使用树莓派来调用摄像头 xff0c 摄像头为树莓派官方摄像头 xff0c 在升级系统和配置后发现使用raspist
  • 树莓派I2C基本用法

    文章目录 一 I2C二 I2C配置1 I2C02 I2C13 I2C34 I2C45 I2C56 I2C6 三 I2C工具总结 一 I2C 树莓派默认打开I2C功能 xff0c 如果I2C没有打开 xff0c 可以使用命令sudo rasp
  • 树莓派RTC

    文章目录 一 RTC准备二 RTC芯片三 为什么使用hwclock显示找不到硬件总结 一 RTC准备 在使能树莓派RTC之前 xff0c 需要先为树莓派RTC模块安装电池 xff08 一般为纽扣电池 xff09 二 RTC芯片 树莓派4B使
  • 树莓派debian11更换国内源

    更换国内源 修改文件 etc apt sources list deb https mirrors tuna tsinghua edu cn debian bullseye main contrib non free span class
  • cpptools占用率过高

    问题描述 使用vscode发现在系统中cpptools CPU占用率达到百分百 电脑发生严重卡顿 解决方案 xff1a 此问题的出现是因为使用了C C 43 43 这个插件 xff0c 如果直接禁用此插件就可以解决这个问题 如果希望使用这个

随机推荐