打印
[AVR单片机]

有谁用ICCAVR写过MPU6050的程序

[复制链接]
3402|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
一群群的过|  楼主 | 2013-10-14 10:37 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
一群群的过|  楼主 | 2013-10-14 10:38 | 只看该作者
#define SDA_1  PORTC|= (1<<2)
#define SDA_0  PORTC&=~(1<<2)
#define SCL_1  PORTC|= (1<<1)
#define SCL_0  PORTC&=~(1<<1)

void I2C_Init(void)
{
    DDRC|=1<<1;
        DDRC|=1<<2;
        SCL_1;
    delay_us(20);
    SDA_1;
    delay_us(20);
}

void I2C_Start(void)//起始信号
{
  DDRC|=1<<1;              //PC1 SCL时钟打开
  DDRC|=1<<2;              //PC2 SDA时钟打开
  SDA_1;//SDA=1;
  SCL_1;//SCL=1;
  delay_us(20);
  SDA_0;//SDA=0
  delay_us(20);
  SCL_0;//SCL=0  
}

void I2C_Stop(void)//停止信号
{
  DDRC|=1<<1;              //PC1 SCL时钟打开
  DDRC|=1<<2;              //PC2 SDA时钟打开
  SDA_0;//SDA=0
  SCL_1;//SCL=1
  delay_us(20);
  SDA_1;//SDA=1  
  delay_us(20);
}

void I2C_SendACK(void)
{
    DDRC|=1<<1;              //PC1 SCL时钟打开
    DDRC|=1<<2;              //PC2 SDA时钟打开
    SDA_1;                  //写应答信号
    SCL_1;                    //拉高时钟线
    delay_us(20);                 //延时
    SCL_0;                    //拉低时钟线
    delay_us(20);
}

u8 I2C_RecvACK(void)
{
    u8 ack=0;
        DDRC|=1<<1;              //PC1 SCL时钟打开
    DDRC&=~(1<<2);              //PC2 SDA时钟打开
        SCL_1;                    //拉高时钟线
    delay_us(20);
        if(PINC&(1<<2))
    ack=1;                   //读应答信号
        else ack=0;
    SCL_0;                    //拉低时钟线
    delay_us(20);
    return ack;
}

void I2C_SendByte(u8 data)
{
    u8 i;
        DDRC|=1<<1;              //PC1 SCL时钟打开
    DDRC|=1<<2;              //PC2 SDA时钟打开
    for (i=0;i<8;i++)         //8位计数器
    {
        data=data<<1;              //移出数据的最高位
                if((data&0x80)>>7==1)
        SDA_1;               //送数据口
                else SDA_0;
        SCL_1;                //拉高时钟线
        delay_us(20);
        SCL_0;                //拉低时钟线
        delay_us(20);
    }
    I2C_RecvACK();
}

u8 I2C_RecvByte(void)
{
    u8 i;
    u8 data = 0;
        DDRC|=1<<1;              //PC1 SCL时钟打开
    DDRC&=~(1<<2);              //PC2 SDA时钟打开
    SDA_1;                    //使能内部上拉,准备读取数据
    for(i=0; i<8; i++)         //8位计数器
    {
        data=data<<1;
        SCL_1;                //拉高时钟线
        delay_us(20);             //延时
        if(PINC&(1<<2))             //读数据   
                data|=0x01;
                else data|=0x00;            
        SCL_0;                //拉低时钟线
        delay_us(20);             //延时
    }
    return data;
}

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

//从I2C设备读取一个字节数据
u8 Single_ReadI2C(u8 REG_Address)
{
        u8 REG_data;
        I2C_Start();                   //起始信号
        I2C_SendByte(SlaveAddress);    //发送设备地址+写信号
        I2C_SendByte(REG_Address);     //发送存储单元地址,从0开始       
        I2C_Start();                   //起始信号
        I2C_SendByte(SlaveAddress+1);  //发送设备地址+读信号
        REG_data=I2C_RecvByte();       //读出寄存器数据
        I2C_SendACK();                //接收应答信号
        I2C_Stop();                    //停止信号
        return REG_data;
}

