stm32入门学习11-硬件I2C和MPU

news2024/12/24 3:21:08

(一)I2C硬件电路

stm32内部有I2C的硬件电路,我们可以使用stm32的标准库函数来实现I2C,这可以为我们减少对软件资源的占用

I2C硬件电路常用的标准库函数

void I2C_Init(I2C_TypeDef* I2Cx, I2C_InitTypeDef* I2C_InitStruct);
//通过结构体初始化I2C

void I2C_StructInit(I2C_InitTypeDef* I2C_InitStruct);
//给初始化结构体赋默认值

void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
//使能I2C,初始化之后要使能其才开始工作

void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState);
//开始I2C传输

void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState);
//结束I2C传输

void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data);
//发送一个字节数据

uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx);
//接收一个字节数据

void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction);
//发送7位地址,在最开始I2C寻址调用这个函数

ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT);
//接收事件,在使用硬件开始传输或发送数据等操作之后都会有对应的事件需要接收判断后再执行下一个操作

void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState);
//设置响应为,相当于软件实现I2C中的ack

我们只要使用这些库函数,按照其规定的流程进行数据的发送和接收即可,不需要我们手动在软件中模拟I2C的高低电平跳变

(二)使用库函数实现I2C数据的发送与接收

(1)发送

I2C发送流程如图,在开始传输完成后,其会产生EV5事件,我们在事件产生后即可发送地址位,成功发送后会产生EV6事件,接着发送寄存器地址,因为这里使用的是一个寄存器和一个移位寄存器来发送数据,所以我们在寄存器的数据写入到移位寄存器中正在发送(EV8事件)即可将新的数据写入寄存器,在最后一个数据位我们没有数据写入寄存器,且移位寄存器发送完毕,会产生EV8_2事件,表示发送完成,然后即可停止传输

这里我们发送一个字节后的接收响应由硬件自动接收,不需要我们手动接收响应

由于我们会频繁接收各种事件,我们可以把接收事件的函数封装成一个简单的函数,且让其超时退出,不让程序卡死

接收事件函数

void mpu_wait_flag(int event)
{
	unsigned int time = 10000;
	while (I2C_CheckEvent(I2C2, event) != SUCCESS)
	{
		time--;
		if (time == 0)
		{
			break;
		}
	}
}

按照流程,我们可以这样编写发送函数

发送函数

void mpu_write(unsigned char address, unsigned char inf)
{
	I2C_GenerateSTART(I2C2, ENABLE);
	mpu_wait_flag(I2C_EVENT_MASTER_MODE_SELECT);	//EV5
	I2C_Send7bitAddress(I2C2, mpu_address, I2C_Direction_Transmitter);
	mpu_wait_flag(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED);	//EV6
	I2C_SendData(I2C2, address);
	mpu_wait_flag(I2C_EVENT_MASTER_BYTE_TRANSMITTING);	//EV8
	I2C_SendData(I2C2, inf);
	mpu_wait_flag(I2C_EVENT_MASTER_BYTE_TRANSMITTED);	//EV8_2
	I2C_GenerateSTOP(I2C2, ENABLE);
}

第一行我们先开始传输,第二行我们接收EV5事件,第三行我们发送7位地址,并且第三个参数为读模式还是写模式,我们选择写模式,第四行我们等待EV6事件,紧接着第五行发送要读取的寄存器地址,第六行等待寄存器地址移动到移位寄存器正在发送事件(EV8),最后第七行写要发送的数据,等待发送完成事件,最后停止传输;

(2)接收

接收数据的流程如图所示

这里一样,我们在开始之后会产生EV5事件,在传递MPU地址后会产生EV6事件,接着读取数据,这里由于我们在读取事件之后硬件电路会立刻把我们之前预设的ack响应发给从机,因此我们需要在读取最后一个数据之前把ack置0,我们这里只读取一个字节的数据,也就是要在发送MPU地址之后,读取数据之前先把ack置0,对应代码如下

