MPU6050陀螺仪(STM32)

目录

一、介绍

二、传感器原理

1.尺寸图

2.引脚描述

三、程序设计

main.c文件

MPU6050.c文件

MPU6050.h文件

四、实验效果

五、资料获取

项目分享


一、介绍

MPU6050是一款集成了三轴陀螺仪、三轴加速度计、温度传感器及 DMP 数字运动处理器的六轴运动传感器,可通过 I2C 接口测量物体三维加速度并直接解算姿态;它具备高度集成、体积小巧、低功耗、性能稳定、成本低廉、开发简单的优点,还能减轻主控芯片运算负担;常被用于无人机飞控、平衡小车、智能穿戴、手机姿态识别、等体感设备,是入门和实用度极高的主流六轴传感器

以下是MPU6050陀螺仪的参数:

|-------|-----------------------|
| 型号 | MPU6050 |
| 工作电压 | DC 3.3~5V |
| 通信接口 | I2C |
| 主芯片 | MPU6050 |
| 芯片内置 | 16bit AD转换器,16位数据输出 |
| 工作温度 | -40~+85℃ |
| 陀螺仪范围 | ±250 500 1000 2000°/s |
| 全量程范围 | ±2/±4/±8/±16 g |

哔哩哔哩视频链接: https://www.bilibili.com/video/BV1SowLzjEKy/?spm_id_from=333.1387.homepage.video_card.click&vd_source=199aed5297a00e80e1faf7e270afe8d7

(资料分享见文末)

二、传感器原理

1.尺寸图

2.引脚描述

|--------|--------------|
| 引脚 | 描述 |
| VCC | 3.3-5V |
| GND | 地 |
| SDA | I2C串行时钟线 |
| SCL | I2C串行数据线 |
| XDA | 连接其他设备的主机数据口 |
| XCL | 给I2C设备提供主时钟 |
| AD0 | I2C器件地址选择位 |
| INT | 中断引脚 |

三、程序设计

1.使用STM32F103C8T6读取陀螺仪数据、加速度数据

2.将读取得到的数据同时在OLED上显示

|-------------|-----|
| MPU6050_SCL | PA0 |
| MPU6050_SDA | PA1 |
| OLED_SCL | PB6 |
| OLED_SDA | PB7 |
| 串口 | 串口1 |

main.c文件

cpp 复制代码
#include "stm32f10x.h"
#include "led.h"
#include "usart.h"
#include "delay.h"
#include "oled.h"
#include "MPU6050.h"

/*****************辰哥单片机设计******************
                     STM32
 * 文件		       	:	    MPU6050实验                 
 * 版本		       	:       V1.0
 * 日期		        :       2026.3.10
 * MCU		       	:	    STM32F103C8T6
 * 接口	        	:	    见代码													
 * IP账号	        :	    辰哥单片机设计(同BILIBILI|抖音|快手|小红书|CSDN|公众号|视频号等)
 * 作者		        :	    辰哥 
 * 工作室	       	:       异方辰电子工作室
 * 官方网站	        :	    www.yfcdz.cn

**********************BEGIN***********************/

