OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 14430|回复: 7

I2C读数据问题 MPU9250数据问题

[复制链接]

8

主题

28

帖子

0

精华

初级会员

Rank: 2

积分
81
金钱
81
注册时间
2014-8-12
在线时间
0 小时
发表于 2014-11-27 15:53:31 | 显示全部楼层 |阅读模式
5金钱
我用的是模拟IO口的I2C,代码如下:
[mw_shl_code=c,true]//----------------------------------------------------------------------| // Funtion name: IIC_Config.c | // Funtion:模拟I2C,PB.06(SCL) PB.07(SDA) | // Writer: Fish | // School: Shenzhen University | // Date: 2014.11.25 | //----------------------------------------------------------------------| #include "IIC_Config.h" char test=0; //************************************ /*模拟i2c端口输入输出定义*/ #define SCL_H GPIOB->BSRR = GPIO_Pin_6 #define SCL_L GPIOB->BRR = GPIO_Pin_6 #define SDA_H GPIOB->BSRR = GPIO_Pin_7 #define SDA_L GPIOB->BRR = GPIO_Pin_7 #define SCL_read GPIOB->IDR & GPIO_Pin_6 #define SDA_read GPIOB->IDR & GPIO_Pin_7 /******************************************************************************* * Function Name : I2C_GPIO_Config * Description : Configration Simulation IIC GPIO * Input : None * Output : None * Return : None ****************************************************************************** */ void I2C_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; GPIO_Init(GPIOB, &GPIO_InitStructure); } /******************************************************************************* * Function Name : I2C_delay * Description : Simulation IIC Timing series delay * Input : None * Output : None * Return : None ****************************************************************************** */ void I2C_delay(void) { u8 i=30; //速度可优化,最小为5 while(i) { i--; } } /******************************************************************************* * Function Name : I2C_Start * Description : Master Start Simulation IIC Communication * Input : None * Output : None * Return : Wheather Start ****************************************************************************** */ bool I2C_Start(void) { SDA_H; SCL_H; I2C_delay(); if(!SDA_read)return FALSE; //SDA为低电平总线忙,退出 SDA_L; I2C_delay(); if(SDA_read) return FALSE; //SDA为高电平总线出错,退出 SDA_L; I2C_delay(); return TRUE; } /******************************************************************************* * Function Name : I2C_Stop * Description : Master Stop Simulation IIC Communication * Input : None * Output : None * Return : None ****************************************************************************** */ void I2C_Stop(void) { SCL_L; I2C_delay(); SDA_L; I2C_delay(); SCL_H; I2C_delay(); SDA_H; I2C_delay(); } /******************************************************************************* * Function Name : I2C_Ack * Description : Master Send Acknowledge Single * Input : None * Output : None * Return : None ****************************************************************************** */ void I2C_Ack(void) { SCL_L; I2C_delay(); SDA_L; I2C_delay(); SCL_H; I2C_delay(); SCL_L; I2C_delay(); } /******************************************************************************* * Function Name : I2C_NoAck * Description : Master Send No Acknowledge Single * Input : None * Output : None * Return : None ****************************************************************************** */ void I2C_NoAck(void) { SCL_L; I2C_delay(); SDA_H; I2C_delay(); SCL_H; I2C_delay(); SCL_L; I2C_delay(); } /******************************************************************************* * Function Name : I2C_WaitAck * Description : Master Reserive Slave Acknowledge Single * Input : None * Output : None * Return : Wheather Reserive Slave Acknowledge Single ****************************************************************************** */ bool I2C_WaitAck(void) //返回:1有ack,0无ack { SCL_L; I2C_delay(); SDA_H; I2C_delay(); SCL_H; I2C_delay(); if(SDA_read) { SCL_L; I2C_delay(); return FALSE; } SCL_L; I2C_delay(); return TRUE; } /******************************************************************************* * Function Name : I2C_SendByte * Description : Master Send a Byte to Slave * Input : Will Send Date * Output : None * Return : None ****************************************************************************** */ void I2C_SendByte(u8 SendByte) //数据从高位到低位 { u8 i=8; while(i--) { SCL_L; I2C_delay(); if(SendByte&0x80) SDA_H; else SDA_L; SendByte<<=1; I2C_delay(); SCL_H; I2C_delay(); } SCL_L; } /******************************************************************************* * Function Name : I2C_RadeByte * Description : Master Reserive a Byte From Slave * Input : None * Output : None * Return : Date From Slave ****************************************************************************** */ unsigned char I2C_RadeByte(void) //数据从高位到低位 { u8 i=8; u8 ReceiveByte=0; SDA_H; while(i--) { ReceiveByte<<=1; SCL_L; I2C_delay(); SCL_H; I2C_delay(); if(SDA_read) { ReceiveByte|=0x01; } } SCL_L; return ReceiveByte; } /*********************************************************************************/ //单字节写入******************************************* bool Single_Write(unsigned char SlaveAddress,unsigned char REG_Address,unsigned char REG_data) //void { if(!I2C_Start())return FALSE; I2C_SendByte(SlaveAddress); //发送设备地址+写信号 //I2C_SendByte(((REG_Address & 0x0700) >>7) | SlaveAddress & 0xFFFE);//设置高起始地址+器件地址 if(!I2C_WaitAck()){I2C_Stop(); return FALSE;} I2C_SendByte(REG_Address ); //设置低起始地址 I2C_WaitAck(); I2C_SendByte(REG_data); I2C_WaitAck(); I2C_Stop(); Delay_ms(5); return TRUE; } //单字节读取***************************************** unsigned char Single_Read(unsigned char SlaveAddress,unsigned char REG_Address) { unsigned char REG_data; if(!I2C_Start())return FALSE; I2C_SendByte(SlaveAddress); //I2C_SendByte(((REG_Address & 0x0700) >>7) | REG_Address & 0xFFFE);//设置高起始地址+器件地址 if(!I2C_WaitAck()){I2C_Stop();test=1; return FALSE;} I2C_SendByte((u8) REG_Address); //设置低起始地址 I2C_WaitAck(); I2C_Start(); I2C_SendByte(SlaveAddress+1); I2C_WaitAck(); REG_data= I2C_RadeByte(); I2C_NoAck(); I2C_Stop(); //return TRUE; return REG_data; } [/mw_shl_code] [mw_shl_code=c,true][/mw_shl_code]
代码是参考网友的,驱动的芯片为MPU9250。
但接上芯片后,数据有时可以读,有时不行,不知代码有何问题?