unsigned char mpu_read(unsigned char address)
{
	unsigned char inf;
	I2C_GenerateSTART(I2C2, ENABLE);
	mpu_wait_flag(I2C_EVENT_MASTER_BYTE_TRANSMITTED);
	I2C_Send7bitAddress(I2C2, mpu_address, I2C_Direction_Transmitter);
	mpu_wait_flag(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED);
	I2C_SendData(I2C2, address);
	mpu_wait_flag(I2C_EVENT_MASTER_BYTE_TRANSMITTED);
	
	I2C_GenerateSTART(I2C2, ENABLE);
	mpu_wait_flag(I2C_EVENT_MASTER_MODE_SELECT);
	I2C_Send7bitAddress(I2C2, mpu_address, I2C_Direction_Receiver);
	mpu_wait_flag(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED);
	
	I2C_AcknowledgeConfig(I2C2, DISABLE);    //ack=0
	
	mpu_wait_flag(I2C_EVENT_MASTER_BYTE_RECEIVED);
	inf = I2C_ReceiveData(I2C2);
	
	I2C_GenerateSTOP(I2C2, ENABLE);
	
	I2C_AcknowledgeConfig(I2C2, ENABLE);
	return inf;
}

第一段对应我们软件I2C的给寄存器地址操作,我们仍需要先写入寄存器地址,然后在第二段我们重新开始传输,接收EV5事件后发送MPU地址,这里第三个参数选择读模式,等待地址发送完成,之后值得注意的是我们先执行的不是读取数据,而是先把应答位置非应答,再去读取数据,读取完成后我们即可停止传输

(三)MPU-6050

经过上面两个函数的编写,我们已经可以调用上面两个函数来实现在指定外设寄存器上写数据和读数据的操作,我们即可进行MPU的初始化和读取转换数据所在的寄存器,这里就和之前使用软件模拟I2C的代码没有什么区别,因为软件我们只是模拟了I2C的波形,最终也封装成了写字节和读字节的函数

(1)初始化

(1)打开时钟和初始化GPIO

这里因为我们使用内部的I2C硬件电路,因此我们打开时钟我们要把I2C的时钟打开,stm32F03C8有两个I2C,这里使用的是I2C2,对应的SCL、SDA引脚为PB10、PB11

void mpu_rcc_init()
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
}

初始化GPIO,这里要用复用开漏输出

void mpu_gpio_init()
{
	GPIO_InitTypeDef gpio_init;
	gpio_init.GPIO_Pin = SCL | SDA;
	gpio_init.GPIO_Mode = GPIO_Mode_AF_OD;
	gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &gpio_init);
}

(2)I2C初始化

使用I2C硬件电路还要对I2C进行初始化,可以看下初始化结构体

(1)第一个参数是选择时钟速度,数值越大电平翻转频率越高,低于100KHz的是正常模式,高于100KHz的是高速模式,这里选择100KHz;

(2)第二个参数是选择模式,可以选泽I2C模式、SMBus设备模式或SMBus主控模式,这里选择I2C模式;

(3)第三个参数是选择高低电平的占空比,这里只有在高速模式下有效,有16:9和2:1两种可选,这里不是高速模式,可以随便选择;

(4)第四个参数是选择自身地址,自身可以作为从机,设置自身地址让其他主机呼叫,随便选择,只要不和MPU或其他I2C上的地址冲突即可;

(5)第五个参数是应答位设置,可以选择应答和非应答,给应答;

(6)第六个参数是选择7位地址模式还是10位地址模式,这里选择7为地址模式;

这样我们就可以初始化I2C了

void mpu_i2c_init()
{
	I2C_InitTypeDef i2c_init;
	i2c_init.I2C_ClockSpeed = 100000;
    i2c_init.I2C_Mode = I2C_Mode_I2C;
    i2c_init.I2C_DutyCycle = I2C_DutyCycle_2;
    i2c_init.I2C_OwnAddress1 = 0x00;
    i2c_init.I2C_Ack = I2C_Ack_Enable;
    i2c_init.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
	I2C_Init(I2C2, &i2c_init);
	
	I2C_Cmd(I2C2, ENABLE);
}

最后不要忘了使能I2C,否则其不工作

(3)MPU初始化

我们把时钟、gpio、I2C的初始化都集成于此,我们还要像软件那样配置寄存器来关闭MPU睡眠模式和选择时钟等功能,具体代码如下

void mpu_init()
{
	mpu_rcc_init();
	mpu_gpio_init();
	mpu_i2c_init();
	
	mpu_write(0x6B, 0x01);	//PWR_MGMT_1 -> 0000 0001
	mpu_write(0x6C, 0x00);	//PWR_MGMT_2 -> 0000 0000}
	mpu_write(0x19, 0x09);	//SMPLRT_DIV -> 0000 1001
	mpu_write(0x1A, 0x06);	//CONFIG -> 0000 0110
	mpu_write(0x1B, 0x18);	//GYRO_CONFIG -> 0001 1000
	mpu_write(0x1C, 0x18);	//ACCEL_CONFIG -> 0001 1000
}

