基于RFbeam的V-LD1-60GHz毫米波雷达传感器数据获取(通过UART串口来控制模块)

news2024/10/5 16:22:40

基于RFbeam的V-LD1-60GHz毫米波雷达传感器数据获取(通过UART串口来控制模块)

文章目录

  • V-LD1
  • 命令发送
  • 消息回复
  • 通信示例
  • 雷达数据获取
  • 宏定义
  • 通信代码
  • 运行效果
  • 附录:压缩字符串、大小端格式转换
    • 压缩字符串
      • 浮点数
      • 压缩Packed-ASCII字符串
    • 大小端转换
      • 什么是大端和小端
      • 数据传输中的大小端
      • 总结
      • 大小端转换函数

V-LD1

该模块是由串口进行控制的
在这里插入图片描述
串口协议结构体如下:

#pragma pack(1)
typedef struct
{
	char Header[4];
	uint32_t Length;
	uint8_t DATA[43];
}V_LD1_Struct;
#pragma pack()

头文字是ASCII码字符串格式
然后四字节的Length表示DATA数据长度
数据位小端格式
在这里插入图片描述
通信方式就是先发一个命令 然后等待RESP返回 随后就是命令对应的数据

INIT命令支持修改波特率 但第一次发的时候必须用115200
在这里插入图片描述修改波特率后 直到GBYE命令或复位、断电之前 都是修改后的波特率

命令发送

读取雷达命令就是GNFD 另外配置雷达参数则是SRPS
在这里插入图片描述
在这里插入图片描述

消息回复

发什么命令 就按什么格式回复 但RESP是肯定会最先回复的
另外 读雷达参数用GRPS命令
在这里插入图片描述

通信示例

在这里插入图片描述

雷达数据获取

通过GNFD命令获取雷达数据
如果不需要读大量数据 可以只使用115200
在这里插入图片描述
在这里插入图片描述

宏定义

#ifndef __V_LD1_H__
#define __V_LD1_H__
#include "main.h"

#pragma pack(1)
typedef struct
{
	char Header[4];
	uint32_t Length;
	uint8_t DATA[43];
}V_LD1_Struct;
#pragma pack()

#pragma pack(1)
typedef struct
{
	char Version[19];
	char Unique_ID[12];
	uint8_t Distance_Range;
	uint8_t Threshold_Offset;
	uint16_t Min_Range_Filter;
	uint16_t Max_Range_Filter;
	uint8_t Distance_Average_Count;
	uint8_t Target_Filter;
	uint8_t Distance_Precision;
	uint8_t TX_Power;
	uint8_t Chirp_Integration_Count;
	uint8_t Short_Range_Distance_Filter;
}V_LD1_Radar_Parameter_Struct;
#pragma pack()

#pragma pack(1)
typedef struct
{
	uint16_t ADC_Value[1024];
}V_LD1_RADC_Struct;
#pragma pack()

#pragma pack(1)
typedef struct
{
	uint16_t Spectrum_Point[512];
	uint16_t Threshold_Point[512];
}V_LD1_RFFT_Struct;
#pragma pack()

#pragma pack(1)
typedef struct
{
	float Distance;
	uint16_t Magnitude_Of_Target;
}V_LD1_PDAT_Struct;
#pragma pack()

#pragma pack(1)
typedef struct
{
	uint32_t Frame_ID;
}V_LD1_DONE_Struct;
#pragma pack()

typedef enum
{
	V_LD1_GNFD_RADC = (1<<0),
	V_LD1_GNFD_RFFT = (1<<1),
	V_LD1_GNFD_PDAT = (1<<2),
	V_LD1_GNFD_DONE = (1<<5),
}V_LD1_GNFD_Enum;

typedef enum
{
	V_LD1_RESP_OK			 									= 0,
	V_LD1_RESP_Unknown_CMD			 				= 1,
	V_LD1_RESP_Invalid_Parameter_Value	= 2,
	V_LD1_RESP_Invalid_RPST_Version			= 3,
	V_LD1_RESP_UART_Error								= 4,
	V_LD1_RESP_No_Calibration_Value			= 5,
	V_LD1_RESP_Timeout									= 6,
	V_LD1_RESP_NO_Programmed						= 7,
}V_LD1_RESP_Enum;