uint8_t ID;								//定义用于存放ID号的变量
int16_t AX, AY, AZ, GX, GY, GZ;			//定义用于存放各个数据的变量
uint8_t fall_status;   
int main(void)
{ 
    SystemInit();//配置系统时钟为72M	
    delay_init(72);    
    LED_Init();
    LED_On();
		MPU6050_Init();		//MPU6050初始化
	  USART1_Config();//串口初始化
    OLED_Init();       // OLED初始化

    printf("Start \n");
    delay_ms(1000);

	//OLED_ShowString(1, 1, "ID:");		//显示静态字符串
	ID = MPU6050_GetID();				//获取MPU6050的ID号
    

    while (1)
    {
			//加速度
			OLED_ShowString(0,0,"X",16,1);
			OLED_ShowString(0,16,"Y",16,1);
			OLED_ShowString(0,32,"Z",16,1);
			//陀螺仪
			OLED_ShowString(64,0,"X",16,1);
			OLED_ShowString(64,16,"Y",16,1);
			OLED_ShowString(64,32,"Z",16,1);
			
      	MPU6050_GetData(&AX, &AY, &AZ, &GX, &GY, &GZ);		
        OLED_ShowintNum(12, 0, AX, 5, 16, 1);  
        OLED_ShowintNum(12, 16, AY, 5, 16, 1); 
        OLED_ShowintNum(12, 32, AZ, 5, 16, 1); 
			
			
        OLED_ShowintNum(76, 0, GX, 5, 16, 1);
        OLED_ShowintNum(76, 16, GY, 5, 16, 1);
        OLED_ShowintNum(76, 32, GZ, 5, 16, 1);
			
			 //OLED_ShowChinese(16,48,0,16,1);	
	     OLED_ShowChinese(0,48,0,16,1);
	     OLED_ShowChinese(16,48,1,16,1);
	     OLED_ShowChinese(32,48,2,16,1);
	     OLED_ShowChinese(48,48,3,16,1);
	     OLED_ShowChar(64,48,':',16,1);
 
			 fall_status = MPU6050_CheckFall();
        if(fall_status)
        {
            OLED_ShowChinese(94,48,0,16,1); // 显示"是"
            printf("Fall detected! \n");       
            LED_Off(); 
        }
        else
        {
            OLED_ShowChinese(94,48,1,16,1);  // 显示"否"
            LED_On();  
        }
			  OLED_Refresh();
       // delay_ms(100);  // 检测间隔100ms,平衡响应速度和防抖
       
    }
}

MPU6050.c文件

cpp 复制代码
#include "MPU6050.h"
#include "math.h"   
#include "stdlib.h" 


/*****************辰哥单片机设计******************
                     STM32
 * 文件			:	    MPU6050实验                 
 * 版本			:       V1.0
 * 日期			:       2026.3.10
 * MCU			:	    STM32F103C8T6
 * 接口			:	    见代码													
 * IP账号		:	    辰哥单片机设计(同BILIBILI|抖音|快手|小红书|CSDN|公众号|视频号等)
 * 作者			:	    辰哥 
 * 工作室		:       异方辰电子工作室
 * 官方网站	    :	    www.yfcdz.cn

**********************BEGIN***********************/


#define XY_ACC_THRESH    1800     
#define FALL_DEBOUNCE_CNT 1       // 防抖次数:连续1次超过阈值即判定(值越大越稳定,越小越灵敏)
#define FALL_CHECK_INTERVAL 100   // 检测间隔(ms)

static uint8_t fall_detect_cnt = 0;  // 静态变量:连续异常计数(仅本文件可见)

/************************ 软件I2C底层驱动函数实现 ************************/
// I2C写SCL引脚电平(BitValue=1:拉高,0:拉低)
void MPU6050_W_SCL(uint8_t BitValue)
{
    // 设置SCL引脚电平(开漏输出模式,拉高=释放总线,拉低=强制输出低)
    GPIO_WriteBit(MPU6050_I2C_PORT, MPU6050_I2C_SCL_PIN, (BitAction)BitValue);
    delay_us(10);  // 延时10us:保证I2C时序稳定(软件I2C必须加延时)
}

// I2C写SDA引脚电平(BitValue=1:拉高,0:拉低)
void MPU6050_W_SDA(uint8_t BitValue)
{
    GPIO_WriteBit(MPU6050_I2C_PORT, MPU6050_I2C_SDA_PIN, (BitAction)BitValue);
    delay_us(10);  // 延时10us:保证I2C时序稳定
}

// I2C读SDA引脚电平(返回:1=高电平,0=低电平)
uint8_t MPU6050_R_SDA(void)
{
    uint8_t BitValue;
    // 读取SDA引脚当前电平(输入模式)
    BitValue = GPIO_ReadInputDataBit(MPU6050_I2C_PORT, MPU6050_I2C_SDA_PIN);
    delay_us(10);  // 延时10us:保证采样稳定
    return BitValue;
}

