课题学习(十八)----捷联测试电路设计与代码实现(基于MPU6050和QMC5883L)

一、 电路设计

  本周主要工作是在项目上,抽空做了一个跟本课题相关的电路板,之前用开发板来做测试,MPU6050和QMC5883L都是用杜邦线连接的,导致接线很乱,也不美观,当然也不符合“捷联”的定义。
  下面是电路的原理图和PCB,因为已经购买了MPU6050和QMC5883L模块,所以直接使用这些模块来做,不再设计外围电路(不是懒,主要是这个电路板做测试使用,后续做课题看不会用这中比较low的MEMS传感器)。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
  本次设计的电路有以下几个特点:

  • 外扩排针,各模块仍然可以正常单独使用
  • 外扩电源,可以使用5V电源直接供电
  • 增加蓝牙模块,并设置为115200波特率,可以通过无线的方式获取传感器的数据
  • 增加ICM20602,可以选择使用MPU6050或者ICM20602
  • 单独设计各模块的封装库(目前无3D模型),并标注三轴的方向已经对应模块的螺孔,可以根据封装库的位置直接增加螺孔
      部分封装库如下所示:
    在这里插入图片描述
      有需要的可以联系我,或者去我的资源中进行下载。

二、 代码

  下面是相关的部分代码:
  ICM20602的代码可参考博客:STM32Cube高效开发教程<基础篇>(十四)----SPI通信及ICM20602软件开发,本博客后续的资源链接中也会包含ICM20602的代码。
  MPU6050.c:

#include "mpu6050.h"
#include "stm32f1xx_hal.h"
uint8_t addressMPU6050;int16_t adcAccel_MPU6050[3]={0},adcGyro_MPU6050[3]={0};  
//初始化MPU6050
//返回值:0,成功
//    其他,错误代码
uint8_t MPU_Init(void)
{ // MPU_IIC_Init();//初始化IIC总线MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X80);	//复位MPU6050HAL_Delay(100);MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X00);	//唤醒MPU6050 MPU_Set_Gyro_Fsr(3);					//陀螺仪传感器,±2000dpsMPU_Set_Accel_Fsr(0);					//加速度传感器,±2gMPU_Set_Rate(50);						//设置采样率50HzMPU_Write_Byte(MPU_INT_EN_REG,0X00);	//关闭所有中断MPU_Write_Byte(MPU_USER_CTRL_REG,0X00);	//I2C主模式关闭MPU_Write_Byte(MPU_FIFO_EN_REG,0X00);	//关闭FIFOMPU_Write_Byte(MPU_INTBP_CFG_REG,0X80);	//INT引脚低电平有效addressMPU6050=MPU_Read_Byte(MPU_DEVICE_ID_REG); if(addressMPU6050==MPU_ADDR)//器件ID正确{MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X01);	//设置CLKSEL,PLL X轴为参考MPU_Write_Byte(MPU_PWR_MGMT2_REG,0X00);	//加速度与陀螺仪都工作MPU_Set_Rate(50);						//设置采样率为50Hz}else return 1;
//		MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X01);	//设置CLKSEL,PLL X轴为参考
//		MPU_Write_Byte(MPU_PWR_MGMT2_REG,0X00);	//加速度与陀螺仪都工作
//		MPU_Set_Rate(50);						//设置采样率为50HzMPU_IIC_SCL_HIG;MPU_IIC_SDA_HIG;return 0;
}
//设置MPU6050陀螺仪传感器满量程范围
//fsr:0,±250dps;1,±500dps;2,±1000dps;3,±2000dps
//返回值:0,设置成功
//    其他,设置失败 
uint8_t MPU_Set_Gyro_Fsr(uint8_t fsr)
{return MPU_Write_Byte(MPU_GYRO_CFG_REG,fsr<<3);//设置陀螺仪满量程范围  
}
//设置MPU6050加速度传感器满量程范围
//fsr:0,±2g;1,±4g;2,±8g;3,±16g
//返回值:0,设置成功
//    其他,设置失败 
uint8_t MPU_Set_Accel_Fsr(uint8_t fsr)
{return MPU_Write_Byte(MPU_ACCEL_CFG_REG,fsr<<3);//设置加速度传感器满量程范围  
}
//设置MPU6050的数字低通滤波器
//lpf:数字低通滤波频率(Hz)
//返回值:0,设置成功
//    其他,设置失败 
uint8_t MPU_Set_LPF(uint16_t lpf)
{uint8_t data=0;if(lpf>=188)data=1;else if(lpf>=98)data=2;else if(lpf>=42)data=3;else if(lpf>=20)data=4;else if(lpf>=10)data=5;else data=6; return MPU_Write_Byte(MPU_CFG_REG,data);//设置数字低通滤波器  
}
//设置MPU6050的采样率(假定Fs=1KHz)
//rate:4~1000(Hz)
//返回值:0,设置成功
//    其他,设置失败 
uint8_t MPU_Set_Rate(uint16_t rate)
{uint8_t data;if(rate>1000)rate=1000;if(rate<4)rate=4;data=1000/rate-1;data=MPU_Write_Byte(MPU_SAMPLE_RATE_REG,data);	//设置数字低通滤波器return MPU_Set_LPF(rate/2);	//自动设置LPF为采样率的一半
}//得到温度值
//返回值:温度值(扩大了100倍)
short MPU_Get_Temperature(void)
{uint8_t buf[2]; short raw;float temp;MPU_Read_Len(MPU_ADDR,MPU_TEMP_OUTH_REG,2,buf); raw=((uint16_t)buf[0]<<8)|buf[1];  temp=36.53+((double)raw)/340;  return temp*100;;
}
//得到陀螺仪值(原始值)
//gx,gy,gz:陀螺仪x,y,z轴的原始读数(带符号)
//返回值:0,成功
//    其他,错误代码
uint8_t MPU_Get_Gyroscope(short *gx,short *gy,short *gz)
{uint8_t buf[6],res;  res=MPU_Read_Len(MPU_ADDR,MPU_GYRO_XOUTH_REG,6,buf);if(res==0){*gx=((uint16_t)buf[0]<<8)|buf[1];  *gy=((uint16_t)buf[2]<<8)|buf[3];  *gz=((uint16_t)buf[4]<<8)|buf[5];adcGyro_MPU6050[0]=(buf[0]<<8)|buf[1];  adcGyro_MPU6050[1]=(buf[2]<<8)|buf[3];  adcGyro_MPU6050[2]=(buf[4]<<8)|buf[5];} 	return res;;
}
//得到加速度值(原始值)
//gx,gy,gz:陀螺仪x,y,z轴的原始读数(带符号)
//返回值:0,成功
//    其他,错误代码
uint8_t MPU_Get_Accelerometer(short *ax,short *ay,short *az)
{uint8_t buf[6],res;  res=MPU_Read_Len(MPU_ADDR,MPU_ACCEL_XOUTH_REG,6,buf);if(res==0){*ax=((uint16_t)buf[0]<<8)|buf[1];  *ay=((uint16_t)buf[2]<<8)|buf[3];  *az=((uint16_t)buf[4]<<8)|buf[5];adcAccel_MPU6050[0]=(buf[0]<<8)|buf[1];  adcAccel_MPU6050[1]=(buf[2]<<8)|buf[3];  adcAccel_MPU6050[2]=(buf[4]<<8)|buf[5];} 	return res;
}

  QMC5883L.c