extern uint8_t V_LD1_Status;
extern uint8_t V_LD1_RxBit;
extern uint8_t V_LD1_RxBuffer[1024];
extern uint8_t V_LD1_RxFlag;
extern V_LD1_Radar_Parameter_Struct V_LD1_Radar_Parameter_Global;

void Init_V_LD1(void);

void Read_V_LD1_Radar(void);
#endif

通信代码

# include "V_LD1.h"

uint8_t V_LD1_RxBit=0;
uint8_t V_LD1_RxBuffer[1024]={0};
uint8_t V_LD1_RxFlag=0;
uint8_t V_LD1_Status=0;

V_LD1_Radar_Parameter_Struct V_LD1_Radar_Parameter_Global={0};

V_LD1_Struct Read_V_LD1_Stu(void)
{
	V_LD1_Struct V_LD1_Stu;
	memset(&V_LD1_Stu,0,sizeof(V_LD1_Stu));
	uint8_t i=0;
	while(V_LD1_Status<2)
	{
		i++;
		delay_ms(10);
		if(i>=50)
		{
			V_LD1_RxBit=0;
			V_LD1_Status=0;
			V_LD1_RxFlag=0;
			return V_LD1_Stu;
		}
	}
	
	memcpy(&V_LD1_Stu.Header[0],&V_LD1_RxBuffer[0],4);
	memcpy(&V_LD1_Stu.Length,&V_LD1_RxBuffer[4],4);
	memcpy(&V_LD1_Stu.DATA[0],&V_LD1_RxBuffer[8],V_LD1_Stu.Length);
	V_LD1_RxBit=0;
	V_LD1_Status=0;
	V_LD1_RxFlag=0;
	
	return V_LD1_Stu;
}

void Send_V_LD1_Stu(V_LD1_Struct V_LD1_Stu)
{
	uint8_t buf[51]={0};
	memcpy(buf,&V_LD1_Stu,V_LD1_Stu.Length+8);
	V_LD1_RxBit=0;
	V_LD1_Status=0;
	V_LD1_RxFlag=0;
	HAL_UART_Transmit(&V_LD1_UART_Handle,buf,V_LD1_Stu.Length+8,0xFFFF);
}

int Read_V_LD1_RESP(void)
{
	V_LD1_Struct V_LD1_Stu=Read_V_LD1_Stu();
	if (V_LD1_Stu.Header[0]=='R' && V_LD1_Stu.Header[1]=='E' && V_LD1_Stu.Header[2]=='S' && V_LD1_Stu.Header[3]=='P' && V_LD1_Stu.Length==1)
	{
		return V_LD1_Stu.DATA[0];
	}
	else
	{
		return -1;
	}
}

int Read_V_LD1_VERS(V_LD1_Struct* V_LD1)
{
	V_LD1_Struct V_LD1_Stu=Read_V_LD1_Stu();
	if (V_LD1_Stu.Header[0]=='V' && V_LD1_Stu.Header[1]=='E' && V_LD1_Stu.Header[2]=='R' && V_LD1_Stu.Header[3]=='S' && V_LD1_Stu.Length==19)
	{
		memcpy(V_LD1,&V_LD1_Stu,27);
		return 0;
	}
	else
	{
		return -1;
	}
}

