STM32CubeMX-H7-13-IIC读写MPU6050模块(下)-硬件IIC驱动MPU6050模块

前言

前面我们已经使用软件驱动iIC,接下来我们使用硬件来驱动。

其实硬件很简单,懂得软件驱动的原理

是发个地址+寄存器+数值

是发个地址+寄存器

HAL库的函数也就是把这些数值填入就可以正常使用

STM32CUBEMX配置

直接把disable换一下就好,其他不用动

IIC的硬件三种使用方式

模式 应用场景
普通 I2C(轮询模式) 适用于对实时性要求不高、数据传输量小的简单应用,如偶尔读取一个传感器的状态信息。
I2C 中断模式(IT I2C) 适用于对实时性有一定要求、数据传输量中等的场景,如周期性地读取多个传感器的数据。
I2C DMA 模式(DMA I2C) 适用于数据传输量大、对实时性要求高的场景,如大量数据的存储或高速传感器数据的连续采集。

普通IIC

普通IIC会用到的函数有

 HAL_I2C_Master_Transmit(hi2c, SIMPLE_DEVICE_ADDR << 1, data, size, 1000);
 HAL_I2C_Master_Receive(hi2c, (SIMPLE_DEVICE_ADDR << 1) | 1, data, size, 1000);


HAL_I2C_Mem_Write(hi2c, MPU6050_WRITE_ADDR, reg, I2C_MEMADD_SIZE_8BIT, &data, 1, 1000);
 HAL_I2C_Mem_Read(hi2c, MPU6050_READ_ADDR, reg, I2C_MEMADD_SIZE_8BIT, &data, 1, 1000);

主要是这四种

HAL_I2C_Master_Transmit

HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);

就是简单对某个设备发送什么信息, 不涉及寄存器

HAL_I2C_Master_Receive

HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);

也只是简单接收,不涉及寄存器的

HAL_I2C_Mem_Read

HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout);

涉及寄存器的,在我们这个模块就需要对寄存器进行操作,所以我打算是使用这个,会使用这个,再去使用中断和DMA都很简单

HAL_I2C_Mem_Write

HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout);

寄存器写入操作

总结

这四个函数的部分参数含义相近,但 HAL_I2C_Mem_Read 和 HAL_I2C_Mem_Write 多了 MemAddress 和 MemAddSize 这两个参数,用于指定从设备内部的寄存器地址及地址大小,以实现对特定寄存器的读写操作。在使用时,需根据具体的 I2C 通信需求准确设置这些参数。

中断DMA

中断IIC

HAL_I2C_Mem_Read_IT

HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size);

HAL_I2C_Mem_Write_IT

HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size);

DMA IIC

HAL_I2C_Mem_Read_DMA

HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size);

HAL_I2C_Mem_Write_DMA

HAL_StatusTypeDef HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size);

普通IIC驱动MPU6050

我们模仿软件那样填入参数就好了

然后我们要封装下函数

void HAL_MPU6050_WriteReg(uint8_t RegAddress, uint8_t Data) {
    HAL_I2C_Mem_Write(&hi2c4, MPU6050_ADDR_AD0_LOW<<1, RegAddress, I2C_MEMADD_SIZE_8BIT, &Data, 1, 1000);  // 写入数据到指定寄存器
}

uint8_t HAL_MPU6050_ReadReg(uint8_t RegAddress) {
    uint8_t Data;
    (&hi2c4, MPU6050_ADDR_AD0_LOW<<1|1, RegAddress, I2C_MEMADD_SIZE_8BIT, &Data, 1, 1000);  // 读取指定寄存器的数据
    return Data;  // 返回读取到的数据	
}

一读一些就好了

给寄存器写入数据,一定是地址,要不然功能都失效完

就是data哪里,如果你不想封装,直接填一个0x75获取地址的指令

那么是无效的,必须拿变量存然后放地址才行

然后就正常使用就OK了

示例程序

初始化程序


void HAL_MPU6050_init(void) {
    HAL_MPU6050_WriteReg(PWR_MGMT_1, 0x80);  // 复位 MPU6050
    HAL_Delay(300);  // 等待传感器复位
    HAL_MPU6050_WriteReg(PWR_MGMT_1, 0x00);  // 唤醒 MPU6050
    HAL_MPU6050_WriteReg(PWR_MGMT_1, 0x01);  // 设置时钟源为 X 轴
    HAL_MPU6050_WriteReg(PWR_MGMT_2, 0x00);  // 设置所有传感器启用
    HAL_MPU6050_WriteReg(SMPLRT_DIV, 0x09);  // 设置采样率分频值
    HAL_MPU6050_WriteReg(CONFIG, 0x06);  // 设置低通滤波器频率
    HAL_MPU6050_WriteReg(GYRO_CONFIG, 0x18);  // 设置陀螺仪量程为 ±2000 °/s
    HAL_MPU6050_WriteReg(ACCEL_CONFIG, 0x18);  // 设置加速度计量程为 ±16 g
    HAL_Delay(100);  // 等待传感器稳定
}

获取ID的程序

uint8_t HAL_MPU6050_GetDeviceID(void) {
    uint8_t data;
    HAL_I2C_Mem_Read(&hi2c4, MPU6050_ADDR_AD0_LOW<<1|1, WHO_AM_I, I2C_MEMADD_SIZE_8BIT, &data, 1, 1000);  // 读取设备 ID 寄存器
	return data;  // 返回设备 ID
}

以上就是对基本的读和写的使用了

猜你喜欢

转载自blog.csdn.net/m0_74211379/article/details/147014579
今日推荐