(2)读取参数

最后我们选择将x轴、y轴和z轴的加速度和角速度放在一个结构体中返回,我们还要注意16位整数转为32位整数中的符号问题

结构体定义

typedef struct infs
{
	int x_acceleration;
	int y_acceleration;
	int z_acceleration;
	
	int x_angular_velocity;
	int y_angular_velocity;
	int z_angular_velocity;
} information;

16位整数转32为整数

int mpu_16_to_32(int original)
{
	int final;
	if (original & 0x8000)
	{
		final = original | 0xFFFF0000;
	}
	return final;
}

我们只要读取MPU对应数据的寄存器即可,这里和软件模拟的操作一样

information mpu_get_inf()
{
	uint8_t inf_L;
	uint8_t inf_H;
	information infor;
	inf_H = mpu_read(0x3B);
	inf_L = mpu_read(0x3C);
	infor.x_acceleration = mpu_16_to_32((inf_H<<8) | inf_L);
	inf_H = mpu_read(0x3D);
	inf_L = mpu_read(0x3E);
	infor.y_acceleration = mpu_16_to_32((inf_H<<8) | inf_L);
	inf_H = mpu_read(0x3F);
	inf_L = mpu_read(0x40);
	infor.z_acceleration = mpu_16_to_32((inf_H<<8) | inf_L);
	
	inf_H = mpu_read(0x43);
	inf_L = mpu_read(0x44);
	infor.x_angular_velocity = mpu_16_to_32((inf_H<<8) | inf_L);
	inf_H = mpu_read(0x45);               
	inf_L = mpu_read(0x46);               
	infor.y_angular_velocity = mpu_16_to_32((inf_H<<8) | inf_L);
	inf_H = mpu_read(0x47);               
	inf_L = mpu_read(0x48);               
	infor.z_angular_velocity = mpu_16_to_32((inf_H<<8) | inf_L);
	
	return infor;
}

(3)封装与声明

最后的.c 和 .h文件如下

#include "stm32f10x.h"                  // Device header

#define SCL GPIO_Pin_10
#define SDA GPIO_Pin_11

#define mpu_address 0xD0

void mpu_wait_flag(int event)
{
	unsigned int time = 10000;
	while (I2C_CheckEvent(I2C2, event) != SUCCESS)
	{
		time--;
		if (time == 0)
		{
			break;
		}
	}
}

void mpu_write(unsigned char address, unsigned char inf)
{
	I2C_GenerateSTART(I2C2, ENABLE);
	mpu_wait_flag(I2C_EVENT_MASTER_MODE_SELECT);	//EV5
	I2C_Send7bitAddress(I2C2, mpu_address, I2C_Direction_Transmitter);
	mpu_wait_flag(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED);	//EV6
	I2C_SendData(I2C2, address);
	mpu_wait_flag(I2C_EVENT_MASTER_BYTE_TRANSMITTING);	//EV8
	I2C_SendData(I2C2, inf);
	mpu_wait_flag(I2C_EVENT_MASTER_BYTE_TRANSMITTED);	//EV8_2
	I2C_GenerateSTOP(I2C2, ENABLE);
}

unsigned char mpu_read(unsigned char address)
{
	unsigned char inf;
	I2C_GenerateSTART(I2C2, ENABLE);
	mpu_wait_flag(I2C_EVENT_MASTER_BYTE_TRANSMITTED);
	I2C_Send7bitAddress(I2C2, mpu_address, I2C_Direction_Transmitter);
	mpu_wait_flag(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED);
	I2C_SendData(I2C2, address);
	mpu_wait_flag(I2C_EVENT_MASTER_BYTE_TRANSMITTED);
	
	I2C_GenerateSTART(I2C2, ENABLE);
	mpu_wait_flag(I2C_EVENT_MASTER_MODE_SELECT);
	I2C_Send7bitAddress(I2C2, mpu_address, I2C_Direction_Receiver);
	mpu_wait_flag(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED);
	
	I2C_AcknowledgeConfig(I2C2, DISABLE);
	
	mpu_wait_flag(I2C_EVENT_MASTER_BYTE_RECEIVED);
	inf = I2C_ReceiveData(I2C2);
	
	I2C_GenerateSTOP(I2C2, ENABLE);
	
	I2C_AcknowledgeConfig(I2C2, ENABLE);
	return inf;
}