// 模拟IIC发送单字节时序
uint8_t QMC5883L_SendByte(uint8_t Sim_i2c_data)
{uint8_t i;SDA1_OUT();QMC5883L_SCL_LOW;for(i=0; i<8; i++){if(Sim_i2c_data&0x80) QMC5883L_SDA_HIG;else QMC5883L_SDA_LOW;Sim_i2c_data<<=1;QMC5883L_NOP;QMC5883L_SCL_HIG;QMC5883L_NOP;QMC5883L_SCL_LOW;QMC5883L_NOP;}return QMC5883L_READY;
}// 模拟IIC发送单字节时序
uint8_t QMC5883L_ReceiveByte(void)
{uint8_t i,Sim_i2c_data;SDA1_IN();//QMC5883L_SDA_HIG;
// QMC5883L_SCL_LOW;Sim_i2c_data=0;for(i=0; i<8; i++){QMC5883L_SCL_LOW;QMC5883L_NOP;QMC5883L_SCL_HIG;// QMC5883L_NOP;Sim_i2c_data<<=1;SDA_Pin_State = QMC5883L_SDA_STATE;if(QMC5883L_SDA_STATE)	Sim_i2c_data|=0x01;// QMC5883L_SCL_LOW;QMC5883L_NOP;}QMC5883L_SendNACK();return Sim_i2c_data;
}// 模拟IIC读单字节,带应答
uint8_t QMC5883L_ReceiveByte_WithACK(void)
{uint8_t i,Sim_i2c_data;SDA1_IN();//QMC5883L_SDA_HIG;
// QMC5883L_SCL_LOW;Sim_i2c_data=0;for(i=0; i<8; i++){QMC5883L_SCL_LOW;QMC5883L_NOP;QMC5883L_SCL_HIG;// QMC5883L_NOP;Sim_i2c_data<<=1;if(QMC5883L_SDA_STATE)	Sim_i2c_data|=0x01;// QMC5883L_SCL_LOW;QMC5883L_NOP;}QMC5883L_SendACK();return Sim_i2c_data;
}// 模拟IIC的多字节读
uint8_t QMC5883L_Read8(uint8_t moni_dev_addr, uint8_t moni_reg_addr, uint8_t moni_i2c_len, uint8_t *moni_i2c_data_buf)
{QMC5883L_START();QMC5883L_SendByte(moni_dev_addr << 1 | WRITE );QMC5883L_Wait_Ack();QMC5883L_SendByte(moni_reg_addr);QMC5883L_Wait_Ack();//QMC5883L_STOP();QMC5883L_START();QMC5883L_SendByte(moni_dev_addr <<1 | READ );QMC5883L_Wait_Ack();while (moni_i2c_len){if (moni_i2c_len==1) *moni_i2c_data_buf =QMC5883L_ReceiveByte();else *moni_i2c_data_buf =QMC5883L_ReceiveByte_WithACK();moni_i2c_data_buf++;moni_i2c_len--;}QMC5883L_STOP();return 0x00;
}// 模拟IIC的多字节写
int8_t QMC5883L_Write8(uint8_t moni_dev_addr, uint8_t moni_reg_addr, uint8_t moni_i2c_len, uint8_t *moni_i2c_data_buf)
{uint8_t i;QMC5883L_START();QMC5883L_SendByte(moni_dev_addr << 1 | WRITE);  // 写指令QMC5883L_Wait_Ack();QMC5883L_SendByte(moni_reg_addr);QMC5883L_Wait_Ack();//QMC5883L_START();for (i=0; i<moni_i2c_len; i++){QMC5883L_SendByte(moni_i2c_data_buf[i]);QMC5883L_Wait_Ack();}QMC5883L_STOP();	return 0;
}uint8_t highByte(uint16_t value)
{uint8_t ret;value = value>>8;ret = (uint8_t)value;return ret;
}uint8_t lowByte(uint16_t value)
{uint8_t ret;value = value&0x00ff;ret = (uint8_t)value;return ret;
}// 读一个字节
uint8_t readOneByte(uint8_t in_adr)
{uint8_t retVal = -1;QMC5883L_Read8(QMC5883L_ADDR,in_adr,1,&retVal);QMC5883L_NOP;return retVal;
}// 读两个字节
uint16_t readTwoBytes(uint8_t in_adr_hi, uint8_t in_adr_lo)
{uint16_t retVal = -1;uint8_t low=0,high=0;/* Read Low Byte */low = readOneByte(in_adr_lo);/* Read High Byte */  high = readOneByte(in_adr_hi);//printf("high:%d,low:%d  ",high,low);retVal = high << 8;retVal = retVal | low;//printf("retVal:%d\r\n",retVal);return retVal;
}// 写一个字节
void writeOneByte(uint8_t adr_in, uint8_t dat_in)
{uint8_t dat = dat_in;QMC5883L_Write8(QMC5883L_ADDR,adr_in,1,&dat);
}// 获取地址
int16_t getAddress()
{return QMC5883L_ADDR; 
}//************************写入单字节数据***************************//初始化QMC5883,根据需要请参考pdf进行修改****
void Init_QMC5883()
{uint8_t addrVale;addrVale = 0x1D;QMC5883L_Write8(QMC5883L_ADDR,CONTROL_REG_1,1,&addrVale);  //控制寄存器配置addrVale = 0x01;QMC5883L_Write8(QMC5883L_ADDR,SET_RESET_REG,1,&addrVale);  //设置清除时间寄存器
}void GetMagValue(void)
{QMC5883L_Read8(QMC5883L_ADDR,XOUT_L,6,Buff);MagnetRawAd[0] = ((int16_t)Buff[1] << 8) | Buff[0];MagnetRawAd[1] = ((int16_t)Buff[3] << 8) | Buff[2];MagnetRawAd[2] = ((int16_t)Buff[5] << 8) | Buff[4];
}

  QMC5883L.h