// I2C引脚初始化(配置为开漏输出)
void MPU6050_IIC_Init(void)
{
    // 1. 使能GPIO端口时钟
    RCC_APB2PeriphClockCmd(MPU6050_I2C_CLK, ENABLE);
    
    // 2. 配置GPIO引脚参数
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;  // 开漏输出(I2C标准模式)
    GPIO_InitStructure.GPIO_Pin = MPU6050_I2C_SCL_PIN | MPU6050_I2C_SDA_PIN; // SCL+SDA引脚
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 输出速率50MHz
    GPIO_Init(MPU6050_I2C_PORT, &GPIO_InitStructure); // 应用配置
    
    // 3. 初始化时将SCL/SDA拉高(I2C总线空闲状态)
    GPIO_SetBits(MPU6050_I2C_PORT, MPU6050_I2C_SCL_PIN | MPU6050_I2C_SDA_PIN);
}

// 发送I2C起始信号(时序:SCL高时,SDA从高拉低)
void MPU6050_Start(void)
{
    MPU6050_W_SDA(1);  // SDA先拉高
    MPU6050_W_SCL(1);  // SCL拉高(总线空闲)
    MPU6050_W_SDA(0);  // SDA拉低(起始信号)
    MPU6050_W_SCL(0);  // SCL拉低(准备发送数据)
}

// 发送I2C停止信号(时序:SCL高时,SDA从低拉高)
void MPU6050_Stop(void)
{
    MPU6050_W_SDA(0);  // SDA先拉低
    MPU6050_W_SCL(1);  // SCL拉高
    MPU6050_W_SDA(1);  // SDA拉高(停止信号)
}

// I2C发送1字节数据(参数Byte:要发送的字节,高位先行)
void MPU6050_SendByte(uint8_t Byte)
{
    uint8_t i;
    // 循环发送8位(高位到低位)
    for (i = 0; i < 8; i++)
    {
        // 1. 输出当前位(Byte & 0x80:取最高位)
        MPU6050_W_SDA(!!(Byte & (0x80 >> i)));
        // 2. SCL拉高(从机采样数据)
        MPU6050_W_SCL(1);
        // 3. SCL拉低(准备发送下一位)
        MPU6050_W_SCL(0);
    }
}

// I2C接收1字节数据(返回:接收到的字节,高位先行)
uint8_t MPU6050_ReceiveByte(void)
{
    uint8_t i, Byte = 0x00;
    MPU6050_W_SDA(1);  // 释放SDA总线(由从机控制)
    // 循环接收8位(高位到低位)
    for (i = 0; i < 8; i++)
    {
        MPU6050_W_SCL(1);  // SCL拉高(从机输出数据)
        // 读取当前位并写入Byte(左移累加)
        if(MPU6050_R_SDA()) Byte |= (0x80 >> i);
        MPU6050_W_SCL(0);  // SCL拉低(准备接收下一位)
    }
    return Byte;
}

// 发送I2C应答位(参数AckBit:0=应答,1=非应答)
void MPU6050_SendAck(uint8_t AckBit)
{
    MPU6050_W_SDA(AckBit); // 输出应答位(0=拉低,1=拉高)
    MPU6050_W_SCL(1);      // SCL拉高(从机采样应答)
    MPU6050_W_SCL(0);      // SCL拉低
}


// 接收I2C应答位(返回:0=从机应答,1=从机非应答)
uint8_t MPU6050_ReceiveAck(void)
{
    uint8_t AckBit;
    MPU6050_W_SDA(1);         // 释放SDA总线
    MPU6050_W_SCL(1);         // SCL拉高(读取应答)
    AckBit = MPU6050_R_SDA(); // 读取应答位
    MPU6050_W_SCL(0);         // SCL拉低
    return AckBit;
}


/************************ MPU6050核心功能函数实现 ************************/
#define MPU6050_ADDR 0xD0  // MPU6050的I2C设备地址(0x68 << 1,左移1位含读写位)

// 写MPU6050寄存器(参数:RegAddress=寄存器地址,Data=要写入的数据)
void MPU6050_WriteReg(uint8_t RegAddress, uint8_t Data)
{
    MPU6050_Start();                // 1. 发送起始信号
    MPU6050_SendByte(MPU6050_ADDR); // 2. 发送设备写地址(0xD0=写)
    MPU6050_ReceiveAck();           // 3. 等待从机应答
    MPU6050_SendByte(RegAddress);   // 4. 发送寄存器地址
    MPU6050_ReceiveAck();           // 5. 等待从机应答
    MPU6050_SendByte(Data);         // 6. 发送要写入的数据
    MPU6050_ReceiveAck();           // 7. 等待从机应答
    MPU6050_Stop();                 // 8. 发送停止信号
}

