OpenEdv-开源电子网

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

我用软件模拟IIC和MPU6050通讯可怎么也不成功

[复制链接]

3

主题

11

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2020-5-14
在线时间
11 小时
发表于 2020-5-22 16:51:26 | 显示全部楼层 |阅读模式
5金钱
真的十分困扰,我自以为对IIC时序非常理解,在初始化MPU6050函数里面加入了返回值,如果得到了正确的MPU6050地址,则控制LED1亮起来,可是无论如何都不行.希望大神能给看看是哪里有问题,如果能成功解决问题,小弟愿意奉上红包表示感谢//延时函数
void IIC_Delay(void)
{
        delay_us(2);
}
//初始化IO口
void SIMIIC_Init(void)
{
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
       
        GPIO_InitTypeDef  GPIO_InitS;
        GPIO_InitS.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11;
        GPIO_InitS.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_InitS.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB,&GPIO_InitS);
        GPIO_SetBits(GPIOB,GPIO_Pin_10|GPIO_Pin_11);       
}
//IIC 起始和结束
void IIC_Start(void)
{
        IIC_SDA_OUT();
        IIC_SCL = 1;
        IIC_SDA_WRITE = 1;
        IIC_Delay();
        IIC_SDA_WRITE = 0;
        IIC_Delay();
        IIC_SCL = 0;
}

void IIC_Stop(void)
{
        IIC_SDA_OUT();
        IIC_SCL = 0;
        IIC_SDA_WRITE = 0;
        IIC_Delay();
        IIC_SCL = 1;
        IIC_SDA_WRITE = 1;
        IIC_Delay();
}


//主机应答

void IIC_ACK(void)
{
        IIC_SDA_OUT();
        IIC_SCL = 0;
        IIC_SDA_WRITE = 0;
        IIC_Delay();
        IIC_SCL = 1;
        IIC_Delay();
        IIC_SCL = 0;
}
//不产生应答信号
void IIC_NAck(void)
{
        IIC_SDA_OUT();
        IIC_SCL = 0;
        IIC_SDA_WRITE = 1;
        IIC_Delay();
        IIC_SCL = 1;
        IIC_Delay();
        IIC_SCL = 0;
}

//1:从机应答 0:从机无应答 直接停止
u8 Wait_ACK(void)
{
        u8 ack_time;
        IIC_SDA_IN();
        IIC_Delay();
        IIC_SCL = 1;
        IIC_Delay();
        while(IIC_SDA_READ)
        {
                ack_time++;
                if(ack_time > 250)
                {
                        IIC_SCL = 0;
                        IIC_Stop();
                        return 0;
                }
        }
        IIC_SCL = 0;
        return 1;
}

发送一个字节
void IIC_Send_Byte(u8 txd)
{
    u8 t;   
        IIC_SDA_OUT();             
    IIC_SCL=0;//拉低时钟开始数据传输
    for(t=0;t<8;t++)
    {              
        IIC_SDA_WRITE=(txd&0x80)>>7;
        txd<<=1;           
                    IIC_SCL=1;
                    IIC_Delay();
                    IIC_SCL=0;       
                    IIC_Delay();
    }
}

//读取并发送ACK或Nack;
//1:发送ACK 0:发送NAK;
u8 IIC_Read_Byte(u8 a)
{
        unsigned char i,receive=0;
        IIC_SDA_IN();//SDA设置为输入
    for(i=0;i<8;i++ )
        {
        IIC_SCL=0;
        IIC_Delay();
                IIC_SCL=1;
        receive<<=1;
        if(IIC_SDA_READ)receive++;   
                IIC_Delay();
    }                                         
    if (!a)
        IIC_NAck();//发送nACK
    else
        IIC_ACK(); //发送ACK   
    return receive;
}

以下是MPU初始化程序
u8 MPU6050_Init(void)
{
        u8 addr;
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);
       
        GPIO_InitTypeDef  GPIO_InitS;
        GPIO_InitS.GPIO_Pin = GPIO_Pin_15;
        GPIO_InitS.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_InitS.GPIO_Pin = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA,&GPIO_InitS);
       
        GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);
        GPIO_ResetBits(GPIOA,GPIO_Pin_15);
       
        SIMIIC_Init();
        MPU_Send_Byte(MPU_PWR_MGMT1_REG,0x80);
        delay_ms(100);
        MPU_Send_Byte(MPU_PWR_MGMT1_REG,0X00);
        Gyroscope_Init(3);
        Accelerometer_Init(0);
        SampleRate_Init(50);
        MPU_Send_Byte(MPU_INT_EN_REG,0X00);
        MPU_Send_Byte(MPU_USER_CTRL_REG,0X00);
        MPU_Send_Byte(MPU_FIFO_EN_REG,0X00);
        MPU_Send_Byte(MPU_INTBP_CFG_REG,0X80);
        addr = MPU_Read_Byte(MPU_DEVICE_ID_REG);
        if(addr == MPU_ADDR)
        {
                MPU_Send_Byte(MPU_PWR_MGMT1_REG,0x01);
                MPU_Send_Byte(MPU_PWR_MGMT2_REG,0x00);
                SampleRate_Init(50);
        }
        else return 0;   //若器件地址和addr不等 则返回0 就是这里得不到正确的地址以至于一直返回0 怎么办啊
        return 1;
}

//向MPU某寄存器发送一字节数据 返回0:从机无应答
u8 MPU_Send_Byte(u8 reg_addr,u8 data)
{
        IIC_Start();
        IIC_Send_Byte((MPU_ADDR<<1)|0);
        if(!Wait_ACK())
        {       
                IIC_Stop();
                return 0;
        }
        IIC_Send_Byte(reg_addr);
        Wait_ACK();
        IIC_Send_Byte(data);
        if(!Wait_ACK())
        {
                IIC_Stop();
                return 0;
        }
        IIC_Stop();
        return 1;
}


