本帖最后由 为半导而生 于 2015-12-10 22:24 编辑
一、实验目的
学习使用STM32F7的I2C,进行MPU6050数据的采集。
二、开发工具
STM32CUBEMX
KEIL V5
三、开发步骤
1.STM32F7的时钟初始化(本小组按照nemo1991方式进行系统初始化)
STM32的时钟系统相对复杂,可以使用多种时钟源,同时可以选择锁相环、倍频分频系数等,同时不同的外设总线可以设置相应的时钟频率。
本次实验中,我们使用内部时钟作为时钟源。
首先,打开STM32CUBEMX(下文简称CUBE),选择新建工程。之后选择MCU的型号,DIS板子上的芯片型号是STM32F746NGH,点击OK。此时即可完成工程的基本创建。
之后选择clockconfiguration进行时钟配置。几个要点:使用HSIRC内部16M时钟作为时钟源;使用PLL,设置分频倍频系数,使得PLL输出为200M(事实上F7的最高时钟频率官方设置为216M);之后合理设置分频系数给HCLK和后续外设及总线使用。
至此,完成时钟初始化。
2.I2C
引脚选择
对于F7的板子,可以引出来的管脚只有Arduino兼容的部分管脚。引脚中包含I2C,这里,对应在F7上的引脚如图1所示。
3.I2C
引脚设置
本次设计中,I2C对应的三个引脚为PB8,PB9。使用I2C复用功能下,IO应该设置为上拉。具体设置如图2所示。
4.I2C
功能设置
按照MPU6050通讯要求,可以使用高速模式的I2C,这里设置如下。具体设置如图3所示。
5.I2C读写函数
- void i2cWrite(uint16_t DevAddress, uint16_t MemAddress, uint8_t data)
- {
- uint8 pData[1];
- pData[0] = data;
- HAL_I2C_Mem_Write(&hi2c1, DevAddress, MemAddress, I2C_MEMADD_SIZE_8BIT, pData, 1, 500);
- }
- uint8 i2cRead(uint16_t DevAddress, uint16_t MemAddress)
- {
- uint8 data[1];
- HAL_I2C_Mem_Read(&hi2c1, DevAddress, MemAddress, I2C_MEMADD_SIZE_8BIT, data, 1, 500);
- return data[0];
- }
复制代码
6.MPU6050
的初始化
- void MPU6050_Init()
- {
- i2cWrite(MPU6050_ADDR, PWR_MGMT_1, 0x00); //½â³ýÐÝÃß״̬
- i2cWrite(MPU6050_ADDR, SMPLRT_DIV, 0x07);
- i2cWrite(MPU6050_ADDR, CONFIG, 0x06);
- //Ñ¡ÔñÁ¿³Ì
- #if GYRO_SCALE == GYRO_SCALE_250dps
- i2cWrite(MPU6050_ADDR, GYRO_CONFIG, 0x00);
- //gyro_coeff = 131.072;
- #endif
- #if GYRO_SCALE == GYRO_SCALE_500dps
- i2cWrite(MPU6050_ADDR, GYRO_CONFIG, 0x08);
- //gyro_coeff = 65.536;
- #endif
- #if GYRO_SCALE == GYRO_SCALE_1000dps
- i2cWrite(MPU6050_ADDR, GYRO_CONFIG, 0x10);
- //gyro_coeff = 32.768;
- #endif
- #if GYRO_SCALE == GYRO_SCALE_2000dps
- i2cWrite(MPU6050_ADDR, GYRO_CONFIG, 0x18);
- //gyro_coeff = 16.384;
- #endif
- i2cWrite(MPU6050_ADDR, ACCEL_CONFIG, 0x00);
- }
复制代码
7.MPU6050
原始数据读取
- int16 MPU6050_GetData(char REG_Address)
- {
- int8 H,L;
- H = i2cRead(MPU6050_ADDR, REG_Address);
- L = i2cRead(MPU6050_ADDR, REG_Address+1);
- return (H<<8)+L;
- }
复制代码