#ifndef __MD_AS5600_H
#define __MD_AS5600_H#include "stm32f1xx_hal.h"  //这个需要根据不同的芯片类型进行变换
#include "main.h"// QMC地址
#define QMC5883L_ADDR               0x0D// 三轴磁力计输出寄存器
#define XOUT_L               0x00
#define XOUT_H               0x01#define YOUT_L               0x02
#define YOUT_H               0x03#define ZOUT_L               0x04
#define ZOUT_H               0x05// 状态寄存器
#define STATUS               0x06// 温度输出寄存器
#define TEMP_L               0x07
#define TEMP_H               0x08// 控制寄存器
#define CONTROL_REG_1               0x09
#define CONTROL_REG_2               0x0A// SET/RESET,推荐写入0x01
#define SET_RESET_REG               0x0B// 芯片ID号
#define CHIP_ID               0x0D#define QMC5883L_SCL_LOW           HAL_GPIO_WritePin(QMC_SCL_GPIO_Port,QMC_SCL_Pin,GPIO_PIN_RESET)
#define QMC5883L_SCL_HIG           HAL_GPIO_WritePin(QMC_SCL_GPIO_Port,QMC_SCL_Pin,GPIO_PIN_SET)
#define QMC5883L_SDA_LOW           HAL_GPIO_WritePin(QMC_SDA_GPIO_Port,QMC_SDA_Pin,GPIO_PIN_RESET)
#define QMC5883L_SDA_HIG           HAL_GPIO_WritePin(QMC_SDA_GPIO_Port,QMC_SDA_Pin,GPIO_PIN_SET)//#define Sim_I2C1_SDA_STATE        (IIC_SDA_GPIO_Port->IDR &= (IIC_SDA_Pin))
#define QMC5883L_SDA_STATE        (QMC_SDA_GPIO_Port->IDR &= (QMC_SDA_Pin))
//#define QMC5883L_SDA_STATE        HAL_GPIO_ReadPin(QMC_SDA_GPIO_Port,QMC_SDA_Pin)#define QMC5883L_DELAY 		QMC5883L_Delay(100000)
#define QMC5883L_NOP		  QMC5883L_Delay(1000)  //25 #define QMC5883L_READY			  0x00
#define QMC5883L_BUS_BUSY		0x01
#define QMC5883L_BUS_ERROR	  0x02#define QMC5883L_NACK	        0x00
#define QMC5883L_ACK				  0x01#define SDA_Pin_Num  1#define WRITE  0x00
#define READ   0x01extern uint16_t rawdata;
extern float degress ;extern int16_t MagnetRawAd[3];  // 磁力计数据void SDA1_IN ( void );
void SDA1_OUT ( void );void QMC5883L_Delay(uint32_t delay);
uint8_t QMC5883L_START(void);
void QMC5883L_STOP(void);
unsigned char QMC5883L_Wait_Ack(void);
void QMC5883L_SendACK(void);
void 	QMC5883L_SendNACK(void);
uint8_t QMC5883L_SendByte(uint8_t Sim_i2c_data);
uint8_t QMC5883L_ReceiveByte(void);
uint8_t QMC5883L_ReceiveByte_WithACK(void);
uint8_t QMC5883L_Read8(uint8_t moni_dev_addr, uint8_t moni_reg_addr, uint8_t moni_i2c_len, uint8_t *moni_i2c_data_buf);
int8_t  QMC5883L_Write8(uint8_t moni_dev_addr, uint8_t moni_reg_addr, uint8_t moni_i2c_len, uint8_t *moni_i2c_data_buf);
uint8_t highByte(uint16_t value);
uint8_t lowByte(uint16_t value);
uint8_t readOneByte(uint8_t in_adr);
uint16_t readTwoBytes(uint8_t in_adr_hi, uint8_t in_adr_lo);
void writeOneByte(uint8_t adr_in, uint8_t dat_in);
int16_t getAddress();void Init_QMC5883();
void GetMagValue(void);#endif 		

  有关QMC5883L芯片会在假期之后更新一篇,讲解IIC通信以及该芯片,后续会补充上链接。
  资源链接:
基于STM32F103C6T6的九轴传感器的工程
STM32F103C6T6模块、MPU6050模块、ICM20602模块等封装库

三、往期回顾

课题学习(一)----静态测量
课题学习(二)----倾角和方位角的动态测量方法(基于磁场的测量系统)
课题学习(三)----倾角和方位角的动态测量方法(基于陀螺仪的测量系统)
课题学习(四)----四元数解法
课题学习(五)----阅读论文《抗差自适应滤波的导向钻具动态姿态测量方法》
课题学习(六)----安装误差校准、实验方法
课题学习(七)----粘滑运动的动态算法
课题学习(八)----卡尔曼滤波动态求解倾角、方位角
课题学习(九)----阅读《导向钻井工具姿态动态测量的自适应滤波方法》论文笔记
课题学习(十)----阅读《基于数据融合的近钻头井眼轨迹参数动态测量方法》论文笔记
课题学习(十一)----阅读《Attitude Determination with Magnetometers and Accelerometers to Use in Satellite》
课题学习(十二)----阅读《Extension of a Two-Step Calibration Methodology to Include Nonorthogonal Sensor Axes》
课题学习(十三)----阅读《Calibration of Strapdown Magnetometers in Magnetic Field Domain》论文笔记
课题学习(十四)----三轴加速度计+三轴陀螺仪传感器-ICM20602
课题学习(十五)----阅读《测斜仪旋转姿态测量信号处理方法》论文
课题学习(十六)----阅读《Continuous Wellbore Surveying While Drilling Utilizing MEMS Gyroscopes Based…》论文
课题学习(十七)----姿态更新的四元数算法总结

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

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

相关文章

【领域驱动设计】模式--通用语言(Ubiquitous language)