// 读MPU6050寄存器(参数:RegAddress=寄存器地址;返回:读取到的数据)
uint8_t MPU6050_ReadReg(uint8_t RegAddress)
{
    uint8_t Data;
    MPU6050_Start();                // 1. 发送起始信号
    MPU6050_SendByte(MPU6050_ADDR); // 2. 发送设备写地址(先写寄存器地址)
    MPU6050_ReceiveAck();           // 3. 等待从机应答
    MPU6050_SendByte(RegAddress);   // 4. 发送寄存器地址
    MPU6050_ReceiveAck();           // 5. 等待从机应答
    
    MPU6050_Start();                // 6. 重新发送起始信号(切换为读模式)
    MPU6050_SendByte(MPU6050_ADDR|0x01); // 7. 发送设备读地址(0xD1=读)
    MPU6050_ReceiveAck();           // 8. 等待从机应答
    Data = MPU6050_ReceiveByte();   // 9. 接收寄存器数据
    MPU6050_SendAck(1);             // 10. 发送非应答(结束接收)
    MPU6050_Stop();                 // 11. 发送停止信号
    return Data;
}

// MPU6050初始化(配置:唤醒传感器、加速度/陀螺仪量程、采样率)
void MPU6050_Init(void)
{
    MPU6050_IIC_Init();  // 1. 初始化I2C引脚
    
    // 2. 唤醒MPU6050(电源管理寄存器1:0x00=使用内部8MHz时钟,唤醒)
    MPU6050_WriteReg(MPU6050_PWR_MGMT_1, 0x00);
    // 3. 设置采样率分频(采样率=1000/(1+9)=100Hz)
    MPU6050_WriteReg(MPU6050_SMPLRT_DIV, 0x09);
    // 4. 配置低通滤波(0x00=256Hz,无滤波)
    MPU6050_WriteReg(MPU6050_CONFIG, 0x00);
    // 5. 配置陀螺仪量程(0x18=±2000°/s,最大量程)
    MPU6050_WriteReg(MPU6050_GYRO_CONFIG, 0x18);
    // 6. 配置加速度计量程(0x18=±16g,最大量程)
    MPU6050_WriteReg(MPU6050_ACCEL_CONFIG, 0x18);
}


// 获取MPU6050的ID号(返回:0x68=正常,其他值=通信异常)
uint8_t MPU6050_GetID(void)
{
    // 读取WHO_AM_I寄存器(默认值0x68)
    return MPU6050_ReadReg(MPU6050_WHO_AM_I);
}

// 获取加速度/陀螺仪原始数据
// 参数说明:
// AccX/AccY/AccZ:输出加速度计原始值(±16g量程下,1LSB=2048 LSB/g)
// GyroX/GyroY/GyroZ:输出陀螺仪原始值(±2000°/s量程下,1LSB=16.4 LSB/(°/s))
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位数据
    
    // 读取加速度计X轴数据(高8位+低8位拼接为16位有符号数)
    DataH = MPU6050_ReadReg(MPU6050_ACCEL_XOUT_H);
    DataL = MPU6050_ReadReg(MPU6050_ACCEL_XOUT_L);
    *AccX = (DataH << 8) | DataL;
    
    // 读取加速度计Y轴数据
    DataH = MPU6050_ReadReg(MPU6050_ACCEL_YOUT_H);
    DataL = MPU6050_ReadReg(MPU6050_ACCEL_YOUT_L);
    *AccY = (DataH << 8) | DataL;
    
    // 读取加速度计Z轴数据
    DataH = MPU6050_ReadReg(MPU6050_ACCEL_ZOUT_H);
    DataL = MPU6050_ReadReg(MPU6050_ACCEL_ZOUT_L);
    *AccZ = (DataH << 8) | DataL;
    
    // 读取陀螺仪X轴数据
    DataH = MPU6050_ReadReg(MPU6050_GYRO_XOUT_H);
    DataL = MPU6050_ReadReg(MPU6050_GYRO_XOUT_L);
    *GyroX = (DataH << 8) | DataL;
    
    // 读取陀螺仪Y轴数据
    DataH = MPU6050_ReadReg(MPU6050_GYRO_YOUT_H);
    DataL = MPU6050_ReadReg(MPU6050_GYRO_YOUT_L);
    *GyroY = (DataH << 8) | DataL;
    
    // 读取陀螺仪Z轴数据
    DataH = MPU6050_ReadReg(MPU6050_GYRO_ZOUT_H);
    DataL = MPU6050_ReadReg(MPU6050_GYRO_ZOUT_L);
    *GyroZ = (DataH << 8) | DataL;
}