//初始化MPU6050
void InitMPU6050(void)
{
        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);
}

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

void main(void)
{
  u16 temp=0x0000;
  uart0_init();
  I2C_Init();
  InitMPU6050();        //初始化MPU6050
  delay_us(200);
  while(1)
  {
   temp=GetData(GYRO_XOUT_H);        //显示X轴角速度
   //temp=GetData(WHO_AM_I);        //
   USART_Transmit0((u8)temp&0xff00);
   USART_Transmit0((u8)temp&0x00ff);
   //USART_Transmit0(0xFF);
   delay_ms(400);
  }
}

使用特权

评论回复
板凳
一群群的过|  楼主 | 2013-10-14 10:39 | 只看该作者
要是知道MPU6050模块的,还想问下,模块引出的几个引脚,AD0,INT在使用时要接吗?接的话怎么接?

使用特权

评论回复
地板
qin552011373| | 2013-10-15 06:23 | 只看该作者
大概看了一下,MPU6050在百度上资料比较多,你可以先收索一下datasheet,看资源那么多,也不像是找不到datasheet的模块,仔细看一下datasheet先

使用特权

评论回复
5
一群群的过|  楼主 | 2013-10-15 09:24 | 只看该作者
qin552011373 发表于 2013-10-15 06:23
大概看了一下,MPU6050在百度上资料比较多,你可以先收索一下datasheet,看资源那么多,也不像是找不到data ...

谢谢,我这几天一直在看,但是连设备ID都读不出来,所以我觉得是I2C出问题,但改了不下6种,还是没办法解决

使用特权

评论回复
6
qin552011373| | 2013-10-15 09:27 | 只看该作者
一群群的过 发表于 2013-10-15 09:24
谢谢,我这几天一直在看,但是连设备ID都读不出来,所以我觉得是I2C出问题,但改了不下6种,还是没办法解 ...

最好是自己写一下,然后就会明白了,做技术不能用感觉,要清晰的知道问题所在

使用特权

评论回复
7
一群群的过|  楼主 | 2013-10-15 09:53 | 只看该作者
I2C的程序我写了多遍,用示波器也看了,没问题。想问下,我用PC口来模拟的,外部I2C器件已经4.7K上拉了,我的口子还要加上拉吗?我口子现在10K下拉,因为之前做一个东西,不下拉不行。会影响吗?

使用特权

评论回复
8
一群群的过|  楼主 | 2013-10-17 09:46 | 只看该作者
谢谢各位,数据已经可以读出,问题是之前怕板子上的10K下拉电阻会影响I2C的标准4.7K上拉(已经在MPU6050的两线上加了4.7K上拉),所以没加下拉电阻,在PC口的输出上,结果证明只是我自己想多了,是要加下拉电阻的,AVR我刚接触不久,请资深前辈指导下这是为什么?

使用特权

评论回复
9
ele_diy| | 2014-2-25 19:21 | 只看该作者
请问一下,我的问题也是和你一样,,看了你的贴子说“所以没加下拉电阻,在PC口的输出上”不知是什意思啊?这样PC口的SDA和SCL分别各加了两个10K下拉电阻了吗???不知前辈可否画个图来看看具体怎么连接啊?很感谢!!!

使用特权

评论回复
10
ele_diy| | 2014-2-25 19:23 | 只看该作者
一群群的过 发表于 2013-10-17 09:46
谢谢各位,数据已经可以读出,问题是之前怕板子上的10K下拉电阻会影响I2C的标准4.7K上拉(已经在MPU6050的 ...

请问一下,我的问题也是和你一样,,看了你的贴子说“所以没加下拉电阻,在PC口的输出上”不知是什意思啊?这样PC口的SDA和SCL分别各加了两个10K下拉电阻了吗???不知前辈可否画个图来看看具体怎么连接啊?很感谢!!!

使用特权

评论回复
11
龙的腾飞| | 2015-5-31 20:09 | 只看该作者
好东西,感谢感谢

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

7

主题

23

帖子

0

粉丝