M0G3507完美移植江科大软件IIC MPU6050

经过两天两夜的查阅文献资料、整理学习,成功的把江科大的软件IIC读写MPU6050移植到MSPM0G3507,亲测有效!!包的,为了让大家直观地感受下,先上图。记得点个赞哦!

学过江科大的STM32的小伙伴是不是觉得这个画面非常熟悉,在这里我选的是满量程为16g,且陀螺仪水平放置,根据Z轴的读数可以计算出当地的重力加速度值,计算公式为读数(X/2^15)*16,即1963/32768*16=0.96。

思路讲解

1.软硬件型号

选择CCS theia进行M0G3507的开发,显示屏为0.96寸4引脚OLED显示屏,陀螺仪选择常见的MPU6050,GY-521模块。

 2.软件IIC时序模拟

//IIC写SDA引脚
void MyI2C_W_SDA(uint8_t BitValue)
{SDA_OUT();if(BitValue)DL_GPIO_setPins(GPIO_sda_PORT, GPIO_sda_PIN_0_PIN);elseDL_GPIO_clearPins(GPIO_sda_PORT, GPIO_sda_PIN_0_PIN);Delay_us(8);					//延时8us,防止时序频率超过要求
}
//IIC写SCL引脚
void MyI2C_W_SCL(uint8_t BitValue)
{if(BitValue)DL_GPIO_setPins(GPIO_scl_PORT, GPIO_scl_PIN_1_PIN);elseDL_GPIO_clearPins(GPIO_scl_PORT, GPIO_scl_PIN_1_PIN);Delay_us(8);	//延时8us,防止时序频率超过要求
}//IIC开始
void MyI2C_Start(void)
{SDA_OUT();MyI2C_W_SDA(1);				//释放SDA,确保SDA为高电平MyI2C_W_SCL(1);				//释放SCL,确保SCL为高电平MyI2C_W_SDA(0);				//在SCL高电平期间,拉低SDA,产生起始信号MyI2C_W_SCL(0);				//起始后拉低SCL,为了占用总线,方便总线时序的拼接
}

 3.IIC发送一个字节数据