/************************ 摔倒检测核心函数 ************************/
// 返回值:1=检测到摔倒,0=正常
uint8_t MPU6050_CheckFall(void)
{
    int16_t ax, ay;          // 临时存储X/Y轴加速度值
    uint32_t xy_acc_sum;     // X+Y轴加速度绝对值之和(避免正负抵消)
    uint8_t fall_flag = 0;   // 摔倒标志(0=正常,1=摔倒)
    
    // 1. 获取当前X、Y轴加速度数据(Z轴/陀螺仪传0,无需读取)
    MPU6050_GetData(&ax, &ay, 0, 0, 0, 0);
    
    // 2. 计算X+Y轴加速度绝对值之和(abs():取绝对值,避免正负抵消)
    xy_acc_sum = abs(ax) + abs(ay);
    
    // 3. 摔倒判定逻辑
    if (xy_acc_sum > XY_ACC_THRESH)  // 超过阈值=异常
    {
        fall_detect_cnt++;  // 连续异常计数+1
        // 连续异常次数达到防抖阈值=判定为摔倒
        if (fall_detect_cnt >= FALL_DEBOUNCE_CNT)
        {
            fall_flag = 1;          // 设置摔倒标志
            fall_detect_cnt = 0;    // 重置计数(避免重复触发)
        }
    }
    else  // 未超过阈值=正常
    {
        fall_detect_cnt = 0;    // 重置异常计数
        fall_flag = 0;          // 清除摔倒标志
    }
    
    return fall_flag;  // 返回判定结果
}

MPU6050.h文件

cpp 复制代码
#ifndef __MPU6050_H
#define __MPU6050_H
#include "stm32f10x.h" 
#include "delay.h"     

/*****************辰哥单片机设计******************
                     STM32
 * 文件			:	MPU6050实验                 
 * 版本			:   V1.0
 * 日期			:   2026.3.10
 * MCU			:	STM32F103C8T6
 * 接口			:	见代码													
 * IP账号		:	辰哥单片机设计(同BILIBILI|抖音|快手|小红书|CSDN|公众号|视频号等)
 * 作者			:	辰哥 
 * 工作室		:   异方辰电子工作室
 * 官方网站	    :	www.yfcdz.cn

**********************BEGIN***********************/

/************************ 软件I2C引脚配置宏 ************************/
#define MPU6050_I2C_PORT        GPIOA                 // I2C总线使用的GPIO端口
#define MPU6050_I2C_SCL_PIN     GPIO_Pin_0            // SCL时钟引脚
#define MPU6050_I2C_SDA_PIN     GPIO_Pin_1            // SDA数据引脚
#define MPU6050_I2C_CLK         RCC_APB2Periph_GPIOA  // I2C端口对应的时钟

