mpu6050对应i2c地址是什么_如何读取数据

mpu6050其实就是一个 i2c 器件,里面有很多寄存器(但是我们用到的只有几个),我们通过读写寄存器来操作这个芯片。所以首要问题就是 stm32 和 mpu6050 的 i2c 通信。
1、配置 stm32 (用i2c1:pb6——scl;pb7——sda) 1)时钟 rcc
rcc_apb2periphclockcmd(rcc_apb2periph_gpiob, enable);
rcc_apb1periphclockcmd(rcc_apb1periph_i2c1 , enable);
2)gpio 配置
gpio_initstructure.gpio_pin = gpio_pin_6 | gpio_pin_7;
gpio_initstructure.gpio_speed = gpio_speed_50mhz;
gpio_initstructure.gpio_mode = gpio_mode_af_od; //两个引脚都加 4.7k 上拉电阻
gpio_init(gpiob, &gpio_initstructure);
3)i2c 配置
void i2c_configuration(void)
{
i2c_inittypedef i2c_initstructure;
i2c_initstructure.i2c_mode = i2c_mode_i2c;
i2c_initstructure.i2c_dutycycle = i2c_dutycycle_2;
i2c_initstructure.i2c_ownaddress1 =0xc0; // stm32 的自身地址,不与从器件相同即可
i2c_initstructure.i2c_ack = i2c_ack_enable;
i2c_initstructure.i2c_acknowledgedaddress = i2c_acknowledgedaddress_7bit;
i2c_initstructure.i2c_clockspeed = 100000;
i2c_init(i2c1, &i2c_initstructure);
i2c_cmd(i2c1, enable);
}
至此,stm32 已配置完毕,其实不是那么难。
2、初始化 mpu6050 void mpu6050_initialize() //初始化过程 ,其实就是写 5个寄存器
{
mpu6050_i2c_bytewrite(0xd0,0x00,mpu6050_ra_pwr_mgmt_1); // reg107, 唤醒,8m内部时钟源
mpu6050_i2c_bytewrite(0xd0,0x07,mpu6050_ra_smplrt_div); //采用频率 1000
mpu6050_i2c_bytewrite(0xd0,0x06,mpu6050_ra_config);
mpu6050_i2c_bytewrite(0xd0,0x01,mpu6050_ra_accel_config); //加速度量程 2g
mpu6050_i2c_bytewrite(0xd0,0x18,mpu6050_ra_gyro_config); //角速度量程 2000度/s
}
注:0xd0 表示 mpu6050 的地址。我们知道 i2c从器件(在此当然是指 mpu6050)有 8 位的地址,前 7 位由 who am i 确定,第 8 位由 ad0 的电平决定。who am i 默认值是 0x68h(1101000b),ad0 接低电平,所以 mpu6050 的 i2c 地址是 0xd0h(11010000b)。
3、i2c 核心程序 ( 读/写) 1)写入寄存器
一次写操作分为几个步骤: 发送开始信号 -》 起始成功?(可能描述的不太准确) -》 发送 mpu6050 地址、状态(写)-》 写地址成功? -》 发送 mpu6050内部某个待写寄存器地址 -》 发送成功? -》 发送要写入的内容 -》 发送成功? -》 发送结束信号
总结:先写 mpu6050 地址,再写 寄存器地址,最后写 内容,且每次都要验证(应该和应答信号有关)。这就像寄快递一样,先写市县地址,再写街道地址,最后写门牌号。
再看下面的程序就会更容易理解一些。
void mpu6050_i2c_bytewrite(u8 slaveaddr, u8 pbuffer, u8 writeaddr)
{
/* send start condition */
i2c_generatestart(i2c1, enable); //发送开始信号
/* test on ev5 and clear it */
while(!i2c_checkevent(i2c1, i2c_event_master_mode_select));
/* send mpu6050 address for write */
i2c_send7bitaddress(i2c1, slaveaddr, i2c_direction_transmitter); // 发送 mpu6050 地址、状态(写)
/* test on ev6 and clear it */
while(!i2c_checkevent(i2c1, i2c_event_master_transmitter_mode_selected));
/* send the mpu6050‘s internal address to write to */
i2c_senddata(i2c1, writeaddr); //发送 mpu6050内部某个待写寄存器地址
/* test on ev8 and clear it */
while(!i2c_checkevent(i2c1, i2c_event_master_byte_transmitted));
/* send the byte to be written */
i2c_senddata(i2c1, pbuffer); //发送要写入的内容
/* test on ev8 and clear it */
while(!i2c_checkevent(i2c1, i2c_event_master_byte_transmitted));
/* send stop condition */
i2c_generatestop(i2c1, enable); //发送结束信号
}
2)读寄存器
因为 加速度值和角速度值都在寄存器里,所以必须读它才能获得数据。
附上程序
如:mpu6050_i2c_bufferread(0xd0, receive_data, mpu6050_ra_who_am_i, 1); //读 who_am_i 寄存器的值(0x68)
如:
void mpu6050_getrawaccelgyro(s16* accelgyro) //读加速度值 和 角速度值
{
u8 tmpbuffer[14],i;
mpu6050_i2c_bufferread(0xd0, tmpbuffer, mpu6050_ra_accel_xout_h, 14);
/* get acceleration */
for(i=0; i《3; i++)
accelgyro=((s16)((u16)tmpbuffer[2*i] 《《 8) + tmpbuffer[2*i+1]);
/* get angular rate */
for(i=4; i《7; i++) //在此跳过温度寄存器,不需要温度值
accelgyro[i-1]=((s16)((u16)tmpbuffer[2*i] 《《 8) + tmpbuffer[2*i+1]);
}
注:
#define mpu6050_ra_accel_xout_h 0x3b
#define mpu6050_ra_accel_xout_l 0x3c
#define mpu6050_ra_accel_yout_h 0x3d
#define mpu6050_ra_accel_yout_l 0x3e
#define mpu6050_ra_accel_zout_h 0x3f
#define mpu6050_ra_accel_zout_l 0x40
#define mpu6050_ra_temp_out_h 0x41
#define mpu6050_ra_temp_out_l 0x42
#define mpu6050_ra_gyro_xout_h 0x43
#define mpu6050_ra_gyro_xout_l 0x44
#define mpu6050_ra_gyro_yout_h 0x45
#define mpu6050_ra_gyro_yout_l 0x46
#define mpu6050_ra_gyro_zout_h 0x47
#define mpu6050_ra_gyro_zout_l 0x48
i2c 读核心程序:
void mpu6050_i2c_bufferread(u8 slaveaddr, u8* pbuffer, u8 readaddr, u16 numbytetoread)
{
/* while the bus is busy */
while(i2c_getflagstatus(i2c1, i2c_flag_busy));
/* send start condition */
i2c_generatestart(i2c1, enable);
/* test on ev5 and clear it */
while(!i2c_checkevent(i2c1, i2c_event_master_mode_select));
/* send mpu6050 address for write */
i2c_send7bitaddress(i2c1, slaveaddr, i2c_direction_transmitter);
/* test on ev6 and clear it */
while(!i2c_checkevent(i2c1, i2c_event_master_transmitter_mode_selected));
/* clear ev6 by setting again the pe bit */
i2c_cmd(i2c1, enable);
/* send the mpu6050’s internal address to write to */
i2c_senddata(i2c1, readaddr);
/* test on ev8 and clear it */
while(!i2c_checkevent(i2c1, i2c_event_master_byte_transmitted));
/* send strat condition a second time */
i2c_generatestart(i2c1, enable);
/* test on ev5 and clear it */
while(!i2c_checkevent(i2c1, i2c_event_master_mode_select));
/* send mpu6050 address for read */
i2c_send7bitaddress(i2c1, slaveaddr, i2c_direction_receiver);
/* test on ev6 and clear it */
while(!i2c_checkevent(i2c1, i2c_event_master_receiver_mode_selected));
/* while there is data to be read */
while(numbytetoread)
{
if(numbytetoread == 1)
{
/* disable acknowledgement */
i2c_acknowledgeconfig(i2c1, disable);
/* send stop condition */
i2c_generatestop(i2c1, enable);
}
/* test on ev7 and clear it */
if(i2c_checkevent(i2c1, i2c_event_master_byte_received))
{
/* read a byte from the mpu6050 */
*pbuffer = i2c_receivedata(i2c1);
/* point to the next location where the byte read will be saved */
pbuffer++;
/* decrement the read bytes counter */
numbytetoread--;
}
}
/* enable acknowledgement to be ready for another reception */
i2c_acknowledgeconfig(i2c1, enable);
}
最后,把六个值 printf 出来就行。

CY8C4014LQI-422 ARM微控制器简介
SD-WAN对于制造业物联网的重要性
特斯拉中国造7月出口突破2万辆 Model3出口量再创新高
工信部刘烈宏提出三点建议,推动信息通信业加速发展
光伏太阳能发电原理
mpu6050对应i2c地址是什么_如何读取数据
惠普HP8156A 光学衰减器
三分频音箱的中音为什么不响?
荣湃半桥驱动芯片的应用场景有哪些?
单片机编程技巧之重用外设驱动代码
微雪电子双模蓝牙串口评估套件介绍
Admix收购英国VR媒体VRFocus VRFocus将保留其编辑独立性
锤子坚果Pro发布会已结束:坚果Pro主打功耗、双摄、续航,业界最帅价格感人1499!
你们知道电解水制氢经济性难题怎么解吗?
关于LED显示屏的尺寸,它是否能够随意放大
土壤养分速测仪与传统方法的对比,它有什么优势
海报寓意全民金属时代!小米或发布Note4和红米4两款新机
高稳定性的压力变送器的生产方法
海信召开彩墨屏阅读手机全球云首发发布会
什么是区块链资产质押贷款系统