OpenEdv-开源电子网

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

STM32 使用模拟IIC读取MPU6050 出现如下图所示的数据 不知道给怎么解决啊?求帮助,弄了好几天了。

[复制链接]

16

主题

56

帖子

0

精华

初级会员

Rank: 2

积分
140
金钱
140
注册时间
2013-8-10
在线时间
0 小时
发表于 2014-7-31 09:37:37 | 显示全部楼层 |阅读模式
5金钱




下面是我的软件部分
void IIC_Start(void)
{
SDA_OUT();     //sda线输出
IIC_SDA=1;    
IIC_SCL=1;
delay_us(5);
  IIC_SDA=0;//START:when CLK is high,DATA change form high to low 
delay_us(5);
IIC_SCL=0;//钳住I2C总线,准备发送或接收数据 
}  
//产生IIC停止信号
void IIC_Stop(void)
{
SDA_OUT();//sda线输出
IIC_SCL=0;
IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
  delay_us(5);
IIC_SCL=1; 
IIC_SDA=1;//发送I2C总线结束信号
delay_us(5);  
}

//等待应答信号到来
//返回值:1,接收应答失败
//        0,接收应答成功
u8 IIC_Wait_Ack(void)
{
u8 ucErrTime=0;
SDA_IN();      //SDA设置为输入  
IIC_SDA=1;delay_us(1);   
IIC_SCL=1;delay_us(1);  
while(READ_SDA)
{
ucErrTime++;
if(ucErrTime>250)
{
IIC_Stop();
return 1;
}
}
IIC_SCL=0;//时钟输出0   
return 0;  


//产生ACK应答
void IIC_Ack(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=0;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
//不产生ACK应答    
void IIC_NAck(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=1;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}     
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答  
void IIC_Send_Byte(u8 txd)
{                        
    u8 t;   
SDA_OUT();    
    IIC_SCL=0;//拉低时钟开始数据传输
    for(t=0;t<8;t++)
    {              
        IIC_SDA=(txd&0x80)>>7;
        txd<<=1;  
// delay_us(2);   //对TEA5767这三个延时都是必须的
// IIC_SCL=1;
// delay_us(2); 
// IIC_SCL=0;
// delay_us(2);
delay_us(5);   
IIC_SCL=1;
delay_us(5); 
IIC_SCL=0;
delay_us(5);
    }  
}    
////读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
//u8 IIC_Read_Byte(void)
//{
// unsigned char i,receive=0;
// SDA_IN();//SDA设置为输入
//    for(i=0;i<8;i++ )
// {
//        IIC_SCL=0; 
//        delay_us(2);
// IIC_SCL=1;
//        receive<<=1;
//        if(READ_SDA)receive++;   
// delay_us(1); 
//    }  
////    if (!ack)
////        IIC_NAck();//发送nACK
////    else
////        IIC_Ack(); //发送ACK   
//    return receive;
//}

//读一个字节,ack=1时,发送ACK,ack=0,发送NAck
u8 IIC_Read_Byte(u8 ack)
{
        unsigned char i,receive=0;
        SDA_IN();//数据线设置为输入
        for(i=0;i<8;i++)
        {
                IIC_SCL=0;
                delay_us(2);
                IIC_SCL=1;
                receive<<=1;
                if(READ_SDA)receive++;
                delay_us(1);
        }
        if(!ack)
         IIC_NAck();
        else
         IIC_Ack();
        return receive;
}

//初始化IIC
void IIC_Init(void)
{     
  RCC->APB2ENR|=1<<3;//先使能外设IO PORTB时钟  
GPIOB->CRH&=0XFFFF00FF;//PB10/11 推挽输出
GPIOB->CRH|=0X00003300;   
GPIOB->ODR|=3<<10;     //PB10,11 输出高
 
IIC_SCL=1;
IIC_SDA=1;
}

//**************************************
//向I2C设备写入一个字节数据
//**************************************
void Single_WriteI2C(u8 REG_Address,u8 REG_data)
{
    IIC_Start();                  //起始信号
    IIC_Send_Byte(SlaveAddress);   //发送设备地址+写信号
IIC_Wait_Ack();
    IIC_Send_Byte(REG_Address);    //内部寄存器地址,
IIC_Wait_Ack();
    IIC_Send_Byte(REG_data);       //内部寄存器数据,
IIC_Wait_Ack();
    IIC_Stop();                   //发送停止信号
}

//**************************************
//从I2C设备读取一个字节数据
//**************************************
u8 Single_ReadI2C(u8 REG_Address)
{
u8 REG_data;
IIC_Start();                   //起始信号
IIC_Send_Byte(SlaveAddress);    //发送设备地址+写信号
IIC_Wait_Ack();

IIC_Send_Byte(REG_Address);     //发送存储单元地址,从0开始
IIC_Wait_Ack();

IIC_Start();                   //起始信号

IIC_Send_Byte(SlaveAddress+1);  //发送设备地址+读信号
IIC_Wait_Ack();

REG_data=IIC_Read_Byte(1);       //读出寄存器数据
/***不屏蔽就会有错误***/
// IIC_Ack();                    //发送应答信号    
delay_us(2);           
IIC_Stop();                    //停止信号
return REG_data;
}


//**************************************
//合成数据
//**************************************
int GetData(u8 REG_Address)
{
char H,L;
H=Single_ReadI2C(REG_Address);
L=Single_ReadI2C(REG_Address+1);
return (H<<8)+L;   //合成数据
}


/**************************实现函数********************************************
*函数原型: unsigned char MPU6050_is_DRY(void)
*功  能:    检查 MPU6050的中断引脚,测试是否完成转换
返回 1  转换完成
0 数据寄存器还没有更新
*******************************************************************************/
unsigned char MPU6050_is_DRY(void)
{
    if(GPIO_ReadInputDataBit(GPIOF,GPIO_Pin_6)==Bit_RESET){
 return 1;
}
else return 0;
}

//**************************************
//初始化MPU6050
//**************************************
void InitMPU6050(void)
{
Single_WriteI2C(PWR_MGMT_1, 0x80); //复位
delay_ms(30);
Single_WriteI2C(PWR_MGMT_1, 0x00); //解除休眠状态
Single_WriteI2C(SMPLRT_DIV, 0x07);   //采样率设置
Single_WriteI2C(CONFIG, 0x06);       //低通滤波
Single_WriteI2C(GYRO_CONFIG, 0x18);      //陀螺仪量程设置
Single_WriteI2C(ACCEL_CONFIG, 0x01);    //加速度量程设置
// Single_WriteI2C(MPU6050_RA_INT_PIN_CFG, 0x32);    //中断INT设置
// Single_WriteI2C(MPU6050_RA_INT_ENABLE, 0x01);    //中断INT设置
}


现在这个程序是刚刚合成的数据  没有进行处理,就是很不稳定 ,会出现有0的现象,网上说数据为0,可能是IIC协议没有配置好,但是我的问题是可以读出一段数据,这个是从51的程序移植过来的 。  还有就是如果我用中断的话,MPU6050的初始化中断配置正不正确?

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

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-7-31 23:48:19 | 显示全部楼层
论坛有网友发过MPU6050的代码,楼主参考下他们的了。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

4

主题

200

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
236
金钱
236
注册时间
2012-12-19
在线时间
0 小时
发表于 2014-8-1 08:39:31 | 显示全部楼层
注意中断引脚的配置哦,我记得好像是下降沿。你完全可以先用其他人的程序然后再改改。
目前在玩STM32,BBB,RPi
回复

使用道具 举报

16

主题

56

帖子

0

精华

初级会员

Rank: 2

积分
140
金钱
140
注册时间
2013-8-10
在线时间
0 小时
 楼主| 发表于 2014-8-1 09:35:49 | 显示全部楼层
回复【3楼】w0rmis20:
---------------------------------问题已经解决了  VCC给5V电压,不是在网上下载的资料说3.3V
回复

使用道具 举报

4

主题

200

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
236
金钱
236
注册时间
2012-12-19
在线时间
0 小时
发表于 2014-8-1 10:16:50 | 显示全部楼层
回复【4楼】Naga1991:
---------------------------------
看来你用的是带电压转换芯片的版本
目前在玩STM32,BBB,RPi
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-7-4 16:11

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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