最近准备一个比赛,所以正在加紧学习stm32,这篇文章就结合mpu6050分析一下利用i2c实现芯片之间的通信。
首先可以在原有的LED文件或显示屏(OLED)的文件基础上,新建一个HANDWARE,在其中加入mpu6050.c和mpu6050.h(名字自定)。
首先是在C文件中加入基本的I2C通信函数
1.I2C的GPIO端口初始化SDA、SCL设置为推挽输出。
2.然后是i2c_start();i2c_stop();函数,根据时序图设置SCL、SDA的高低电平变化。
3.之后加入主机ack的响应函数和ack的等待响应函数i2c_wait_ack();i2c_ack();i2c_waitack();。
4.最后加入IIC_Send_Byte();和IIC_Read_Byte();
具体实现可以参考其他文章,这里重点讲解mpu6050的通信实现。
上面部分的一个难点在于GPIO口的模式转化,因为SDA的输入输出在变化,所以可以使用寄存器操作的宏定义来改变IO口的模式,使用位操作来控制SDA、SCL的高低电平。其中在wait_ack中设置SDA为输入,可以通过SDA_w的设置达到输入的上拉、下拉的设置,具体参考下面的端口位配置表。
#define SDA_IN() {GPIOB->CRH&=0XFFFFFFF0;GPIOB->CRH|=8<<0;}
#define SDA_OUT() {GPIOB->CRH&=0XFFFFFFF0;GPIOB->CRH|=3<<0;}
//IO操作函数
#define SCL PBout(9) //SCL
#define SDA_w PBout(8) //SDA
#define SDA_r PBin(8) //输入SDA
完成上面的I2C函数,就可以根据I2C函数完成mpu6050函数的编写了。对于具体芯片,有具体的时序分析。这部分也可以参考其他文章,这里列出实例。
u8 MPU_Write_Byte(u8 reg,u8 data)
{
i2c_start();
IIC_Send_Byte((MPU_ADDR<<1)|0);//发送器件地址+写命令
if(i2c_wait_ack()) //等待应答
{
i2c_stop();
return 1;
}
IIC_Send_Byte(reg); //写寄存器地址
i2c_wait_ack(); //等待应答
IIC_Send_Byte(data);//发送数据
if(i2c_wait_ack()) //等待ACK
{
i2c_stop();
return 1;
}
i2c_stop();
return 0;
}
u8 MPU_Read_Byte(u8 reg)
{
u8 res;
i2c_start();
IIC_Send_Byte((MPU_ADDR<<1)|0);//发送器件地址+写命令
i2c_wait_ack(); //等待应答
IIC_Send_Byte(reg); //写寄存器地址
i2c_wait_ack(); //等待应答
i2c_start();
IIC_Send_Byte((MPU_ADDR<<1)|1);//发送器件地址+读命令
i2c_wait_ack(); //等待应答
res=IIC_Read_Byte(0);//读取数据,发送nACK
i2c_stop(); //产生一个停止条件
return res;
}
1.针对mpu6050写出具体的字节发送、读取函数,mpu6050主要用到了MPU_Read_Byte,MPU_Write_Byte,MPU_Read_Len(连续读函数)。
2.mpu6050的初始化函数MPU_Init(),其中会向芯片的指定寄存器传入参数,所以可以在.h文件中加入寄存器的宏定义。
3.根据需要定义向指定寄存器读取数值的函数,mpu6050可以读取陀螺仪值、加速度值、温度值。
其中加速度计通过重力加速度分解(利用atan2)可以得到倾角,而陀螺仪则可以测得角速度。但是这两类数据都不准确,需要数据融合。
这里给出一个互补滤波的算法。
Angle = (0.98) * (Angle + gyro * dt) + (0.02) *(acc);
利用这个算法可以得到较精确的值。
上一篇:STM32(五)IIC通信原理及IO口软件模拟编程
下一篇:STM32(五)IIC通信原理及IO口软件模拟编程
推荐阅读最新更新时间:2024-11-17 05:41
设计资源 培训 开发板 精华推荐
- LTC1844ES5-BYP 演示板,低噪声微功率线性稳压器,Vin = 1.8V - 6.5V,Vout = 150mA Max
- 用于 24V 汽车应用的 LTC4367CMS8-1 过压电源保护控制器的典型应用
- LT1086CM-3.3 5V、1.5A 低压差正稳压器的典型应用
- 用于微功率 A/D 转换器的 LT1634ACS8-4.096 电压基准的典型应用
- LTC3873、48V 输入、3.3V、3A 输出反激式转换器
- 具有理想二极管的 LTC4364 浪涌抑制器的典型应用
- L7812A 固定输出稳压器的典型应用
- LT1121AHCS8 5V 低压差稳压器的典型应用电路,用于具有关断的电池供电电源
- 通用8位S08/RS08 MCU塔式系统模块
- 基于Kinetis KV的三相PMSM无传感器控制参考设计