void Read_V_LD1_Radar(void)
{
	V_LD1_Struct V_LD1_Stu={0};
	V_LD1_PDAT_Struct PDAT_Stu = {0};
	GUI_Struct Stu={0};
	uint8_t RESP_Code=0;
	
	memcpy(&V_LD1_Stu.Header[0],"GNFD",4);
	V_LD1_Stu.Length=1;
	V_LD1_Stu.DATA[0]=0|V_LD1_GNFD_PDAT;	
	Send_V_LD1_Stu(V_LD1_Stu);
	RESP_Code=Read_V_LD1_RESP();
	printf("[INFO] GNFD PDAT RESP: %d\n",RESP_Code);
	
	V_LD1_Stu=Read_V_LD1_Stu();
	
	if (V_LD1_Stu.Header[0]=='P' && V_LD1_Stu.Header[1]=='D' && V_LD1_Stu.Header[2]=='A' && V_LD1_Stu.Header[3]=='T' && V_LD1_Stu.Length==6)
	{
		memcpy(&PDAT_Stu,&V_LD1_Stu.DATA[0],6);
		printf("[INFO] PDAT: %f %d\n",PDAT_Stu.Distance,PDAT_Stu.Magnitude_Of_Target);
		Stu.COM=0x00;
		Stu.BCNT[0]=0;
		Stu.BCNT[1]=6;
		memcpy(&Stu.DATA[0],&PDAT_Stu,6);
		GUI_Slave_Send(Stu);
	}
}

void Init_Radar_Parameter(void)
{
	V_LD1_Radar_Parameter_Global.Distance_Range=0;
	V_LD1_Radar_Parameter_Global.Threshold_Offset=60;
	V_LD1_Radar_Parameter_Global.Min_Range_Filter=5;
	V_LD1_Radar_Parameter_Global.Max_Range_Filter=460;
	V_LD1_Radar_Parameter_Global.Distance_Average_Count=5;
	V_LD1_Radar_Parameter_Global.Target_Filter=0;
	V_LD1_Radar_Parameter_Global.Distance_Precision=1;
	V_LD1_Radar_Parameter_Global.TX_Power=31;
	V_LD1_Radar_Parameter_Global.Chirp_Integration_Count=20;
	V_LD1_Radar_Parameter_Global.Short_Range_Distance_Filter=0;
}

void Init_V_LD1(void)
{
	V_LD1_Struct V_LD1_Stu={0};
	V_LD1_RxBit=0;
	V_LD1_Status=0;
	V_LD1_RxFlag=0;
	
	uint8_t RESP_Code=0;
	memset(V_LD1_RxBuffer,0,sizeof(V_LD1_RxBuffer));
	
	memcpy(&V_LD1_Stu.Header[0],"RFSE",4);
	V_LD1_Stu.Length=0;
	Send_V_LD1_Stu(V_LD1_Stu);
	RESP_Code=Read_V_LD1_RESP();
	printf("[INFO] RFSE RESP: %d\n",RESP_Code);
	
	memcpy(&V_LD1_Stu.Header[0],"INIT",4);
	V_LD1_Stu.Length=1;
	V_LD1_Stu.DATA[0]=0;	
	Send_V_LD1_Stu(V_LD1_Stu);
	RESP_Code=Read_V_LD1_RESP();
	printf("[INFO] INIT RESP: %d\n",RESP_Code);
	
	if(RESP_Code==V_LD1_RESP_OK)
	{
		if(Read_V_LD1_VERS(&V_LD1_Stu)==0)
		{
			printf("[INFO] V_LD1_Version: %s\n",V_LD1_Stu.DATA);
			memcpy(&V_LD1_Radar_Parameter_Global.Version[0],&V_LD1_Stu.DATA[0],19);
		}
	}
	
	memcpy(&V_LD1_Stu.Header[0],"TGFI",4);
	V_LD1_Stu.Length=1;	
	V_LD1_Stu.DATA[0]=0	;
	Send_V_LD1_Stu(V_LD1_Stu);
	RESP_Code=Read_V_LD1_RESP();
	printf("[INFO] TGFI RESP: %d\n",RESP_Code);
	
	memcpy(&V_LD1_Stu.Header[0],"INTN",4);
	V_LD1_Stu.Length=1;	
	V_LD1_Stu.DATA[0]=20;
	Send_V_LD1_Stu(V_LD1_Stu);
	RESP_Code=Read_V_LD1_RESP();
	printf("[INFO] INTN RESP: %d\n",RESP_Code);
	
	memcpy(&V_LD1_Stu.Header[0],"SRDF",4);
	V_LD1_Stu.Length=1;	
	V_LD1_Stu.DATA[0]=0;
	Send_V_LD1_Stu(V_LD1_Stu);
	RESP_Code=Read_V_LD1_RESP();
	printf("[INFO] SRDF RESP: %d\n",RESP_Code);
	
	Read_V_LD1_Radar();	
}

