赞
踩
#include "stm32f10x.h" #include "delay.h" #include "OLED.h" #include "MPU6050.h" uint8_t ID; int main(void) { OLED_Init(); MPU6050_Init(); OLED_ShowString(1, 1, "ID:"); ID = MPU6050_GetID(); OLED_ShowHexNum(1, 4, ID, 2); MPU6050_DataTypeDef MPU6050_DataStructure; while(1) { // 读取数据 MPU6050_GetData(&MPU6050_DataStructure); // 显示数据 OLED_ShowSignedNum(2, 1, MPU6050_DataStructure.AccX, 5); OLED_ShowSignedNum(3, 1, MPU6050_DataStructure.AccY, 5); OLED_ShowSignedNum(4, 1, MPU6050_DataStructure.AccZ, 5); OLED_ShowSignedNum(2, 8, MPU6050_DataStructure.GyroX, 5); OLED_ShowSignedNum(3, 8, MPU6050_DataStructure.GyroY, 5); OLED_ShowSignedNum(4, 8, MPU6050_DataStructure.GyroZ, 5); } }
#include "stm32f10x.h" #include "Delay.h" #define I2CPORT GPIOB // I2C所用端口 #define I2CSCL_PIN GPIO_Pin_10 // I2C SLC所用引脚 #define I2CSDA_PIN GPIO_Pin_11 // I2C SDA所用引脚 /* * 初始化MyI2C */ void MyI2C_Init(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // 配置GPIOB 10 11 为开漏输出 GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin=I2CSCL_PIN|I2CSDA_PIN; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_OD; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_SetBits(I2CPORT, I2CSCL_PIN|I2CSDA_PIN); } /* * 写时钟线 */ void MyI2C_W_SCL(uint8_t BitValue) { GPIO_WriteBit(I2CPORT, I2CSCL_PIN, (BitAction) BitValue); Delay_us(10); } /* * 写数据线 */ void MyI2C_W_SDA(uint8_t BitValue) { GPIO_WriteBit(I2CPORT, I2CSDA_PIN, (BitAction) BitValue);\ Delay_us(10); } /* * 读数据线 */ uint8_t MyI2C_R_SDA(void) { uint8_t BitValue; BitValue = GPIO_ReadInputDataBit(I2CPORT, I2CSDA_PIN); Delay_us(10); return BitValue; } /* * 起始条件 SCL高电平期间 SDA从高电平切换到低电平 */ void MyI2C_Start(void) { MyI2C_W_SDA(1); MyI2C_W_SCL(1); // SLC高电平 MyI2C_W_SDA(0); // SDA切换到低电平 MyI2C_W_SCL(0); // 为下一个信号做准备 } /* * 终止条件 SCL高电平期间 SDA从低电平切换到高电平 */ void MyI2C_Stop(void) { MyI2C_W_SDA(0); MyI2C_W_SCL(1); // 因传输在停止条件后终止,故不需将SLC拉低 MyI2C_W_SDA(1); } /* * 发送一个字节 SCL低电平间 主机将数据位依次放到SDA线上,然后释放SCL * 从机在SCL高电平期间读取数据位 * 接起始条件 */ void MyI2C_SendByte(uint8_t Byte) { uint8_t i; for(i=0; i<8; ++i) { MyI2C_W_SDA(Byte & (0x80 >> i)); // 主机放数据 MyI2C_W_SCL(1); // 主机释放SCL 从机读数据 MyI2C_W_SCL(0); // 主机下拉SCL 准备放数据 } } /* * 接收一个字节 SCL低电平间 从机将数据位依次放到SDA线上, 然后释放SCL * 主机在SCL高电平期间读取数据位 */ uint8_t MyI2C_ReceiveByte(void) { uint8_t Byte = 0x00; uint8_t i; MyI2C_W_SDA(1); // 主机释放SDA for(i=0; i<8; ++i) { MyI2C_W_SCL(1); // SCL高电平 if(MyI2C_R_SDA() == 1) Byte |= (0x80 >> i); MyI2C_W_SCL(0); } return Byte; } /* * 发送应答 0表示应答 1表示非应答 */ void MyI2C_SendAck(uint8_t AckBit) { MyI2C_W_SDA(AckBit); MyI2C_W_SCL(1); MyI2C_W_SCL(0); } /* * 接收应答 */ uint8_t MyI2C_ReceiveACK(void) { uint8_t AckBit; MyI2C_W_SDA(1); // 主机释放SDA MyI2C_W_SCL(1); AckBit = MyI2C_R_SDA(); MyI2C_W_SCL(0); return AckBit; }
#ifndef __MYI2C_H
#define __MYI2C_H
void MyI2C_Init(void);
void MyI2C_W_SCL(uint8_t BitValue);
void MyI2C_W_SDA(uint8_t BitValue);
uint8_t MyI2C_R_SDA(void);
void MyI2C_Start(void);
void MyI2C_Stop(void);
void MyI2C_SendByte(uint8_t Byte);
uint8_t MyI2C_ReceiveByte(void);
void MyI2C_SendAck(uint8_t AckBit);
uint8_t MyI2C_ReceiveACK(void);
#endif
#include "stm32f10x.h" #include "MyI2C.h" #include "MPU6050_REG.h" #define MPU_ADDRESS 0xD0 /* * 往指定地址写入指定数据 */ void MPU6050_WriteReg(uint8_t RegAddress, uint8_t Data) { // 起始条件 MyI2C_Start(); // 呼叫设备(MPU6050) MyI2C_SendByte(MPU_ADDRESS); // 接收应答 MyI2C_ReceiveACK(); // 寻找地址 MyI2C_SendByte(RegAddress); // 接收应答 MyI2C_ReceiveACK(); // 写入数据 MyI2C_SendByte(Data); // 接收应答 MyI2C_ReceiveACK(); // 终止条件 MyI2C_Stop(); } /* * 从指定地址读取数据 */ uint8_t MPU6050_ReadReg(uint8_t RegAddress) { uint8_t Data; // 起始条件 MyI2C_Start(); // 呼叫设备(MPU6050) MyI2C_SendByte(MPU_ADDRESS); // 接收应答 MyI2C_ReceiveACK(); // 寻找地址 MyI2C_SendByte(RegAddress); // 接收应答 MyI2C_ReceiveACK(); // 再次起始 MyI2C_Start(); MyI2C_SendByte(MPU_ADDRESS | 0x01); // 接收应答 MyI2C_ReceiveACK(); // 读取数据 Data = MyI2C_ReceiveByte(); // 发送应答 MyI2C_SendAck(1); // 终止条件 MyI2C_Stop(); return Data; } /* * 配置MPU6050 */ void MPU6050_Init(void) { // I2C初始化 MyI2C_Init(); MPU6050_WriteReg(PWR_MGMT_1, 0x01); MPU6050_WriteReg(PWR_MGMT_2, 0x00); MPU6050_WriteReg(SMPLRT_DIV, 0x09); MPU6050_WriteReg(CONFIG, 0x06); MPU6050_WriteReg(GYRO_CONFIG, 0x18); MPU6050_WriteReg(ACCEL_CONFIG, 0x18); } /* * 获取ID号 */ uint8_t MPU6050_GetID(void) { return MPU6050_ReadReg(WHO_AM_I); } /* * 获取MPU6050数据 */ void MPU6050_GetData(MPU6050_DataTypeDef * MPU_DataStructure) { uint16_t Data_H, Data_L; // 高位数据和低位数据 Data_H = MPU6050_ReadReg(ACCEL_XOUT_H); Data_L = MPU6050_ReadReg(ACCEL_XOUT_L); MPU_DataStructure->AccX=(Data_H<<8) | Data_L; Data_H = MPU6050_ReadReg(ACCEL_YOUT_H); Data_L = MPU6050_ReadReg(ACCEL_YOUT_L); MPU_DataStructure->AccY=(Data_H<<8) | Data_L; Data_H = MPU6050_ReadReg(ACCEL_ZOUT_H); Data_L = MPU6050_ReadReg(ACCEL_ZOUT_L); MPU_DataStructure->AccZ=(Data_H<<8) | Data_L; Data_H = MPU6050_ReadReg(GYRO_XOUT_H); Data_L = MPU6050_ReadReg(GYRO_XOUT_L); MPU_DataStructure->GyroX=(Data_H<<8) | Data_L; Data_H = MPU6050_ReadReg(GYRO_YOUT_H); Data_L = MPU6050_ReadReg(GYRO_YOUT_L); MPU_DataStructure->GyroY=(Data_H<<8) | Data_L; Data_H = MPU6050_ReadReg(GYRO_ZOUT_H); Data_L = MPU6050_ReadReg(GYRO_ZOUT_L); MPU_DataStructure->GyroZ=(Data_H<<8) | Data_L; }
#ifndef __MPU6050_H
#define __MPU6050_H
#include "MPU6050_REG.h"
void MPU6050_WriteReg(uint8_t RegAddress, uint8_t Data);
uint8_t MPU6050_ReadReg(uint8_t RegAddress);
void MPU6050_Init(void);
uint8_t MPU6050_GetID(void);
void MPU6050_GetData(MPU6050_DataTypeDef * MPU_DataStructure);
#endif
#ifndef __MPU6050_REG_H #define __MPU6050_REG_H // 寄存器地址 #define SMPLRT_DIV 0x19 #define CONFIG 0x1A #define GYRO_CONFIG 0x1B #define ACCEL_CONFIG 0x1C #define ACCEL_XOUT_H 0x3B #define ACCEL_XOUT_L 0x3C #define ACCEL_YOUT_H 0x3D #define ACCEL_YOUT_L 0x3E #define ACCEL_ZOUT_H 0x3F #define ACCEL_ZOUT_L 0x40 #define TEMP_OUT_H 0x41 #define TEMP_OUT_L 0x42 #define GYRO_XOUT_H 0x43 #define GYRO_XOUT_L 0x44 #define GYRO_YOUT_H 0x45 #define GYRO_YOUT_L 0x46 #define GYRO_ZOUT_H 0x47 #define GYRO_ZOUT_L 0x48 #define PWR_MGMT_1 0x6B #define PWR_MGMT_2 0x6C #define WHO_AM_I 0x75 /* * MPU6050数据结构体 */ typedef struct { int16_t AccX; int16_t AccY; int16_t AccZ; int16_t GyroX; int16_t GyroY; int16_t GyroZ; } MPU6050_DataTypeDef; #endif
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。