void mpu_rcc_init()
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
}

void mpu_gpio_init()
{
	GPIO_InitTypeDef gpio_init;
	gpio_init.GPIO_Pin = SCL | SDA;
	gpio_init.GPIO_Mode = GPIO_Mode_AF_OD;
	gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &gpio_init);
}

void mpu_i2c_init()
{
	I2C_InitTypeDef i2c_init;
	i2c_init.I2C_ClockSpeed = 100000;
    i2c_init.I2C_Mode = I2C_Mode_I2C;
    i2c_init.I2C_DutyCycle = I2C_DutyCycle_2;
    i2c_init.I2C_OwnAddress1 = 0x00;
    i2c_init.I2C_Ack = I2C_Ack_Enable;
    i2c_init.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
	I2C_Init(I2C2, &i2c_init);
	
	I2C_Cmd(I2C2, ENABLE);
}

void mpu_init()
{
	mpu_rcc_init();
	mpu_gpio_init();
	mpu_i2c_init();
	
	mpu_write(0x6B, 0x01);	//PWR_MGMT_1 -> 0000 0001
	mpu_write(0x6C, 0x00);	//PWR_MGMT_2 -> 0000 0000}
	mpu_write(0x19, 0x09);	//SMPLRT_DIV -> 0000 1001
	mpu_write(0x1A, 0x06);	//CONFIG -> 0000 0110
	mpu_write(0x1B, 0x18);	//GYRO_CONFIG -> 0001 1000
	mpu_write(0x1C, 0x18);	//ACCEL_CONFIG -> 0001 1000
}

typedef struct infs
{
	int x_acceleration;
	int y_acceleration;
	int z_acceleration;
	
	int x_angular_velocity;
	int y_angular_velocity;
	int z_angular_velocity;
} information;

int mpu_16_to_32(int original)
{
	int final;
	if (original & 0x8000)
	{
		final = original | 0xFFFF0000;
	}
	return final;
}

information mpu_get_inf()
{
	uint8_t inf_L;
	uint8_t inf_H;
	information infor;
	inf_H = mpu_read(0x3B);
	inf_L = mpu_read(0x3C);
	infor.x_acceleration = mpu_16_to_32((inf_H<<8) | inf_L);
	inf_H = mpu_read(0x3D);
	inf_L = mpu_read(0x3E);
	infor.y_acceleration = mpu_16_to_32((inf_H<<8) | inf_L);
	inf_H = mpu_read(0x3F);
	inf_L = mpu_read(0x40);
	infor.z_acceleration = mpu_16_to_32((inf_H<<8) | inf_L);
	
	inf_H = mpu_read(0x43);
	inf_L = mpu_read(0x44);
	infor.x_angular_velocity = mpu_16_to_32((inf_H<<8) | inf_L);
	inf_H = mpu_read(0x45);               
	inf_L = mpu_read(0x46);               
	infor.y_angular_velocity = mpu_16_to_32((inf_H<<8) | inf_L);
	inf_H = mpu_read(0x47);               
	inf_L = mpu_read(0x48);               
	infor.z_angular_velocity = mpu_16_to_32((inf_H<<8) | inf_L);
	
	return infor;
}
#ifndef __MPU_H__
#define __MPU_H__

typedef struct infs
{
	int x_acceleration;
	int y_acceleration;
	int z_acceleration;
	
	int x_angular_velocity;
	int y_angular_velocity;
	int z_angular_velocity;
} information;

void mpu_init(void);
information mpu_get_inf(void);

#endif

(四)主函数调用

我们只要在主函数开始时对MPU初始化,然后在循环中调用读取寄存器值的函数即可,和软件模拟实现的程序一样

#include "stm32f10x.h"                  // Device header
#include "OLED.h"
#include "MPU.h"
#include "Delay.h"
int main()
{
	mpu_init();
	OLED_Init();
	information inf;
	while(1)
	{
		inf = mpu_get_inf();
		OLED_ShowSignedNum(1, 1, inf.x_acceleration, 5);
		OLED_ShowSignedNum(2, 1, inf.y_acceleration, 5);
		OLED_ShowSignedNum(3, 1, inf.z_acceleration, 5);
		
		OLED_ShowSignedNum(1, 8, inf.x_acceleration, 5);
		OLED_ShowSignedNum(2, 8, inf.y_acceleration, 5);
		OLED_ShowSignedNum(3, 8, inf.z_acceleration, 5);
		
		Delay_ms(500);
	}
	return 0;
}