运行效果

在这里插入图片描述

附录:压缩字符串、大小端格式转换

压缩字符串

首先HART数据格式如下:
在这里插入图片描述
在这里插入图片描述
重点就是浮点数和字符串类型
Latin-1就不说了 基本用不到

浮点数

浮点数里面 如 0x40 80 00 00表示4.0f

在HART协议里面 浮点数是按大端格式发送的 就是高位先发送 低位后发送

发送出来的数组为:40,80,00,00

但在C语言对浮点数的存储中 是按小端格式来存储的 也就是40在高位 00在低位
浮点数:4.0f
地址0x1000对应00
地址0x1001对应00
地址0x1002对应80
地址0x1003对应40

若直接使用memcpy函数 则需要进行大小端转换 否则会存储为:
地址0x1000对应40
地址0x1001对应80
地址0x1002对应00
地址0x1003对应00

大小端转换:

void swap32(void * p)
{
   uint32_t *ptr=p;
   uint32_t x = *ptr;
   x = (x << 16) | (x >> 16);
   x = ((x & 0x00FF00FF) << 8) | ((x >> 8) & 0x00FF00FF);

   *ptr=x;
}

压缩Packed-ASCII字符串

本质上是将原本的ASCII的最高2位去掉 然后拼接起来 比如空格(0x20)
四个空格拼接后就成了
1000 0010 0000 1000 0010 0000
十六进制:82 08 20
对了一下表 0x20之前的识别不了
也就是只能识别0x20-0x5F的ASCII表
在这里插入图片描述

压缩/解压函数后面再写:

//传入的字符串和数字必须提前声明 且字符串大小至少为str_len 数组大小至少为str_len%4*3 str_len必须为4的倍数
uint8_t Trans_ASCII_to_Pack(uint8_t * str,uint8_t * buf,const uint8_t str_len)
{
   if(str_len%4)
   {
      return 0;
   }
	 
   uint8_t i=0;
   memset(buf,0,str_len/4*3);	  
   for(i=0;i<str_len;i++)
   {
      if(str[i]==0x00)
      {
         str[i]=0x20;
      }
   }

   for(i=0;i<str_len/4;i++)
   {
      buf[3*i]=(str[4*i]<<2)|((str[4*i+1]>>4)&0x03);
      buf[3*i+1]=(str[4*i+1]<<4)|((str[4*i+2]>>2)&0x0F);
      buf[3*i+2]=(str[4*i+2]<<6)|(str[4*i+3]&0x3F);
   }

   return 1;
}

//传入的字符串和数字必须提前声明 且字符串大小至少为str_len 数组大小至少为str_len%4*3 str_len必须为4的倍数
uint8_t Trans_Pack_to_ASCII(uint8_t * str,uint8_t * buf,const uint8_t str_len)
{
   if(str_len%4)
   {
      return 0;
   }

   uint8_t i=0;

   memset(str,0,str_len);

   for(i=0;i<str_len/4;i++)
   {
      str[4*i]=(buf[3*i]>>2)&0x3F;
      str[4*i+1]=((buf[3*i]<<4)&0x30)|(buf[3*i+1]>>4);
      str[4*i+2]=((buf[3*i+1]<<2)&0x3C)|(buf[3*i+2]>>6);
      str[4*i+3]=buf[3*i+2]&0x3F;
   }

   return 1;
}


大小端转换

在串口等数据解析中 难免遇到大小端格式问题

什么是大端和小端

所谓的大端模式,就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。

所谓的小端模式,就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。

简单来说:大端——高尾端,小端——低尾端

举个例子,比如数字 0x12 34 56 78在内存中的表示形式为:

1)大端模式:

低地址 -----------------> 高地址

0x12 | 0x34 | 0x56 | 0x78

2)小端模式:

低地址 ------------------> 高地址

