查看: 10904|回复: 15

[经验] GD32空中飞鼠 之 硬件I2C读MPU6050

  [复制链接]
  • TA的每日心情

    2023-7-25 22:49
  • 签到天数: 385 天

    连续签到: 1 天

    [LV.9]以坛为家II

    发表于 2015-7-19 16:36:41 | 显示全部楼层 |阅读模式
    分享到:

    硬件I2C读MPU6050


    拿到小红板研究了一段时间,我的方案是做空中飞鼠的实验,那就要使用MPU6050来读取重取X和Y轴的重力加速度,MPU6050模块提供I2C通讯接口。I2C在STM32F1系列MCU上硬件使用上有诸多的问题,所以很多人都使用软件I2C。大家都知道GD32系列MCU是“山寨”STM32,所以可能也会存在同要的问题。但是我想即便是GD32“山寨”STM32,也可能是硬件寄存器和寄存器地址和STM32定义的一样,是为了大家从STM32更容易过渡到GD32上来做开发(这是不是在偷STM32的普及成果!),其硬件实现肯定是不一样的。既然硬件实现不一样,那GD32的硬件I2C就可能比STM32要好用。好了废话不多说,开始吧。


    我们使用GD32的I2C1来读MPU6050,查下数据手册pin定义:


    i2c.png

    PB8,PB9复用I2C1的SCL,SDA
    原理图上PB8,PB9在CN5上引出


    cn5.png

    实际接线图:


    IMG_20150719_151236.jpg

    为了调试I2C,使用logic8来分析I2C的波形。


    I2C逻辑电平

    I2C逻辑电平

    花了好几天时间终于调试通过。其实很简单,使用起来了很方便,只是GD没有I2C的例子,走了不少的弯路。特分享给大家,希望对其它人有用,代码我就只贴关键代码,明白人应该一看就知道了。

    1. //配置I2C
    2. void I2cConfig(void)
    3. {
    4.         GPIO_InitPara GPIO_InitStructure;
    5.         I2C_InitPara I2C_InitStructure;
    6.         
    7.         RCC_AHBPeriphClock_Enable(RCC_AHBPERIPH_GPIOB,ENABLE);
    8.         RCC_APB1PeriphClock_Enable(RCC_APB1PERIPH_I2C1,ENABLE);
    9.         
    10.         GPIO_DeInit(GPIOB);
    11.         /* Connect pin to Periph */
    12.         GPIO_PinAFConfig(GPIOB,GPIO_PINSOURCE8,GPIO_AF_1);
    13.         GPIO_PinAFConfig(GPIOB,GPIO_PINSOURCE9,GPIO_AF_1);
    14.         
    15.         /* Configure pins as AF pushpull */
    16.         GPIO_InitStructure.GPIO_Pin     = SCL|SDA;
    17.         GPIO_InitStructure.GPIO_Mode    = GPIO_MODE_AF;
    18.         GPIO_InitStructure.GPIO_Speed   = GPIO_SPEED_50MHZ;
    19.         GPIO_InitStructure.GPIO_OType   = GPIO_OTYPE_PP;
    20.         GPIO_InitStructure.GPIO_PuPd    = GPIO_PUPD_PULLUP;
    21.         GPIO_Init( GPIOB , &GPIO_InitStructure);

    22.         I2C_DeInit(I2C1);
    23.         I2C_InitStructure.I2C_AddressingMode = I2C_ADDRESSING_MODE_7BIT;
    24.         I2C_InitStructure.I2C_BitRate = 100000;
    25.         I2C_InitStructure.I2C_DeviceAddress = 0x08;
    26.         I2C_InitStructure.I2C_DutyCycle = I2C_DUTYCYCLE_2;
    27.         I2C_InitStructure.I2C_Protocol = I2C_PROTOCOL_I2C;
    28.         I2C_Init(I2C1,&I2C_InitStructure);
    29.         I2C_Enable(I2C1,ENABLE);
    30. }
    复制代码
    上面的代码是配置I2C,不用太多的解释。下面的就是关键代码了
    1. //**************************************
    2. //向I2C设备写入一个字节数据
    3. //**************************************
    4. void Single_WriteI2C(uint8_t REG_Address,uint8_t REG_data)
    5. {
    6.         I2C_StartOnBus_Enable(I2C1,ENABLE);
    7.         while(I2C_StateDetect(I2C1,I2C_PROGRAMMINGMODE_MASTER_SBSEND) == ERROR);//不能用I2C_GetBitState(I2C1,I2C_FLAG_SBSEND)
    8.         
    9.         //发送从设备地址到i2c总线上
    10.         //I2C_AddressingDevice_7bit(I2C1,0xD0,I2C_DIRECTION_TRANSMITTER);
    11.         I2C_SendData(I2C1,SlaveAddress);
    12.         while(I2C_StateDetect(I2C1,I2C_PROGRAMMINGMODE_MASTER_TRANSMITTER_ADDSEND) == ERROR);

    13.         I2C_SendData(I2C1,REG_Address);
    14.         I2C_SendData(I2C1,REG_data);
    15.         
    16.         while(I2C_StateDetect(I2C1,I2C_PROGRAMMINGMODE_MASTER_BYTE_TRANSMITTED) == ERROR);
    17.         //while(!I2C_GetBitState(I2C1,I2C_FLAG_BTC));
    18.         I2C_StopOnBus_Enable(I2C1,ENABLE);
    19. }
    20. //**************************************
    21. //从I2C设备读取一个字节数据
    22. //**************************************
    23. uint8_t Single_ReadI2C(uint8_t REG_Address)
    24. {
    25.         uint8_t data;
    26.         //起始信号
    27.         I2C_StartOnBus_Enable(I2C1,ENABLE);
    28.         while(I2C_StateDetect(I2C1,I2C_PROGRAMMINGMODE_MASTER_SBSEND) == ERROR);
    29.         
    30.         //发送从设备地址到i2c总线上
    31.         I2C_AddressingDevice_7bit(I2C1,SlaveAddress,I2C_DIRECTION_TRANSMITTER);
    32.         while(I2C_StateDetect(I2C1,I2C_PROGRAMMINGMODE_MASTER_TRANSMITTER_ADDSEND) == ERROR);
    33.         //发送读地址
    34.         I2C_SendData(I2C1,REG_Address);
    35.         
    36.         //再次发送起始信号
    37.         I2C_StartOnBus_Enable(I2C1,ENABLE);
    38.         while(I2C_StateDetect(I2C1,I2C_PROGRAMMINGMODE_MASTER_SBSEND) == ERROR);
    39.         //发送读设备信号
    40.         I2C_SendData(I2C1,SlaveAddress+1);
    41.         while(I2C_StateDetect(I2C1,I2C_PROGRAMMINGMODE_MASTER_RECEIVER_ADDSEND) == ERROR);
    42.         
    43.         while(I2C_StateDetect(I2C1,I2C_PROGRAMMINGMODE_MASTER_BYTE_RECEIVED) == ERROR);
    44.         data = I2C_ReceiveData(I2C1);
    45.         
    46.         I2C_StopOnBus_Enable(I2C1,ENABLE);
    47.         return data;
    48. }
    复制代码
    刚开始的时候一切安照参考手册上的I2C通讯流程,但总线状态我一直使用I2C_GetBitState来取I2C总线状态,i2c总线上始终只出现一次数据,再写数据已经没有任何反应了,调试了好几天都一样,把参考手册i2c通讯流程都看了好几遍,最后把gd32f1x0_i2c.c文件打开,一个函数一个函数细细看下。看到I2C_StateDetect这个函数,而且注释上有@brief  Detect I2Cx State Machine.想想以前在新唐上的I2C就是用状态机检测,就试试这个来检测状态,大功告成。太坑爹了,在这里真希望官为真的应该出一本函数手册,配以用例,让俺们也少走些变路。。。





    点评

    推荐大家一个靠谱的论文检测平台。重复的部分有详细出处以及具体修改意见,能直接在文章上做修改,全部改完一键下载就搞定了。他们现在正在...  发表于 2020-5-3 19:21
    回复

    使用道具 举报

  • TA的每日心情

    2015-7-14 18:08
  • 签到天数: 5 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    发表于 2015-7-20 00:02:48 | 显示全部楼层
    我软件模拟的i2c昨天也刚刚调通了。。。。
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2016-8-15 09:28
  • 签到天数: 222 天

    连续签到: 1 天

    [LV.7]常住居民III

    发表于 2015-7-20 08:32:09 | 显示全部楼层
    多谢楼主分享,非常不错 技术贴
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2015-7-20 09:14:08 | 显示全部楼层
    收藏了  看转到日照传感器上面是什么效果 ,我原来用的是模拟方式实现
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2015-12-29 13:50
  • 签到天数: 47 天

    连续签到: 1 天

    [LV.5]常住居民I

    发表于 2015-7-20 09:39:01 | 显示全部楼层
    不错不错啊,支持
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2015-12-29 13:50
  • 签到天数: 47 天

    连续签到: 1 天

    [LV.5]常住居民I

    发表于 2015-7-20 10:51:37 | 显示全部楼层
    没有这个传感器啊
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2023-7-25 22:49
  • 签到天数: 385 天

    连续签到: 1 天

    [LV.9]以坛为家II

    发表于 2015-7-20 11:12:26 | 显示全部楼层
    魅影迷踪 发表于 2015-7-20 10:51
    没有这个传感器啊

    只要有I2C的设备,不一定非要用这个传感 器。

    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2016-1-22 11:18
  • 签到天数: 159 天

    连续签到: 1 天

    [LV.7]常住居民III

    发表于 2015-7-20 15:09:48 | 显示全部楼层
    不错!!!支持 楼主我希望看到获得的MPU6050的数据 我也在搞 数据老是不正确
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2015-12-29 13:50
  • 签到天数: 47 天

    连续签到: 1 天

    [LV.5]常住居民I

    发表于 2015-7-21 08:51:23 | 显示全部楼层
    关键是啥都没有
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    擦汗
    2020-12-31 13:14
  • 签到天数: 526 天

    连续签到: 1 天

    [LV.9]以坛为家II

    发表于 2015-7-21 08:57:44 | 显示全部楼层
    支持下,我也在调i2c,太蛋疼了
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条



    手机版|小黑屋|与非网

    GMT+8, 2024-6-2 23:53 , Processed in 0.196529 second(s), 35 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.