还有使用MPU9250的时候可以读回ak8963磁力计的地址和WHOAMI,但无法读取数据寄存器的值,有人遇到过这样的问题吗?有的话解决方法是什么?

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

88

主题

7377

帖子

5

精华

资深版主

Rank: 8Rank: 8

积分
14980
金钱
14980
注册时间
2013-11-13
在线时间
1823 小时
发表于 2014-11-27 16:42:16 | 显示全部楼层
MPU9250读取AK8963的时候,一定要设置为单次读取,要不然读取不出来!
开往春天的手扶拖拉机
回复

使用道具 举报

8

主题

28

帖子

0

精华

初级会员

Rank: 2

积分
81
金钱
81
注册时间
2014-8-12
在线时间
0 小时
 楼主| 发表于 2014-11-28 14:59:17 | 显示全部楼层
回复【2楼】zuozhongkai:
---------------------------------
之前其实也可以读出数值的,但不稳定,不过其他六轴的数据非常稳定,确定不是I2C的问题,可能是硬件的问题,还有,即使磁力计数据读出来了,最大值也只有400,可手册中的取值范围是正负32767。感觉很差异,这个问题你遇到过吗?怎么解决?
还有,为什么要设置为单此读取,麻烦你解答我一下,谢谢。
回复

使用道具 举报

11

主题

96

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
341
金钱
341
注册时间
2014-6-16
在线时间
43 小时
发表于 2015-5-1 18:05:31 | 显示全部楼层
你好,你试过用SPI读取MPU9250的磁力计数据吗?我再这块遇到问题了,不知道怎么解决?
回复

使用道具 举报

26

主题

193

帖子

8

精华

金牌会员

Rank: 6Rank: 6

积分
1800
金钱
1800
注册时间
2012-8-23
在线时间
57 小时
发表于 2016-9-14 21:21:14 | 显示全部楼层
1,可以连续读,但是每次都要读状态寄存器,否则数据不会更新
2,地磁数据原本就比较小,400左右正常
回复

使用道具 举报

0

主题

34

帖子

0

精华

初级会员

Rank: 2

积分
179
金钱
179
注册时间
2017-2-2
在线时间
24 小时
发表于 2018-1-19 19:24:58 | 显示全部楼层
beyond696 发表于 2016-9-14 21:21
1,可以连续读,但是每次都要读状态寄存器,否则数据不会更新
2,地磁数据原本就比较小,400左右正常

我也是只能单次读,当初始化设置成连续读时也没有用,每次读还得再设置读取方式,不知道什么原因
回复

使用道具 举报

2

主题

685

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3448
金钱
3448
注册时间
2017-7-4
在线时间
869 小时
发表于 2018-1-20 11:00:00 | 显示全部楼层
诸葛景云 发表于 2018-1-19 19:24
我也是只能单次读,当初始化设置成连续读时也没有用,每次读还得再设置读取方式,不知道什么原因

模拟i2c:http://blog.csdn.net/qq_20553613/article/details/78878211
回复

使用道具 举报

6

主题

32

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
210
金钱
210
注册时间
2019-4-3
在线时间
50 小时
发表于 2019-5-23 17:18:20 | 显示全部楼层
AK8963连续读必须得同时读取AK8963_RA_ST2这个地址的寄存器,才会刷新三轴的值,不然值一直是一样的,但是我现在也出现了有时候能读值,有时候全为0的问题,不知道有没有解决方案
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-26 01:28

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表