void MyI2C_SendByte(uint8_t Byte)
{SDA_OUT();uint8_t i;for (i = 0; i < 8; i ++)				//循环8次,主机依次发送数据的每一位{MyI2C_W_SDA(Byte & (0x80 >> i));	//使用掩码的方式取出Byte的指定一位数据并写入到SDA线MyI2C_W_SCL(1);						//释放SCL,从机在SCL高电平期间读取SDAMyI2C_W_SCL(0);						//拉低SCL,主机开始发送下一位数据}
}
4.IIC接收一个字节的数据
uint8_t MyI2C_ReceiveByte(void)
{SDA_OUT();uint8_t i, Byte = 0x00;	//定义接收的数据,并赋初值0x00MyI2C_W_SDA(1);			//接收前,主机先确保释放SDA,避免干扰从机的数据发送for (i = 0; i < 8; i ++)	//循环8次,主机依次接收数据的每一位{SDA_IN();MyI2C_W_SCL(1);						//释放SCL,主机机在SCL高电平期间读取SDAif (MyI2C_R_SDA() == 1){Byte |= (0x80 >> i);}	//读取SDA数据,并存储到Byte变量//当SDA为1时,置变量指定位为1,当SDA为0时,不做处理,指定位为默认的初值0MyI2C_W_SCL(0);						//拉低SCL,从机在SCL低电平期间写入SDA}return Byte;							//返回接收到的一个字节数据
}
5.IIC发送应答位
void MyI2C_SendAck(uint8_t AckBit)
{SDA_OUT();MyI2C_W_SDA(AckBit);					//主机把应答位数据放到SDA线MyI2C_W_SCL(1);							//释放SCL,从机在SCL高电平期间,读取应答位MyI2C_W_SCL(0);							//拉低SCL,开始下一个时序模块
}
6.IIC接收应答位
uint8_t MyI2C_ReceiveAck(void)
{SDA_OUT();uint8_t AckBit;							MyI2C_W_SDA(1);			//接收前,主机先确保释放SDA,避免干扰从机的数据发送MyI2C_W_SCL(1);			//释放SCL,主机机在SCL高电平期间读取SDASDA_IN();AckBit = MyI2C_R_SDA();			MyI2C_W_SCL(0);				//拉低SCL,开始下一个时序模块return AckBit;				//返回定义应答位变量
}
7.MPU6050写数据
void MPU6050_WriteReg(uint8_t RegAddress, uint8_t Data)
{MyI2C_Start();						//I2C起始MyI2C_SendByte(MPU6050_ADDRESS);	//发送从机地址(0xD0),读写位为0,表示即将写入MyI2C_ReceiveAck();					//接收应答MyI2C_SendByte(RegAddress);			//发送寄存器地址MyI2C_ReceiveAck();					//接收应答MyI2C_SendByte(Data);				//发送要写入寄存器的数据MyI2C_ReceiveAck();					//接收应答MyI2C_Stop();						//I2C终止
}
8.MPU6050读数据
uint8_t MPU6050_ReadReg(uint8_t RegAddress)
{uint8_t Data;MyI2C_Start();						//I2C起始MyI2C_SendByte(MPU6050_ADDRESS);	//发送从机地址,读写位为0,表示即将写入MyI2C_ReceiveAck();					//接收应答MyI2C_SendByte(RegAddress);			//发送寄存器地址MyI2C_ReceiveAck();					//接收应答MyI2C_Start();						//I2C重复起始MyI2C_SendByte(MPU6050_ADDRESS | 0x01);	//发送从机地址,读写位为1,表示即将读取MyI2C_ReceiveAck();					//接收应答Data = MyI2C_ReceiveByte();			//接收指定寄存器的数据MyI2C_SendAck(1);					//发送应答,给从机非应答,终止从机的数据输出MyI2C_Stop();						//I2C终止return Data;
}
9.myi2c.c
#include "ti_msp_dl_config.h"#include "ti/driverlib/dl_gpio.h"
//打开SDA引脚(输出)
void SDA_OUT(void)   
{DL_GPIO_initDigitalOutput(GPIO_sda_PIN_0_IOMUX);     DL_GPIO_setPins(GPIO_sda_PORT, GPIO_sda_PIN_0_PIN);	   DL_GPIO_enableOutput(GPIO_sda_PORT, GPIO_sda_PIN_0_PIN); 
}
//关闭SDA引脚(输入)
void SDA_IN(void)
{DL_GPIO_initDigitalInputFeatures(GPIO_sda_PIN_0_IOMUX,DL_GPIO_INVERSION_DISABLE, DL_GPIO_RESISTOR_PULL_UP,DL_GPIO_HYSTERESIS_DISABLE, DL_GPIO_WAKEUP_DISABLE);}void Delay_us(uint16_t us)
{while(us--)delay_cycles(CPUCLK_FREQ/1000000);
}//CPUCLK_FREQ为时钟频率,可以根据配置的改变而改变
/*引脚配置层*//*** 函    数:I2C写SCL引脚电平* 参    数:BitValue 协议层传入的当前需要写入SCL的电平,范围0~1* 返 回 值:无* 注意事项:此函数需要用户实现内容,当BitValue为0时,需要置SCL为低电平,当BitValue为1时,需要置SCL为高电平*/
void MyI2C_W_SCL(uint8_t BitValue)
{if(BitValue)DL_GPIO_setPins(GPIO_scl_PORT, GPIO_scl_PIN_1_PIN);elseDL_GPIO_clearPins(GPIO_scl_PORT, GPIO_scl_PIN_1_PIN);Delay_us(8);	//延时8us,防止时序频率超过要求
}/*** 函    数:I2C写SDA引脚电平* 参    数:BitValue 协议层传入的当前需要写入SDA的电平,范围0~0xFF* 返 回 值:无* 注意事项:此函数需要用户实现内容,当BitValue为0时,需要置SDA为低电平,当BitValue非0时,需要置SDA为高电平*/
void MyI2C_W_SDA(uint8_t BitValue)
{SDA_OUT();if(BitValue)DL_GPIO_setPins(GPIO_sda_PORT, GPIO_sda_PIN_0_PIN);elseDL_GPIO_clearPins(GPIO_sda_PORT, GPIO_sda_PIN_0_PIN);Delay_us(8);					//延时8us,防止时序频率超过要求
}/*** 函    数:I2C读SDA引脚电平* 参    数:无* 返 回 值:协议层需要得到的当前SDA的电平,范围0~1* 注意事项:此函数需要用户实现内容,当前SDA为低电平时,返回0,当前SDA为高电平时,返回1*/
uint8_t MyI2C_R_SDA(void)
{uint8_t b;uint32_t BitValue;SDA_IN();BitValue = DL_GPIO_readPins(GPIO_sda_PORT, GPIO_sda_PIN_0_PIN);		//读取SDA电平{if(BitValue)   b=1;else           b=0;}Delay_us(8);		//延时8us,防止时序频率超过要求return b;	        //返回SDA电平
}/*** 函    数:I2C初始化* 参    数:无* 返 回 值:无* 注意事项:此函数需要用户实现内容,实现SCL和SDA引脚的初始化*/
void MyI2C_Init(void)
{SYSCFG_DL_GPIO_init();/*设置默认电平*/DL_GPIO_setPins(GPIOA, GPIO_sda_PIN_0_PIN |GPIO_scl_PIN_1_PIN);//设置PA8和PA9引脚初始化后默认为高电平(释放总线状态)
}/*协议层*//*** 函    数:I2C起始* 参    数:无* 返 回 值:无*/
void MyI2C_Start(void)
{SDA_OUT();MyI2C_W_SDA(1);				//释放SDA,确保SDA为高电平MyI2C_W_SCL(1);				//释放SCL,确保SCL为高电平MyI2C_W_SDA(0);				//在SCL高电平期间,拉低SDA,产生起始信号MyI2C_W_SCL(0);				//起始后拉低SCL,为了占用总线,方便总线时序的拼接
}/*** 函    数:I2C终止* 参    数:无* 返 回 值:无*/
void MyI2C_Stop(void)
{SDA_OUT();MyI2C_W_SDA(0);							//拉低SDA,确保SDA为低电平MyI2C_W_SCL(1);							//释放SCL,使SCL呈现高电平MyI2C_W_SDA(1);							//在SCL高电平期间,释放SDA,产生终止信号
}/*** 函    数:I2C发送一个字节* 参    数:Byte 要发送的一个字节数据,范围:0x00~0xFF* 返 回 值:无*/
void MyI2C_SendByte(uint8_t Byte)
{SDA_OUT();uint8_t i;for (i = 0; i < 8; i ++)				//循环8次,主机依次发送数据的每一位{MyI2C_W_SDA(Byte & (0x80 >> i));	//使用掩码的方式取出Byte的指定一位数据并写入到SDA线MyI2C_W_SCL(1);						//释放SCL,从机在SCL高电平期间读取SDAMyI2C_W_SCL(0);						//拉低SCL,主机开始发送下一位数据}
}/*** 函    数:I2C接收一个字节* 参    数:无* 返 回 值:接收到的一个字节数据,范围:0x00~0xFF*/
uint8_t MyI2C_ReceiveByte(void)
{SDA_OUT();uint8_t i, Byte = 0x00;	//定义接收的数据,并赋初值0x00MyI2C_W_SDA(1);			//接收前,主机先确保释放SDA,避免干扰从机的数据发送for (i = 0; i < 8; i ++)	//循环8次,主机依次接收数据的每一位{SDA_IN();MyI2C_W_SCL(1);						//释放SCL,主机机在SCL高电平期间读取SDAif (MyI2C_R_SDA() == 1){Byte |= (0x80 >> i);}	//读取SDA数据,并存储到Byte变量//当SDA为1时,置变量指定位为1,当SDA为0时,不做处理,指定位为默认的初值0MyI2C_W_SCL(0);						//拉低SCL,从机在SCL低电平期间写入SDA}return Byte;							//返回接收到的一个字节数据
}/*** 函    数:I2C发送应答位* 参    数:Byte 要发送的应答位,范围:0~1,0表示应答,1表示非应答* 返 回 值:无*/
void MyI2C_SendAck(uint8_t AckBit)
{SDA_OUT();MyI2C_W_SDA(AckBit);					//主机把应答位数据放到SDA线MyI2C_W_SCL(1);							//释放SCL,从机在SCL高电平期间,读取应答位MyI2C_W_SCL(0);							//拉低SCL,开始下一个时序模块
}/*** 函    数:I2C接收应答位* 参    数:无* 返 回 值:接收到的应答位,范围:0~1,0表示应答,1表示非应答*/
uint8_t MyI2C_ReceiveAck(void)
{SDA_OUT();uint8_t AckBit;							//定义应答位变量MyI2C_W_SDA(1);							//接收前,主机先确保释放SDA,避免干扰从机的数据发送MyI2C_W_SCL(1);							//释放SCL,主机机在SCL高电平期间读取SDASDA_IN();AckBit = MyI2C_R_SDA();					//将应答位存储到变量里MyI2C_W_SCL(0);							//拉低SCL,开始下一个时序模块return AckBit;							//返回定义应答位变量
}
10.myi2c.h
#ifndef __MYI2C_H
#define __MYI2C_H
#include "stdint.h"void MyI2C_Init(void);
void MyI2C_Start(void);
void MyI2C_Stop(void);
void MyI2C_SendByte(uint8_t Byte);
uint8_t MyI2C_R_SDA(void);
uint8_t MyI2C_ReceiveByte(void);
void MyI2C_SendAck(uint8_t AckBit);
uint8_t MyI2C_ReceiveAck(void);
void MyI2C_W_SCL(uint8_t BitValue);
void MyI2C_W_SDA(uint8_t BitValue);
void Delay_us(uint16_t us);#endif
11.mpu6050.c
#include "ti_msp_dl_config.h"
#include "myi2C.h"
#include "MPU6050_Reg.h"#define MPU6050_ADDRESS		0xD0		//MPU6050的I2C从机地址/*** 函    数:MPU6050写寄存器* 参    数:RegAddress 寄存器地址,范围:参考MPU6050手册的寄存器描述* 参    数:Data 要写入寄存器的数据,范围:0x00~0xFF* 返 回 值:无*/
void MPU6050_WriteReg(uint8_t RegAddress, uint8_t Data)
{MyI2C_Start();						//I2C起始MyI2C_SendByte(MPU6050_ADDRESS);	//发送从机地址,读写位为0,表示即将写入MyI2C_ReceiveAck();					//接收应答MyI2C_SendByte(RegAddress);			//发送寄存器地址MyI2C_ReceiveAck();					//接收应答MyI2C_SendByte(Data);				//发送要写入寄存器的数据MyI2C_ReceiveAck();					//接收应答MyI2C_Stop();						//I2C终止
}/*** 函    数:MPU6050读寄存器* 参    数:RegAddress 寄存器地址,范围:参考MPU6050手册的寄存器描述* 返 回 值:读取寄存器的数据,范围:0x00~0xFF*/
uint8_t MPU6050_ReadReg(uint8_t RegAddress)
{uint8_t Data;MyI2C_Start();						//I2C起始MyI2C_SendByte(MPU6050_ADDRESS);	//发送从机地址,读写位为0,表示即将写入MyI2C_ReceiveAck();					//接收应答MyI2C_SendByte(RegAddress);			//发送寄存器地址MyI2C_ReceiveAck();					//接收应答MyI2C_Start();						//I2C重复起始MyI2C_SendByte(MPU6050_ADDRESS | 0x01);	//发送从机地址,读写位为1,表示即将读取MyI2C_ReceiveAck();					//接收应答Data = MyI2C_ReceiveByte();			//接收指定寄存器的数据MyI2C_SendAck(1);					//发送应答,给从机非应答,终止从机的数据输出MyI2C_Stop();						//I2C终止return Data;
}/*** 函    数:MPU6050初始化* 参    数:无* 返 回 值:无*/
void MPU6050_Init(void)
{MyI2C_Init();									//先初始化底层的I2C/*MPU6050寄存器初始化,需要对照MPU6050手册的寄存器描述配置,此处仅配置了部分重要的寄存器*/MPU6050_WriteReg(MPU6050_PWR_MGMT_1, 0x01);		//电源管理寄存器1,取消睡眠模式,选择时钟源为X轴陀螺仪MPU6050_WriteReg(MPU6050_PWR_MGMT_2, 0x00);		//电源管理寄存器2,保持默认值0,所有轴均不待机MPU6050_WriteReg(MPU6050_SMPLRT_DIV, 0x09);		//采样率分频寄存器,配置采样率MPU6050_WriteReg(MPU6050_CONFIG, 0x06);			//配置寄存器,配置DLPFMPU6050_WriteReg(MPU6050_GYRO_CONFIG, 0x18);	//陀螺仪配置寄存器,选择满量程为±2000°/sMPU6050_WriteReg(MPU6050_ACCEL_CONFIG, 0x18);	//加速度计配置寄存器,选择满量程为±16g
}/*** 函    数:MPU6050获取ID号* 参    数:无* 返 回 值:MPU6050的ID号*/
uint8_t MPU6050_GetID(void)
{return MPU6050_ReadReg(MPU6050_WHO_AM_I);		//返回WHO_AM_I寄存器的值
}/*** 函    数:MPU6050获取数据* 参    数:AccX AccY AccZ 加速度计X、Y、Z轴的数据,使用输出参数的形式返回,范围:-32768~32767* 参    数:GyroX GyroY GyroZ 陀螺仪X、Y、Z轴的数据,使用输出参数的形式返回,范围:-32768~32767* 返 回 值:无*/
void MPU6050_GetData(int16_t *AccX, int16_t *AccY, int16_t *AccZ, int16_t *GyroX, int16_t *GyroY, int16_t *GyroZ)
{uint8_t DataH, DataL;								//定义数据高8位和低8位的变量DataH = MPU6050_ReadReg(MPU6050_ACCEL_XOUT_H);		//读取加速度计X轴的高8位数据DataL = MPU6050_ReadReg(MPU6050_ACCEL_XOUT_L);		//读取加速度计X轴的低8位数据*AccX = (DataH << 8) | DataL;						//数据拼接,通过输出参数返回DataH = MPU6050_ReadReg(MPU6050_ACCEL_YOUT_H);		//读取加速度计Y轴的高8位数据DataL = MPU6050_ReadReg(MPU6050_ACCEL_YOUT_L);		//读取加速度计Y轴的低8位数据*AccY = (DataH << 8) | DataL;						//数据拼接,通过输出参数返回DataH = MPU6050_ReadReg(MPU6050_ACCEL_ZOUT_H);		//读取加速度计Z轴的高8位数据DataL = MPU6050_ReadReg(MPU6050_ACCEL_ZOUT_L);		//读取加速度计Z轴的低8位数据*AccZ = (DataH << 8) | DataL;						//数据拼接,通过输出参数返回DataH = MPU6050_ReadReg(MPU6050_GYRO_XOUT_H);		//读取陀螺仪X轴的高8位数据DataL = MPU6050_ReadReg(MPU6050_GYRO_XOUT_L);		//读取陀螺仪X轴的低8位数据*GyroX = (DataH << 8) | DataL;						//数据拼接,通过输出参数返回DataH = MPU6050_ReadReg(MPU6050_GYRO_YOUT_H);		//读取陀螺仪Y轴的高8位数据DataL = MPU6050_ReadReg(MPU6050_GYRO_YOUT_L);		//读取陀螺仪Y轴的低8位数据*GyroY = (DataH << 8) | DataL;						//数据拼接,通过输出参数返回DataH = MPU6050_ReadReg(MPU6050_GYRO_ZOUT_H);		//读取陀螺仪Z轴的高8位数据DataL = MPU6050_ReadReg(MPU6050_GYRO_ZOUT_L);		//读取陀螺仪Z轴的低8位数据*GyroZ = (DataH << 8) | DataL;						//数据拼接,通过输出参数返回
}
12.mpu6050.h
#ifndef __MPU6050_H
#define __MPU6050_H
#include "myi2C.h"
void MPU6050_WriteReg(uint8_t RegAddress, uint8_t Data);
uint8_t MPU6050_ReadReg(uint8_t RegAddress);void MPU6050_Init(void);
uint8_t MPU6050_GetID(void);
void MPU6050_GetData(int16_t *AccX, int16_t *AccY, int16_t *AccZ, int16_t *GyroX, int16_t *GyroY, int16_t *GyroZ);#endif
13.mpu6050_Reg.h
#ifndef __MPU6050_REG_H
#define __MPU6050_REG_H#define	MPU6050_SMPLRT_DIV		0x19
#define	MPU6050_CONFIG			0x1A
#define	MPU6050_GYRO_CONFIG		0x1B
#define	MPU6050_ACCEL_CONFIG	0x1C#define	MPU6050_ACCEL_XOUT_H	0x3B
#define	MPU6050_ACCEL_XOUT_L	0x3C
#define	MPU6050_ACCEL_YOUT_H	0x3D
#define	MPU6050_ACCEL_YOUT_L	0x3E
#define	MPU6050_ACCEL_ZOUT_H	0x3F
#define	MPU6050_ACCEL_ZOUT_L	0x40
#define	MPU6050_TEMP_OUT_H		0x41
#define	MPU6050_TEMP_OUT_L		0x42
#define	MPU6050_GYRO_XOUT_H		0x43
#define	MPU6050_GYRO_XOUT_L		0x44
#define	MPU6050_GYRO_YOUT_H		0x45
#define	MPU6050_GYRO_YOUT_L		0x46
#define	MPU6050_GYRO_ZOUT_H		0x47
#define	MPU6050_GYRO_ZOUT_L		0x48#define	MPU6050_PWR_MGMT_1		0x6B
#define	MPU6050_PWR_MGMT_2		0x6C
#define	MPU6050_WHO_AM_I		0x75#endif
14.main.c
#include "ti_msp_dl_config.h"
#include "oled.h"
#include "mpu6050.h"
#include "ti/driverlib/dl_gpio.h"
int16_t AX,AY,AZ,GX,GY,GZ;
int main(void)
{SYSCFG_DL_init();OLED_Init();OLED_CLS();MPU6050_Init();//MPU6050_WriteReg(0x19,0x00);while (1){MPU6050_GetData(&AX,&AY,&AZ,&GX,&GY,&GZ);OLED_ShowString(2,1,"AX:");OLED_ShowSignedNum(2,4,AX,4);OLED_ShowString(3,1,"AY:");OLED_ShowSignedNum(3,4,AY,4);OLED_ShowString(4,1,"AZ:");OLED_ShowSignedNum(4,4,AZ,4);OLED_ShowString(2,9,"GX:");OLED_ShowSignedNum(2,12,AX,4);OLED_ShowString(3,9,"GY:");OLED_ShowSignedNum(3,12,GY,4);OLED_ShowString(4,9,"GZ:");OLED_ShowSignedNum(4,12,GZ,4);}
}
15.总结

        在syscfg中配置好MPU6050的SDA和SCL引脚,通过软件模拟IIC时序,对MPU6050进行读写操作。作为嵌入式的小伙伴们,都知道MPU6050的重要性,它可以用于飞行控制和姿态稳定,提供的角速度和加速度数据对于无人机的稳定飞行至关重要,能够帮助无人机实现精确的姿态调整和位置控制,在智能小车中,MPU6050可用于检测机器人的姿态和运动状态,帮助机器人实现自主导航和避障。

        现在比较成功的案例是嘉立创的1306系列的开发板,但是讲解资料少,羞涩难懂,小编这个成功地将江科大讲解的MPU6050移植到M0G3507,视频讲解细致,函数形式和参数通俗易懂,包会的!!需要完整的MPU6050代码可以留言哦,然后可以搭配自己的OLED进行结果的展示,这是小编花了两天多的时间才成功移植,成功地读取到了陀螺仪的六轴数据,接下来就可以进行姿态解算继续完成M0G3507的项目啦!