一.前言 有道无术术可求&#xff0c;有术无道止于术。方法论的形成都是为了让我们能够更高效&#xff0c;系统的解决问题&#xff0c;而不至于遇到问题不知所措。 二.通用语言的必要性 相信大家在实际的软件开发流程过程中&#xff0c;经常会遇到参照 Prd原型 编码出的系统与实…

SSM驾校预约管理系统----计算机毕业设计

项目介绍 本项目分为管理员、教练、学员三种角色&#xff0c; 管理员角色包含以下功能&#xff1a; 学员管理、教练管理、车辆管理、关系管理、车辆维修管理、个人中心等功能。 教练角色包含以下功能&#xff1a; 我的课程、我的学员、车辆中心、个人中心等功能。 学员角色包…

zabbix添加监控主机(agent)并告警

一、添加监控主机 总体来说&#xff0c;在被监控主机上安装部署zabbix-agent&#xff0c;并修改配置文件&#xff08;zabbix_agentd.conf&#xff09;的参数。然后在zabbix 服务端zabbix-get检查是否可以监控。如果可以了&#xff0c;就可以在web页面添加了&#xff0c;要监控…

Ubuntu16.04 安装Anaconda

步骤 1&#xff1a; 去官网下载安装包,链接如下: https://repo.anaconda.com/archive/ 找到对应版本下载至本地电脑&#xff0c;并上传至服务器。 步骤2: 通过命令解压 sh Anaconda3-2023.03-0-Linux-x86_64.sh 一路选择yes或则回车&#xff0c;直到安装成功出现下面画面&…

Spring高手之路-@Autowired和@Resource注解异同点

目录 相同点 不同点 1.来源不同。 2.包含的属性不同 3.匹配方式&#xff08;装配顺序&#xff09;不同。 ​编辑 4.支持的注入对象类型不同 5.应用地方不同 相同点 都可以实现依赖注入&#xff0c;通过注解将需要的Bean自动注入到目标类中。都可以用于注入任意类型的Bean…

vue如何实现局部刷新?

应用场景&#xff1a; 比如你要切换tap栏实现刷新下面form表单等&#xff0c;相当于刷新页面。 如何使用如下&#xff1a; <div v-if"isReloadData"> 比如你想刷新那个位置就把 v-if"isReloadData"写到那个标签上 </div> 在data中定义刷新标…

如何本地搭建FastDFS文件服务器并实现远程访问【内网穿透】

文章目录 前言1. 本地搭建FastDFS文件系统1.1 环境安装1.2 安装libfastcommon1.3 安装FastDFS1.4 配置Tracker1.5 配置Storage1.6 测试上传下载1.7 与Nginx整合1.8 安装Nginx1.9 配置Nginx 2. 局域网测试访问FastDFS3. 安装cpolar内网穿透4. 配置公网访问地址5. 固定公网地址5.…

基于零和收益的DEA模型研究python实现

传统的DEA模型往往假设相关的是相互独立的,此时DEA模型只能计算出相对效率,无法进行效率的调整。如在碳排放分配问题上,碳排放总量保持不变,利用DEA模型只能计算出每个省份分配的相对效率,这在讨论固定资源下的碳排放配额分配问题时具有明显的局限性。在这种情况下,利用Z…

软件测试/测试开发丨Windows Appium环境搭建

windows 版本 Appium 环境搭建 安装 nodejs 下载.msi文件 https://nodejs.org/en/download/ 注意&#xff1a; 1、下载12.*版本双击安装即可。 2、无须配置环境变量,直接重启一个 cmd 输入下面的命令&#xff0c;能够查看这两个版本号即安装成功。 安装 appium desktop 直…

js对象方法大全(开发必会)

目录 前言 assgin(对象合并) 参数 功能 返回值 测试 结果 结论 create(以源对象为原型创建新对象) 参数 功能 返回值 测试 结果 结论 defineProperties(对属性进行具体定义) 参数 功能 返回值 测试 结果 结论 defineProperty(重写或定义新属性) 参数 功…

无论男孩女孩都要尽情打扮

