IIC通信协议
基本功能
-
同步时序的稳定性比异步时序更高
-
半双工
-
SCL、SDA两根通信线
-
支持总线挂载(一主多从,多主多从)
硬件电路
- 所有I2C设备的SCL连接在一起,SDA连接在一起
- 设备的SCL和SDA均要配置成开漏输出模式(防止形成短路电流,SDA要么被上拉,要么输出低电平),会有“线与”的现象。在多主机的模式下,可以利用线与的特性,实现总线仲裁和时钟同步。
- SCL和SDA各添加一个上拉电阻,阻值一般为4.7KΩ左右
PS:IIC时序是高位先行,串口是低位先行
PS:主机接收时,需要释放SDA,即输入模式
PS:从机的地址可以通过电路改变
红线处,此时需要从机应答,这里如果但看主机的SDA,应该会释放SDA,即高电平,由于从机要发送应答,根据线与的特性,这里拉低了SDA,所以最后SDA呈现图中所示。
IIC通信的设备中会有单独一个字节空间存储地址指针,当给IIC设备指定地址写时,地址指针会加一,这时如果使用当前地址读,就是读取指针地址指向的内存。此时序较为少用、
指定地址读的实现原理:先调用指定地址写,但是不写数据。再次调用当前地址读,这样复合的时序就能完成指定地址读的功能了
MPU6050
姿态角(欧拉角)
飞机相对于初始三个轴的夹角:
- 俯仰角:Pitch
- 滚转:Roll
- 偏航:Yaw
要想获得稳定的欧拉角,就需要进行数据融合,进一步得到姿态角。
常见的数据融合算法:
- 互补滤波
- 卡尔曼滤波
ps:惯性导航领域里,姿态解算
加速度计结构
F=ma(测力计)
加速度计测得的是静态加速度,只能在物体静止的时候使用
陀螺仪传感器
测得的是角速度,要想得到角度,可以进行求积分
陀螺仪具有动态稳定性,不具有静态稳定性
对两种传感器进行互补滤波,就可以得到稳定的姿态角了
MPU6050的参数
eg: mpu6050的从机地址:0x68 ,IIC时序中发送的第一个字节,高七位为从机地址,第八位为读写位。有时候把0XD0当作MPU6050的地址
硬件结构
六轴传感器的缺点:没有稳定的参考方向
XCL,XDA:挂载磁力计,气压计
INT引脚:可以配置MPU6050内部一些事件,产生电平跳变
PS:MPU6050内部包含DMP单元:进行姿态融合和数据结算
包含稳压电路
传感器内部含有自测单元
使能自测->读取数据1->失能自测->读取数据2,两个数据相减,得到的数据称作自测响应,自测响应如果在规定的范围内,说明芯片性能没问题。
电荷泵
是一种升压电路
原理:电源和电容串并联的切换(充电->串联->相当于电压升高(放电)->快速切换到并联->充电->循环)+ 电容滤波 = 平稳升压
DMP(数字运动处理器)
配合MPU6050官方的DMP库,进行姿态解算。
引脚说明
FSYNC:帧同步
通信接口:用于和STM32通信
xxxxxxxxxx python script_name.py --train_data_dir “path/to/train_data” --test_data_dir “path/to/test_data” --img_height 128 --img_width 128 --batch_size 64 --epochs 15python
可以拓展连接磁力计
软件IIC读写MPU6050
1 |
|
修改MPU6050地址
可见,寻址无应答
读取MPU6050 ID号
1 | int main(void) |
写MPU6050,需要关闭MPU6050的睡眠模式
1 | int main(void) |
PS:某种程度上来说,对寄存器的读写操作可以看作读写一个存储器,但是寄存器能反应硬件电路的状态,对硬件电路进行操作
MPU6050读取六轴姿态值
函数定义
1 | //使用指针,实现函数多返回值的操作 |
主程序
1 | int16_t Ax,Ay,Az,Gx,Gy,Gz; |
加速度计最大量程为16g
左侧为加速度计,右侧为角速度测量值
硬件IIC读写MPU6050
CR:控制寄存器
DR:数据寄存器
SR:状态寄存器
STM32IIC外设
多主机模型
一主多从
多主多从
固定多主机:
可变多主机:
GPIO复用输入和复用输出
IIC主机发送流程图
IIC主机接收流程图
库函数解释
产生起始条件
void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState);
生成终止条件
void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState);
配置在收到一个字节后,是否给从机应答
void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState);
写数据到数据寄存器DR
void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data);
读取DR的数据,作为返回值
uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx);
发送7位地址
void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction);
状态监控函数的官方说明
1 | /** |
#IIC配置占空比的缘由
上升沿变化较慢,下降沿比较迅速,标准速度下,时钟占空比接近1:1,快速状态,占空比接近2:1
100KHZ
400KHZ
1 | * 1) Basic state monitoring |
解决WHILE死循环等待的问题
多个while,比较危险,一旦通信出现问题,程序直接卡死
1 | void MPU6050_WriteReg(uint8_t RegAddress,uint8_t Data) |
保护程序
1 | void MPU6050_WaitEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT) |
DMP库
digital motion processor数字运动处理器,mpu6050自带的一个硬件,可以直接输出用于姿态结算的四元数