MPU6050引脚M0G3507引脚
GNDGND
SCLPA9
SDAPA8
VCCVCC

参考资料:STM32入门教程-2023版 细致讲解 中文字幕_哔哩哔哩_bilibili

百度网盘,无需密码,配合自己的OLED

完整ccs theia工程

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

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

相关文章

CI/CD与DevOps流程流程简述(提供思路)

一 CI/CD流程详解&#xff1a;代码集成、测试与发布部署 引言 在软件开发的世界里&#xff0c;CI/CD&#xff08;持续集成/持续交付&#xff09;就像是一套精密的流水线&#xff0c;确保代码从开发到上线的整个过程高效、稳定。我作为一名资深的软件工程师&#xff0c;接下来…

大数据基础——Ubuntu 安装

文章目录 Ubuntu 安装一、配置电脑二、安装系统 Ubuntu 安装 一、配置电脑 1、进入VMware 2、选择配置类型 3、选择硬件兼容性版本 4、当前虚拟机的操作系统 选择“稍后安装操作系统”&#xff08;修改&#xff09; 5、选择虚拟机将来需要安装的系统 选中“Linux”和选择…

LeetCode百题刷003(449周赛一二题)

遇到的问题都有解决的方案&#xff0c;希望我的博客可以为你提供一些帮助 一、不同字符数量最多为 K 时的最少删除数 &#xff08;哈希表空间换时间&#xff09; 不同字符数量最多为 K 时的最少删除数 - 力扣 (LeetCode) 竞赛https://leetcode.cn/contest/weekly-contest-449/…