0x78 | 0x56 | 0x34 | 0x12

可见,大端模式和字符串的存储模式类似。

数据传输中的大小端

比如地址位、起止位一般都是大端格式
如:
起始位:0x520A
则发送的buf应为{0x52,0x0A}

而数据位一般是小端格式(单字节无大小端之分)
如:
一个16位的数据发送出来为{0x52,0x0A}
则对应的uint16_t类型数为: 0x0A52

而对于浮点数4.0f 转为32位应是:
40 80 00 00

以大端存储来说 发送出来的buf就是依次发送 40 80 00 00

以小端存储来说 则发送 00 00 80 40

由于memcpy等函数 是按字节地址进行复制 其复制的格式为小端格式 所以当数据为小端存储时 不用进行大小端转换
如:

uint32_t dat=0;
uint8_t buf[]={0x00,0x00,0x80,0x40};
   memcpy(&dat,buf,4);
   float f=0.0f;
   f=*((float*)&dat); //地址强转
   printf("%f",f);

或更优解:

   uint8_t buf[]={0x00,0x00,0x80,0x40};   
   float f=0.0f;
   memcpy(&f,buf,4);

而对于大端存储的数据(如HART协议数据 全为大端格式) 其复制的格式仍然为小端格式 所以当数据为小端存储时 要进行大小端转换
如:

uint32_t dat=0;
uint8_t buf[]={0x40,0x80,0x00,0x00};
   memcpy(&dat,buf,4);
   float f=0.0f;
   swap32(&dat); //大小端转换
   f=*((float*)&dat); //地址强转
   printf("%f",f);

或:

uint8_t buf[]={0x40,0x80,0x00,0x00};
   memcpy(&dat,buf,4);
   float f=0.0f;
   swap32(&f); //大小端转换
   printf("%f",f);

或更优解:

uint32_t dat=0;
uint8_t buf[]={0x40,0x80,0x00,0x00};
   float f=0.0f;
   dat=(buf[0]<<24)|(buf[0]<<16)|(buf[0]<<8)|(buf[0]<<0)
   f=*((float*)&dat);

总结

固 若数据为小端格式 则可以直接用memcpy函数进行转换 否则通过移位的方式再进行地址强转

对于多位数据 比如同时传两个浮点数 则可以定义结构体之后进行memcpy复制(数据为小端格式)

对于小端数据 直接用memcpy写入即可 若是浮点数 也不用再进行强转

对于大端数据 如果不嫌麻烦 或想使代码更加简洁(但执行效率会降低) 也可以先用memcpy写入结构体之后再调用大小端转换函数 但这里需要注意的是 结构体必须全为无符号整型 浮点型只能在大小端转换写入之后再次强转 若结构体内采用浮点型 则需要强转两次

所以对于大端数据 推荐通过移位的方式来进行赋值 然后再进行个别数的强转 再往通用结构体进行写入

多个不同变量大小的结构体 要主要字节对齐的问题
可以用#pragma pack(1) 使其对齐为1
但会影响效率

大小端转换函数

直接通过对地址的操作来实现 传入的变量为32位的变量
中间变量ptr是传入变量的地址

void swap16(void * p)
{
   uint16_t *ptr=p;
   uint16_t x = *ptr;
   x = (x << 8) | (x >> 8);

   *ptr=x;
}

void swap32(void * p)
{
   uint32_t *ptr=p;
   uint32_t x = *ptr;
   x = (x << 16) | (x >> 16);
   x = ((x & 0x00FF00FF) << 8) | ((x >> 8) & 0x00FF00FF);

   *ptr=x;
}