这款柔软又细腻的开衫外套 上身体验感很不错的哈 舒适软糯百搭还透气&#xff0c;抗起球的面料 黑灰两色简单大方 胸前加上了流行的刺绣设计&#xff0c;可爱又精致 单穿内搭都可&#xff0c;现在天气还比较冷 外面可以套个羽绒服之类的 时尚叠穿风&#xff0c;韩系范儿…

【揭秘】技术同学申请专利的惊人好处,你绝对不能错过!

今天跟大家分享一下&#xff0c;从一名技术工程师&#xff08;程序员&#xff09;的角度&#xff0c;为什么要写专利以及如何去申请专利&#xff1f; 专利的本质 首先就是要科普一下&#xff0c;并不是说一定要做出来的某个东西&#xff0c;才能够申请专利&#xff0c;和想象…

Java线程池ThreadPoolExecutor源码解析

Java线程池ThreadPoolExecutor源码解析 1.ThreadPoolExecutor的构造实现 以jdk8为准&#xff0c;常说线程池有七大参数&#xff0c;通常而言&#xff0c;有四个参数是比较重要的 public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit …

虚拟机迁移技术原理与应用

虚拟机迁移技术主要应用于两种场景&#xff1a; 第一种&#xff0c;随着现在虚拟化的发展&#xff0c;传统it架构的物理机需迁移到虚拟机上&#xff0c;实现负载均衡、资源优化等目的。 第二种&#xff0c;将虚拟机从一个虚拟化平台迁移到另一个虚拟化平台&#xff0c;可以是…

MySQL的高级SQL语句

目录 1.mysql高阶查询 select&#xff1a;显示表格中一个或数个字段的所有数据记录 distinct&#xff1a;不显示重复的数据记录 where&#xff1a;有条件查询 AND OR &#xff1a;且 或 in&#xff1a;显示已知值的数据记录 between&#xff1a;显示两个值范围内的数据记…

nrm的保姆级使用教程

&#x1f4e2; 鸿蒙专栏&#xff1a;想学鸿蒙的&#xff0c;冲 &#x1f4e2; C语言专栏&#xff1a;想学C语言的&#xff0c;冲 &#x1f4e2; VUE专栏&#xff1a;想学VUE的&#xff0c;冲这里 &#x1f4e2; CSS专栏&#xff1a;想学CSS的&#xff0c;冲这里 &#x1f4…

【UE 游戏模板】 游戏分类(RPG、RST等)

目录 0 引言1 游戏分类1.1 角色扮演游戏&#xff08;RPG&#xff09;1.2 第一人称射击游戏&#xff08;FPS&#xff09;1.3 即时策略游戏&#xff08;RTS&#xff09;1.4 VR游戏1.5 集换式卡牌游戏&#xff08;TCG&#xff09;1.5 塔防游戏&#xff08;Tower Defense Games&…

【Web】Ctfshow Thinkphp5 非强制路由RCE漏洞

目录 非强制路由RCE漏洞 web579 web604 web605 web606 web607-610 前面审了一些tp3的sql注入,终于到tp5了&#xff0c;要说tp5那最经典的还得是rce 下面介绍非强制路由RCE漏洞 非强制路由RCE漏洞原理 非强制路由相当于开了一个大口子&#xff0c;可以任意调用当前框…

golang 图片加水印

需求&#xff1a; 1&#xff0c;员工签到图片加水印 2&#xff0c;水印文字需要有半透明的底色&#xff0c;避免水印看不清 3&#xff0c;图片宽设置在600&#xff0c;小于600或者大于600都需要等比例修改图片的高度&#xff0c;保持水印在图片中的大小和位置 4&#xff0c;处理…

GLTF编辑器-位移贴图实现破碎的路面

在线工具推荐&#xff1a; 3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 位移贴图是一种可以用于增加模型细节和形状的贴图。它能够在渲染时针…