【网安等保】OpenEuler 24.03系统主机安全加固及配置优化实践指南

[ 知识是人生的灯塔&#xff0c;只有不断学习&#xff0c;才能照亮前行的道路 ] &#x1f4e2; 大家好&#xff0c;我是 WeiyiGeek&#xff0c;一个正在向全栈工程师(SecDevOps)前进的计算机技术爱好者&#xff0c;欢迎各位道友一起学习交流、一起进步 &#x1f680;&#xff0…

大模型赋能:2D 写实数字人开启实时交互新时代

在数字化浪潮席卷全球的当下&#xff0c;人工智能技术不断突破创新&#xff0c;其中大模型驱动的 2D 写实数字人正成为实时交互领域的一颗新星&#xff0c;引领着行业变革&#xff0c;为人们带来前所未有的交互体验。 一、2D 写实数字人概述 2D 写实数字人是通过计算机图形学…

Dockers部署oscarfonts/geoserver镜像的Geoserver

Dockers部署oscarfonts/geoserver镜像的Geoserver 说实话&#xff0c;最后发现要选择合适的Geoserver镜像才是关键&#xff0c;所以所以所以…&#x1f437; 推荐oscarfonts/geoserver的镜像&#xff01; 一开始用kartoza/geoserver镜像一直提示内存不足&#xff0c;不过还好…

关于解决MySQL的常见问题

一&#xff1a;MySQL输入密码时闪退 这有可能是因为MySQL服务没有开启。 打开系统配置&#xff08;直接搜索即可&#xff09;&#xff0c;查看MySQL服务是否开启。 此时显示的是已停止。确定是这个问题。 现在打开计算机管理&#xff08;直接搜索即可&#xff09;。 找到MyS…

LeetCode 热题 100 101. 对称二叉树

LeetCode 热题 100 | 101. 对称二叉树 大家好&#xff0c;今天我们来解决一道经典的二叉树问题——对称二叉树。这道题在 LeetCode 上被标记为简单难度&#xff0c;要求检查给定的二叉树是否轴对称。 问题描述 给你一个二叉树的根节点 root&#xff0c;检查它是否轴对称。 示…

图形化编程革命:iVX携手AI 原生开发范式

一、技术核心&#xff1a;图形化编程的底层架构解析 1. 图形化开发的效率优势&#xff1a;代码量减少 72% 的秘密 传统文本编程存在显著的信息密度瓶颈。以 "按钮点击→条件判断→调用接口→弹窗反馈" 流程为例&#xff0c;Python 实现需定义函数、处理缩进并编写 …

uniapp跨平台开发HarmonyOS NEXT应用初体验

之前写过使用uniapp开发鸿蒙应用的教程&#xff0c;简单介绍了如何配置开发环境和运行项目。那时候的HbuilderX还是4.22版本&#xff0c;小一年过去了HbuilderX的正式版本已经来到4.64&#xff0c;历经了多个版本的更新后&#xff0c;跨平台开发鸿蒙应用的体验大幅提升。今天再…

windows怎么修改DNS

好的&#xff0c;在 Windows 操作系统中修改 DNS 设置有几种方法&#xff0c;最常用的是通过“网络和 Internet 设置”。以下是详细步骤&#xff1a; 方法一&#xff1a;通过设置应用修改 DNS (适用于 Windows 10/11) 打开设置&#xff1a; 点击屏幕左下角的 Windows 开始按钮…

Java基本数据类型缓存池解析-源码剖析

抛出问题&#xff1a;new Integer(18) 与 Integer.valueOf(18) 的区别是什么&#xff1f; new Integer(18) 每次都会新建一个对象;Integer.valueOf(18) 会使⽤用缓存池中的对象&#xff0c;多次调用只会取同⼀一个对象的引用 Integer x new Integer(18); Integer y new Int…

WORD压缩两个免费方法

日常办公和学习中&#xff0c;Word文档常常因为包含大量图片、图表或复杂格式而导致文件体积过大&#xff0c;带来诸多不便&#xff0c;比如 邮件发送受限&#xff1a;许多邮箱附件限制在10-25MB&#xff0c;大文件无法直接发送 存储空间占用&#xff1a;大量文档占用硬盘或云…

罗技无线鼠标的配对方法

罗技鼠标的配对方法&#xff1a; 重新连接鼠标 请按照以下步骤将鼠标与 USB 接收器重新配对。 1.将USB接收器插入计算机。 2.将鼠标关闭电源。 3.按住并持续按住向右按钮&#xff0c;直到操作结束。 4.切换鼠标电源。 5. 单击一次左侧按钮。 6. 单击一次中间按钮。 7.全部松开&…

四、Hadoop 2.X vs 3.X:特性、架构与性能全解析

Hadoop 2.X 与 Hadoop 3.X 深度对比&#xff1a;版本特性、架构与性能剖析 在大数据处理的浪潮中&#xff0c;Hadoop 凭借其分布式存储与计算的强大能力&#xff0c;成为了业界的核心框架之一。随着技术的不断演进&#xff0c;Hadoop 也经历了多个重要版本的迭代。其中&#x…

【React中useReducer钩子详解】

useReducer 是 React 中用于管理复杂状态逻辑的 Hook&#xff0c;它通过 集中式状态更新逻辑 替代 useState&#xff0c;尤其适合处理多值关联状态或依赖前序状态更新的场景。以下是其核心要点&#xff1a; 1. 核心概念 Reducer 模式&#xff1a;灵感来自 JavaScript 的 Array…

【C++】C++函数指针详解与实用技巧

C函数指针详解与实用技巧 在C中&#xff0c;**函数指针&#xff08;Function Pointer&#xff09;**是一种强大而灵活的工具&#xff0c;常用于回调机制、策略模式、事件处理等场景。本文将从概念、语法、常见用法到实战示例&#xff0c;带你全面掌握C函数指针。 &#x1f9e0…

【计算机视觉】基于深度学习的实时情绪检测系统:emotion-detection项目深度解析

基于深度学习的实时情绪检测系统&#xff1a;emotion-detection项目深度解析 1. 项目概述2. 技术原理与模型架构2.1 核心算法1) 数据预处理流程2) 改进型MobileNetV2 2.2 系统架构 3. 实战部署指南3.1 环境配置3.2 数据集准备3.3 模型训练3.4 实时推理 4. 常见问题与解决方案4.…

IC ATE集成电路测试学习——电流测试的原理和方法

电流测试 我们可以通过电流来判断芯片的工作状态时&#xff0c;首先先了解下芯片的电流是如何产生的。 静态电流 理论上&#xff0c;CMOS结构的芯片静态时几乎不耗电 CMOS基本结构&#xff1a;Pmos Nmos 串联当逻辑电平稳定时&#xff1a; ➜ 要么Pmos导通&#xff0c;Nmo…

stm32week15

stm32学习 十一.中断 2.NVIC Nested vectored interrupt controller&#xff0c;嵌套向量中断控制器&#xff0c;属于内核(M3/4/7) 中断向量表&#xff1a;定义一块固定的内存&#xff0c;以4字节对齐&#xff0c;存放各个中断服务函数程序的首地址&#xff0c;中断向量表定…