(五)总结

在学习软件模拟I2C后,这里学习的是通过硬件I2C,通过库函数来实现I2C通信,读取MPU寄存器中的数据,我们对I2C的理解更加深入,对stm32的了解也更加具体

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

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

相关文章

萤石开放平台 P套餐和E套餐的切换方法

本文将详述P套餐和E套餐的切换方法 注&#xff1a;套餐切换成功后立即生效&#xff0c;次日开始扣费&#xff0c;企业版套餐按日计消耗扣费&#xff0c;第二天计算前一天的费用并在余额扣除对应金额 一&#xff0e; E套餐切换成P套餐 请提工单联系我们&#xff1a; 萤石开放…

centos7.9安装k8s 1.3

centos7.9安装k8s 1.3 k8s环境规划&#xff1a;初始化修改网卡配置两台服务器都执行 配置阿里yum源 安装containerd服务安装初始化k8s需要的软件包kubeadm初始化k8s集群 扩容k8s集群-添加第一个工作节点安装kubernetes网络组件-Calico测试在k8s创建pod是否可以正常访问网络和co…

数据结构(邓俊辉)学习笔记】词典 02—— 散列函数

文章目录 1. 冲突难免2. 何为优劣3. 整除留余4. 以禅为师5. M A D6. 平方取中7. 折叠汇总8. 伪随机数9. 多项式10. Vorldmort 1. 冲突难免 好&#xff0c;接下来的这一节我们就来介绍散列策略中的第一项&#xff0c;也是最重要的技术&#xff0c;散列函数的设计与定制。 在上…

免杀笔记 ---> 函数踩踏 PEB寻址

又鸽了一段时间了&#xff0c;最近在写这个武器&#xff0c;感兴趣的师傅们可以去看看&#xff08;顺便给我点个Star&#xff09; whoami-juruo/InjectTools: 一款集成了DLL-Session0注入&#xff0c;APC注入&#xff0c;映射注入&#xff0c;线程劫持&#xff0c;函数踩踏自提…

电脑开机出现checking media presence原因分析及解决方法

最近有网友反馈电脑开机出现checking media presence&#xff1f;电脑开机出现checking media presence原因有很多&#xff1a;分区类型不对、双硬盘选择的第一启动项不对等等原因&#xff0c;下面小编就教大家电脑开机出现checking media presence详细解决方法。 电脑开机出现…

【ARM】CMSIS 软件标准接口

目录 CMSIS&#xff1a;Cortex Microcontroller Software Interface Standard1. 概述2. CMSIS-Core2.1 概述2.2 关键组件2.3 示例代码2.4 详细解释 3. CMSIS-DSP3.1 概述3.2 关键组件3.3 示例代码3.4 详细解释 4. CMSIS-RTOS4.1 概述4.2 关键组件4.3 示例代码4.4 详细解释 5. C…

java之equals的使用区别