void swap64(void * p)
{
   uint64_t *ptr=p;
   uint64_t x = *ptr;
   x = (x << 32) | (x >> 32);
   x = ((x & 0x0000FFFF0000FFFF) << 16) | ((x >> 16) & 0x0000FFFF0000FFFF);
   x = ((x & 0x00FF00FF00FF00FF) << 8) | ((x >> 8) & 0x00FF00FF00FF00FF);

   *ptr=x;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1209492.html

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

相关文章

Istio学习笔记- 服务网格

Istio 服务网格 参考&#xff1a;Istio / Istio 服务网格 Istio 使用功能强大的 Envoy 服务代理扩展了 Kubernetes&#xff0c;以建立一个可编程的、可感知的应用程序网络。Istio 与 Kubernetes 和传统工作负载一起使用&#xff0c;为复杂的部署带来了标准的通用流量管理、遥…

大数据知识图谱项目——基于知识图谱的电影问答系统(超详细讲解及源码)

大数据知识图谱项目——基于知识图谱的电影问答系统&#xff08;超详细讲解及源码&#xff09; 一、项目概述 知识图谱是将知识连接起来形成的一个网络。由节点和边组成&#xff0c;节点是实体&#xff0c;边是两个实体的关系&#xff0c;节点和边都可以有属性。知识图谱除了…

【网络奇缘】- 计算机网络|网络类型|性能指标

&#x1f308;个人主页: Aileen_0v0&#x1f525;系列专栏: 一见倾心,再见倾城 --- 计算机网络~&#x1f4ab;个人格言:"没有罗马,那就自己创造罗马~" 目录 计算机网络分类 1.根据范围分类 ​编辑 2.按使用者分​编辑 3.按交换技术分 ​编辑4.按拓扑结构分 ​…

基恩士软件的基本操作(三,监控台调试)

目录 模拟器 模拟器编辑 plc的传输 监控器 在线编辑 程序出现问题时的排查方法 接点跳转功能 交叉参考功能 关系映射功能 程序监控器 登录监控器&#xff08;查看与修改软元件的值&#xff09; 批量监控器 实时时序图 单元监控器 I/O单元监控器 运动单元监控器…

【Shell脚本11】Shell 函数

Shell 函数 linux shell 可以用户定义函数&#xff0c;然后在shell脚本中可以随便调用。 shell中函数的定义格式如下&#xff1a; [ function ] funname [()]{action;[return int;]}说明&#xff1a; 1、可以带function fun() 定义&#xff0c;也可以直接fun() 定义,不带任何…

Latex在图表标题里面引用参考文献时,出现参考文献顺序混乱的解决方案(适用于bibtex)

问题描述 如果你在figure环境的\caption或\captionof中使用\cite&#xff0c;但是参考文献的顺序仍然不正确&#xff0c;可能是因为LaTeX的处理流程导致了这个问题。 比如图片在第二章节但里面引用了参考文献&#xff0c;在文章末尾的参考文献第二章图片的参考文献顺序&#…

CCNA课程实验-14-Final_Lab

目录 实验条件网络拓朴需求 配置实现1. 配置PC1~3, DHCP_Server的vlan2. VLAN10、20的网关为MSW1对应的SVI&#xff0c;VLAN30、40的网关为MSW2对应的SVI&#xff1b;3. 配置5台交换机之间线路均为Trunk4. 配置5台交换机均启用Rapid-PVST(RSTP)5. 配置DHCP Server&#xff0c;创…

Uniapp开发 购物商城源码 在线电商商城源码 适配移动终端项目及各小程序

lilishop电商商城系统 商城移动端&#xff0c;使用Uniapp开发&#xff0c;可编译为所有移动终端项目及各小程序 源码下载&#xff1a;https://download.csdn.net/download/m0_66047725/88487579 源码下载2&#xff1a;关注我留言

Camtasia 2024中文版功能介绍

在如今的数字时代&#xff0c;屏幕录制已成为许多工作或学习中不可或缺的一部分&#xff0c;无论是制作教学视频、演示软件功能&#xff0c;还是为了录制游戏过程&#xff0c;屏幕录制软件都扮演着至关重要的角色。实际上屏幕录制不仅仅可以单纯录制屏幕&#xff0c;还能玩出非…

​软考-高级-系统架构设计师教程(清华第2版)【第5章 软件工程基础知识(190~233)-思维导图】​

软考-高级-系统架构设计师教程&#xff08;清华第2版&#xff09;【第5章 软件工程基础知识&#xff08;190~233&#xff09;-思维导图】 课本里章节里所有蓝色字体的思维导图

【Linux网络】1分钟使用shell脚本完成DNS主从解析服务器部署(适用于centos主机)

DNS正向解析主从解析服务器脚本 1、脚本内容 主服务器脚本 #!/bin/bash ##先修改本地DNS缓存服务器 read -p "请输入主服务器ip地址&#xff1a;" masterIP sed -i /DNS/d /etc/sysconfig/network-scripts/ifcfg-ens33 echo "DNS$masterIP" >> /e…

electronjs入门-编辑器应用程序

我们将在Electron中创建一个新项目&#xff0c;如我们在第1章中所示&#xff0c;名为“编辑器”&#xff0c;我们将在下一章中使用它来创建编辑器&#xff1b;在index.js中&#xff0c;这是我们的主要过程&#xff1b;请记住为Electron软件包放置必要的依赖项&#xff1a; npm…

【MediaFoundation】相关的概念

MF 概览 Media Foundation 提供了两种不同的编程模型&#xff0c;左边展示的是端到端的媒体数据模型&#xff0c;主要用在&#xff1a;播放URL或者文件&#xff0c;以及控制流。 在图表右侧展示的第二种模型中&#xff0c;应用程序可以从源头拉取数据&#xff0c;也可以将数据…

代号:408 —— 1000道精心打磨的计算机考研题

文章目录 &#x1f4cb;前言&#x1f3af;计算机科学与技术专业介绍&#xff08;14年发布&#xff09;&#x1f9e9;培养目标&#x1f9e9;毕业生应具备的知识和能力&#x1f9e9;主要课程 &#x1f3af;代号&#xff1a;408&#x1f525;文末送书&#x1f9e9;有什么优势&…

量化交易:使用 python 进行股票交易回测

执行环境: Google Colab 1. 下载数据 import yfinance as yfticker ZM df yf.download(ticker) df2. 数据预处理 df df.loc[2020-01-01:].copy()使用了 .loc 方法来选择索引为 ‘2020-01-01’ 以后的所有行数据。通过 .copy() 方法创建了一个这些数据的副本&#xff0c;确…

PCA9698的IIC转接GPIO控制N路灯

PCA9698验证灯的办法和PCA9535验证6路数字继电器&#xff0c;编译成ko直接Insmod&#xff0c;然后查看/dev/节点有了吗&#xff1f;然后用iictool命令往对应iic地址上面写数据&#xff0c;看看灯亮灭或者听继电器开关声响&#xff0c;至于写多少&#xff0c;研究芯片手册上面参…

Spark SQL编程

1. Spark SQL概述 1.1 什么是Spark SQL Spark SQL是用于结构化数据处理的Spark模块。与基本的Spark RDD API不同&#xff0c;Spark SQL提供的接口为Spark提供了有关数据结构和正在执行的计算的更多信息。在内部&#xff0c;Spark SQL使用这些额外的信息来执行额外的优化。与Spa…

Mac M2/M3 芯片环境配置以及常用软件安装-前端

最近换了台新 Mac&#xff0c;所有的配置和软件就重新安装下&#xff0c;顺便写个文章。 一、环境配置 1. 安装 Homebrew 安装 Homebrew【Mac 安装 Homebrew】 通过国内镜像安装会比较快 /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Ho…

IDEA接口调试插件不好找?这款免费用!

IDEA插件市场中的API调试插件不是收费&#xff08;Fast Request &#xff09;就是不好用&#xff08;apidoc、apidocx等等&#xff09;今天给大家介绍一款国产的API调试插件&#xff1a;Apipost-Helper&#xff0c;完全免费且好看好用&#xff01; 这款插件由Apipost团队开发的…

【Qt之QWizard】使用2,示例分析

效果图 根据首页的选择不同&#xff0c;进入不同的选项。 以下是代码。 示例 .h #ifndef LICENSEWIZARD_H #define LICENSEWIZARD_H#include <QWizard>QT_BEGIN_NAMESPACE class QCheckBox; class QLabel; class QLineEdit; class QRadioButton; QT_END_NAMESPACEcla…