//从MPU某寄存器读取数据
u8 MPU_Read_Byte(u8 reg_addr)
{
        u8 rec_data = 0;
        IIC_Start();
        IIC_Send_Byte((MPU_ADDR<<1)|0);
        Wait_ACK();
        IIC_Send_Byte(reg_addr);
        Wait_ACK();
        IIC_Start();
        IIC_Send_Byte((MPU_ADDR<<1)|1);
        Wait_ACK();
        rec_data = IIC_Read_Byte(0);
        IIC_Stop();
        return rec_data;
}

这程序逻辑清晰,按道理不应该得不到器件地址吧,求大神指点
1.png

最佳答案

查看完整内容[请看2#楼]

淦 我debug出来自己的问题了 还是代码写的不够细心 readdata写成senddata了 擦 另外就是这个问题 可以参考一下 正点的代码确实好 但还是可以再完善一下:https://blog.csdn.net/pamzerbhu/article/details/79949684?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_par ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

3

主题

28

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
455
金钱
455
注册时间
2020-3-27
在线时间
52 小时
发表于 2020-5-22 16:51:27 | 显示全部楼层
淦 我debug出来自己的问题了 还是代码写的不够细心 readdata写成senddata了 擦
另外就是这个问题 可以参考一下 正点的代码确实好 但还是可以再完善一下:https://blog.csdn.net/pamzerbhu/ ... ai2-1.channel_param
回复

使用道具 举报

0

主题

67

帖子

0

精华

初级会员

Rank: 2

积分
71
金钱
71
注册时间
2018-12-27
在线时间
0 小时
发表于 2020-5-22 16:51:29 | 显示全部楼层
默默的路过,帮顶
回复

使用道具 举报

3

主题

11

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2020-5-14
在线时间
11 小时
 楼主| 发表于 2020-5-22 16:54:55 | 显示全部楼层

谢谢帮顶,这已经成为我心头大患了
回复

使用道具 举报

3

主题

11

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2020-5-14
在线时间
11 小时
 楼主| 发表于 2020-5-22 17:56:17 | 显示全部楼层
救救孩子吧,这代码跟原子哥例程几乎一模一样,就是有问题
回复

使用道具 举报

15

主题

1061

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
3627
金钱
3627
注册时间
2019-8-14
在线时间
1054 小时
发表于 2020-5-22 18:19:29 | 显示全部楼层
可以仿真看看代码是卡在哪里了
回复

使用道具 举报

3

主题

11

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2020-5-14
在线时间
11 小时
 楼主| 发表于 2020-5-22 19:31:14 | 显示全部楼层
hou18 发表于 2020-5-22 18:19
可以仿真看看代码是卡在哪里了

这方面教程有点少啊
回复

使用道具 举报

0

主题

5

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2020-4-4
在线时间
8 小时
发表于 2020-5-22 22:53:46 | 显示全部楼层
u8 Wait_ACK(void)
{
        u8 ack_time;       //IIC_SDA_OUT();
      //IIC_SDA_WRITE  = 1;
        IIC_SDA_IN();
        IIC_Delay();
        IIC_SCL = 1;
        IIC_Delay();
        while(IIC_SDA_READ)
        {
                ack_time++;
                if(ack_time > 250)
                {
                        IIC_SCL = 0;
                        IIC_Stop();
                        return 0;
                }
        }
        IIC_SCL = 0;
        return 1;
}

发送一个字节
void IIC_Send_Byte(u8 txd)
{
    u8 t;   
        IIC_SDA_OUT();            
    IIC_SCL=0;//拉低时钟开始数据传输
    for(t=0;t<8;t++)
    {              
        IIC_SDA_WRITE=(txd&0x80)>>7;
        txd<<=1;  
                   //IIC_Delay();         
                    IIC_SCL=1;
                    IIC_Delay();
                    IIC_SCL=0;      
                    IIC_Delay();
    }
}
回复

使用道具 举报

34

主题

255

帖子

0

精华

高级会员

Rank: 4

积分
912
金钱
912
注册时间
2019-7-5
在线时间
189 小时
发表于 2020-5-23 08:40:54 | 显示全部楼层
你首先在示波器或逻辑分析仪上看看你的IIC初始化,发送和接收时序对不对先
回复

使用道具 举报

1

主题

7

帖子

0

精华

新手上路

积分
43
金钱
43
注册时间
2020-2-3
在线时间
15 小时
发表于 2020-7-9 22:34:00 | 显示全部楼层
请问你解决了这个问题嘛 我也卡了好久 救救孩子吧
回复

使用道具 举报

1

主题

7

帖子

0

精华

新手上路

积分
43
金钱
43
注册时间
2020-2-3
在线时间
15 小时
发表于 2020-7-10 08:52:55 | 显示全部楼层
请问你解决了嘛 我也遇到这个问题了
回复

使用道具 举报

3

主题

28

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
455
金钱
455
注册时间
2020-3-27
在线时间
52 小时
发表于 2020-8-25 21:14:55 | 显示全部楼层
我也遇到这个问题了呜呜呜
回复

使用道具 举报

11

主题

2149

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4926
金钱
4926
注册时间
2015-1-10
在线时间
618 小时
发表于 2020-8-28 13:44:19 | 显示全部楼层
用软件模拟的前提是你需要把时序搞明白了,别看到datasheet里写了个IIC就把例程套进去
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-13 01:54

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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