public class SystermDemo3 {public static void main(String[] args) {String s"abc";StringBuilder sbnew StringBuilder("abc");System.out.println(s.equals(sb));//false//equals方法是被s调用的,而s是字符串//所以equals要看String类中//字符串中的e…

大模型笔记5 Extractive QA任务评估

目录 Extractive QA任务评估 Extractive QA评测指标 precision, recall, f1 ROUGE 划分训练与评估数据集 token位置评估 单个token位置评估 输入label的token位置 预测token位置 评估 Wandb 共享机器同时登录 样本类别平衡 标记token label时对窗口进行筛选 训练…

亚马逊日本站认证 硅藻土商品

商品说明和商品照片 硅藻土商品&#xff0c;是指以硅藻土为主要原料而制作的商品。其中&#xff0c;针对浴室脚垫和杯垫等呈板状的商品&#xff0c;因需确认其石棉含有率符合相关安全基准规定&#xff0c;请您提交相关证明资料。 防止石棉损害健康条例以及相关法令 可证明该产…

[算法题]课程表/课程表 II

题目链接: 课程表 课程表 II 通过拓扑排序求解, 首先认识有向无环图: 入度表示有多少点指向自己, 出度表示自己指向多少点, 拓扑排序的思想则为选出入度为 0 的点排, 然后将被选出的点指向的点的入度减 1, 当入度被减到 0 时表示该点可以被选出, 一直循环直到全部点被选出或…

书生大模型实战营-基础关卡-2-8G 显存玩转书生大模型 Demo

Cli Demo 部署 InternLM2-Chat-1.8B 模型 先简单试试 InternLM2-Chat-1.8B 模型的能力 生成 300 字的小故事 我的prompt&#xff1a;写一个300字以内的小故事,故事符合中国特色. 模型输出&#xff1a;故事整体性还是很好的。 在一个小镇上&#xff0c;住着一只名叫小明的猫咪…

基于Dijkstra的校园导游系统

目录 一. 设计目的 二. 设计背景 三. 系统功能 四. 系统算法实现 五. 系统调试与结果分析 六. 完整源代码 一. 设计目的 通过设计并实现校园导游系统&#xff0c;使学生对数据结构有更深入的了解。该系统综合性非常广&#xff0c;能够极大提高学生的设计&#xff0c;编程及…

数据库中的约束,聚合函数以及联合查询

目录 数据库中的约束 not null unique default primary key foreign key 表的设计 聚合函数&#xff08;查询&#xff09; 分组 联表查询&#xff08;多表查询&#xff09; 内连接 外连接 左外连接 右外连接 自连接 子查询 合并查询 数据库中的约束 为了保证…

用python获取系统的硬件信息(python实例二十九)

目录 1.认识Python 2.环境与工具 2.1 python环境 2.2 Visual Studio Code编译 3.获取系统信息 3.1 代码构思 3.2 代码示例 3.3 运行部分结果 4.总结 1.认识Python Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。 Python 的设计具有很强的…

计算机组成原理面试-核心概念-问题理解

目录 1.怎么理解计算机组成原理中存储器、控制器、运算器、输入输出设备之间的协作关系和工作流程 2.比、比特等类似几种表示信息存储的单位具体换算 3.介绍计算机的五大功能-数据传送功能、数据存储功能、数据处理功能、操作控制功能、操作判断功能 4.计算机的工作过程/指令…

【Linux基础】Linux基本指令(一)

目录 前言1&#xff0c; ls指令2&#xff0c;pwd指令三&#xff0c;cd指令3.1 当前目录与上级目录3.2 绝对路径和相对路径3.3 tree指令 四&#xff0c;创建一个普通文件或目录4.1 touch指令4.2 mkdir指令 五&#xff0c;删除目录或文件5.1 rmdir指令5.2 rm 指令 六&#xff0c;…

华大基因阿尔茨海默病风险基因检测,助力阿尔茨海默病早预防

中国正面临日益加剧的老龄化挑战。据统计&#xff0c;2020年我国60岁以上的老年人口已达2.6亿&#xff0c;其中轻度认知障碍患者超过3800万&#xff0c;而阿尔茨海默病患者近千万。随着这一趋势的延续&#xff0c;如何早期发现和预防阿尔茨海默病已成为公共卫生领域的重要议题。…

为什么建议从二维向三维GIS开发方向拓展?

GIS开发是地理信息系统领域中一个薪资待遇较高的职业方向&#xff0c;吸引了众多来自测绘、遥感和城市规划等相关专业的学生转型投身于WebGIS开发工作。 那么&#xff0c;今天从技术角度出发&#xff0c;探讨为何鼓励大家超越WebGIS的范畴&#xff0c;继续深入学习三维GIS开发…

el-date-picker 限制开始时间和结束时间

el-date-picker 限制开始时间和结束时间 需求&#xff1a;el-date-picker 月份限制开始时间和结束时间 开始时间&#xff1a;202307 结束时间&#xff1a;202407 代码实现 vue 页面 <el-form-item label"月份" prop"monthList"><el-date-picker …

零基础5分钟上手亚马逊云科技AWS核心云开发/云架构 - 创建高可用数据库集群

简介&#xff1a; 欢迎来到小李哥全新亚马逊云科技AWS云计算知识学习系列&#xff0c;适用于任何无云计算或者亚马逊云科技技术背景的开发者&#xff0c;让大家零基础5分钟通过这篇文章就能完全学会亚马逊云科技一个经典的服务开发架构方案。 我将每天介绍一个基于亚马逊云科…