MPU6050与51单片机串口通信,串口助手显示波特率为9600,数据格式为8位数据位,无校验位,1位停止位。
时间: 2023-05-28 15:08:13 浏览: 217
以下是MPU6050与51单片机串口通信的代码:
```c
#include <reg51.h>
#define MPU6050_ADDR 0xD0 // MPU6050的I2C地址
#define MPU6050_SMPLRT_DIV 0x19
#define MPU6050_CONFIG 0x1A
#define MPU6050_GYRO_CONFIG 0x1B
#define MPU6050_ACCEL_CONFIG 0x1C
#define MPU6050_ACCEL_XOUT_H 0x3B
#define MPU6050_ACCEL_XOUT_L 0x3C
#define MPU6050_ACCEL_YOUT_H 0x3D
#define MPU6050_ACCEL_YOUT_L 0x3E
#define MPU6050_ACCEL_ZOUT_H 0x3F
#define MPU6050_ACCEL_ZOUT_L 0x40
#define MPU6050_TEMP_OUT_H 0x41
#define MPU6050_TEMP_OUT_L 0x42
#define MPU6050_GYRO_XOUT_H 0x43
#define MPU6050_GYRO_XOUT_L 0x44
#define MPU6050_GYRO_YOUT_H 0x45
#define MPU6050_GYRO_YOUT_L 0x46
#define MPU6050_GYRO_ZOUT_H 0x47
#define MPU6050_GYRO_ZOUT_L 0x48
sbit SDA = P1^1;
sbit SCL = P1^0;
void delay(unsigned int i)
{
while(i--);
}
void i2c_start()
{
SDA = 1;
SCL = 1;
delay(10);
SDA = 0;
delay(10);
SCL = 0;
delay(10);
}
void i2c_stop()
{
SDA = 0;
SCL = 1;
delay(10);
SDA = 1;
delay(10);
}
void i2c_send_ack(bit ack)
{
SDA = !ack;
SCL = 1;
delay(10);
SCL = 0;
delay(10);
SDA = 1;
delay(10);
}
bit i2c_recv_ack()
{
SCL = 1;
delay(10);
bit ack = SDA;
SCL = 0;
delay(10);
return ack;
}
void i2c_send_byte(unsigned char dat)
{
for(int i=0; i<8; i++)
{
SDA = (dat & 0x80) ? 1 : 0;
dat <<= 1;
SCL = 1;
delay(10);
SCL = 0;
delay(10);
}
i2c_recv_ack();
}
unsigned char i2c_recv_byte()
{
unsigned char dat = 0;
SDA = 1;
for(int i=0; i<8; i++)
{
SCL = 1;
delay(10);
dat <<= 1;
dat |= SDA;
SCL = 0;
delay(10);
}
return dat;
}
void mpu6050_write_byte(unsigned char addr, unsigned char dat)
{
i2c_start();
i2c_send_byte(MPU6050_ADDR);
i2c_recv_ack();
i2c_send_byte(addr);
i2c_recv_ack();
i2c_send_byte(dat);
i2c_recv_ack();
i2c_stop();
}
unsigned char mpu6050_read_byte(unsigned char addr)
{
unsigned char dat = 0;
i2c_start();
i2c_send_byte(MPU6050_ADDR);
i2c_recv_ack();
i2c_send_byte(addr);
i2c_recv_ack();
i2c_start();
i2c_send_byte(MPU6050_ADDR | 0x01);
i2c_recv_ack();
dat = i2c_recv_byte();
i2c_send_ack(0);
i2c_stop();
return dat;
}
void mpu6050_init()
{
mpu6050_write_byte(MPU6050_SMPLRT_DIV, 0x07); // 陀螺仪采样率 = 8kHz / (7+1) = 1kHz
mpu6050_write_byte(MPU6050_CONFIG, 0x06); // 陀螺仪低通滤波器带宽 = 5Hz
mpu6050_write_byte(MPU6050_GYRO_CONFIG, 0x18); // 陀螺仪量程 = ±2000dps
mpu6050_write_byte(MPU6050_ACCEL_CONFIG, 0x01); // 加速度计量程 = ±4g
}
void main()
{
TMOD = 0x20; // 设置定时器1为模式2
TH1 = 0xfd; // 波特率为9600
TL1 = 0xfd;
SCON = 0x50; // 8位数据位,无校验位,1位停止位
TR1 = 1; // 启动定时器1
PCON = 0x00; // 不使用节能模式
mpu6050_init();
while(1)
{
int accel_x, accel_y, accel_z, gyro_x, gyro_y, gyro_z;
accel_x = (mpu6050_read_byte(MPU6050_ACCEL_XOUT_H) << 8) | mpu6050_read_byte(MPU6050_ACCEL_XOUT_L);
accel_y = (mpu6050_read_byte(MPU6050_ACCEL_YOUT_H) << 8) | mpu6050_read_byte(MPU6050_ACCEL_YOUT_L);
accel_z = (mpu6050_read_byte(MPU6050_ACCEL_ZOUT_H) << 8) | mpu6050_read_byte(MPU6050_ACCEL_ZOUT_L);
gyro_x = (mpu6050_read_byte(MPU6050_GYRO_XOUT_H) << 8) | mpu6050_read_byte(MPU6050_GYRO_XOUT_L);
gyro_y = (mpu6050_read_byte(MPU6050_GYRO_YOUT_H) << 8) | mpu6050_read_byte(MPU6050_GYRO_YOUT_L);
gyro_z = (mpu6050_read_byte(MPU6050_GYRO_ZOUT_H) << 8) | mpu6050_read_byte(MPU6050_GYRO_ZOUT_L);
printf("accel_x=%d, accel_y=%d, accel_z=%d, gyro_x=%d, gyro_y=%d, gyro_z=%d\n", accel_x, accel_y, accel_z, gyro_x, gyro_y, gyro_z);
delay(1000);
}
}
```
在上面的代码中,我们通过i2c_start、i2c_stop、i2c_send_byte、i2c_recv_byte等函数来实现I2C通信。mpu6050_write_byte和mpu6050_read_byte函数分别用于向MPU6050写入数据和读取数据。mpu6050_init函数用于初始化MPU6050。
在主函数中,我们使用printf函数来将MPU6050的加速度计和陀螺仪数据通过串口输出到PC上。注意,由于51单片机的串口波特率是9600,因此我们需要在PC端的串口助手中设置波特率为9600,并且数据格式为8位数据位,无校验位,1位停止位。
阅读全文