/************************ MPU6050寄存器地址定义 ************************/
#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    // 加速度计X轴高8位数据寄存器
#define	MPU6050_ACCEL_XOUT_L	0x3C    // 加速度计X轴低8位数据寄存器
#define	MPU6050_ACCEL_YOUT_H	0x3D    // 加速度计Y轴高8位数据寄存器
#define	MPU6050_ACCEL_YOUT_L	0x3E    // 加速度计Y轴低8位数据寄存器
#define	MPU6050_ACCEL_ZOUT_H	0x3F    // 加速度计Z轴高8位数据寄存器
#define	MPU6050_ACCEL_ZOUT_L	0x40    // 加速度计Z轴低8位数据寄存器
#define	MPU6050_TEMP_OUT_H		0x41    // 温度传感器高8位数据寄存器
#define	MPU6050_TEMP_OUT_L		0x42    // 温度传感器低8位数据寄存器
#define	MPU6050_GYRO_XOUT_H		0x43    // 陀螺仪X轴高8位数据寄存器
#define	MPU6050_GYRO_XOUT_L		0x44    // 陀螺仪X轴低8位数据寄存器
#define	MPU6050_GYRO_YOUT_H		0x45    // 陀螺仪Y轴高8位数据寄存器
#define	MPU6050_GYRO_YOUT_L		0x46    // 陀螺仪Y轴低8位数据寄存器
#define	MPU6050_GYRO_ZOUT_H		0x47    // 陀螺仪Z轴高8位数据寄存器
#define	MPU6050_GYRO_ZOUT_L		0x48    // 陀螺仪Z轴低8位数据寄存器
#define	MPU6050_PWR_MGMT_1		0x6B    // 电源管理寄存器1(唤醒传感器、选择时钟源)
#define	MPU6050_PWR_MGMT_2		0x6C    // 电源管理寄存器2(禁用轴)
#define	MPU6050_WHO_AM_I		  0x75    // 设备ID寄存器(默认值0x68,用于校验通信)

/************************ I2C底层驱动函数声明(软件模拟I2C) ************************/
void MPU6050_IIC_Init(void);            // I2C引脚初始化(配置为开漏输出)
void MPU6050_Start(void);               // 发送I2C起始信号(SCL高时SDA拉低)
void MPU6050_Stop(void);                // 发送I2C停止信号(SCL高时SDA拉高)
void MPU6050_SendByte(uint8_t Byte);    // I2C发送1字节数据(高位先行)
uint8_t MPU6050_ReceiveByte(void);      // I2C接收1字节数据(高位先行)
void MPU6050_SendAck(uint8_t AckBit);   // 发送应答位(0=应答,1=非应答)
uint8_t MPU6050_ReceiveAck(void);       // 接收从机应答位

/************************ MPU6050功能函数声明 ************************/
void MPU6050_WriteReg(uint8_t RegAddress, uint8_t Data);  // 写MPU6050寄存器(指定地址写入1字节)
uint8_t MPU6050_ReadReg(uint8_t RegAddress);              // 读MPU6050寄存器(指定地址读取1字节)
void MPU6050_Init(void);                                  // MPU6050初始化(配置量程、采样率、唤醒)
uint8_t MPU6050_GetID(void);                              // 获取MPU6050的ID号(校验通信是否正常)
// 获取加速度/陀螺仪原始数据(输出:AccX/Y/Z=加速度值,GyroX/Y/Z=陀螺仪值)
void MPU6050_GetData(int16_t *AccX, int16_t *AccY, int16_t *AccZ, 
                     int16_t *GyroX, int16_t *GyroY, int16_t *GyroZ);
uint8_t MPU6050_CheckFall(void);                          // 摔倒检测函数(返回:1=摔倒,0=正常)

#endif  // __MPU6050_H 头文件结束

四、实验效果

五、资料获取

项目分享

相关推荐
梦..3 小时前
电路EMC问题(二)
嵌入式硬件·硬件架构·硬件工程·pcb工艺
我不是程序猿儿5 小时前
【嵌入式】stm32的时钟配置入门及切入
stm32·单片机·嵌入式硬件
是大强6 小时前
斯密特触发器作用
单片机
爱倒腾的老唐7 小时前
03、制作 STM32 最小系统
stm32·单片机·嵌入式硬件
悠哉悠哉愿意8 小时前
【物联网学习笔记】串口接收
笔记·单片机·嵌入式硬件·物联网·学习
dragen_light8 小时前
jetson orin nano 配置lerobot环境(内含重装torch/torchvision步骤)
嵌入式硬件
夜月yeyue8 小时前
Linux 邻接(Neighbor)子系统架构与 NUD 状态机
linux·运维·服务器·嵌入式硬件·算法·系统架构
灵魂尾巴.8 小时前
单片机数据存储器
单片机·嵌入式硬件
番茄灭世神8 小时前
空气质量检测仪项目笔记——硬件介绍
stm32·单片机·嵌入式·gd32·国产芯片