• STM32实现硬件I2C通讯,读取MPU6050的ID号


    今天学习了使用硬件I2C的方式成功读取MPU6050的ID号,特此记录一下过程:

    首先需要学习的是MPU6050的初始化:

    第一步:打开GPIOB的时钟(因为I2C2的引脚10,11在GPIOB上)

    第二步:打开I2C2的时钟

    第三步:初始化GPIO。

    第四步:初始化I2C2。

    第五步:开启I2C2。

    下面学习的就是指定MPU6050的寄存器地址写数据的函数:
    第一步:行成起始条件

    第二步:等待EV5事件

    第三步:发送7位地址(方向:发送者)

    第四步:等待EV6事件(发送完成)

    第五步:发送寄存器地址

    第六步:等待EV8事件(正在发送)

    第七步:发送数据

    第八步:等待EV8_2事件(发送完成)

    第九步:行成停止条件。

    再下面学习的就是指定MPU6050的寄存器地址读数据的函数:

    第一步:行成起始条件

    第二步:等待EV5事件

    第三步:发送7位地址(方向:发送者)

    第四步:等待EV6事件(发送完成)

    第五步:发送寄存器地址

    第六步:等待EV8事件(发送完成)

    第七步:再次行成起始条件

    第八步:等待EV5事件

    第九步:发送7位地址(方向:接收模式)最后一位是接收模式

    第十步:等待EV6事件(接收完成标志)

    第十一步:应答位给非应答

    第十二步:行成终止条件

    第十三步: 等待EV7事件(接收完成)

    第十四步:提取接收到的数据

    第十五步:应答位给应答(回复默认值)

    最后就是读取MPU6050的ID号了,MPU6050的ID号存在MPU650的寄存器地址为0x75,读取这个地址中的值就是ID号了。

    下面把整个文件展示一下:

    1. #include "stm32f10x.h" // Device header
    2. #include "MPU6050.h"
    3. #define MPU6050_ADDRESS 0xD0
    4. #define GPIO_POART GPIOB
    5. #define SCL GPIO_Pin_10
    6. #define SDA GPIO_Pin_11
    7. #define GPIO_CLOCK RCC_APB2Periph_GPIOB
    8. #define I2C_CLOCK RCC_APB1Periph_I2C2
    9. void MPU6050_WriteReg(uint8_t Address, uint8_t Data)
    10. {
    11. I2C_GenerateSTART(I2C2, ENABLE); // 行成起始条件
    12. while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT) !=SUCCESS );// 等待EV5事件
    13. I2C_Send7bitAddress(I2C2, MPU6050_ADDRESS, I2C_Direction_Transmitter); // 发送7位地址(方向:发送者)
    14. while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) !=SUCCESS );// 等待EV6事件(发送完成)
    15. I2C_SendData(I2C2, Address); //发送寄存器地址
    16. while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTING) !=SUCCESS );// 等待EV8事件(正在发送)
    17. I2C_SendData(I2C2, Data); //发送数据
    18. while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED) !=SUCCESS );// 等待EV8_2事件(发送完成)
    19. I2C_GenerateSTOP(I2C2, ENABLE); //行成停止条件
    20. }
    21. uint8_t MPU6050_ReadReg(uint8_t Address)
    22. {
    23. uint8_t Data;
    24. I2C_GenerateSTART(I2C2, ENABLE); // 行成起始条件
    25. while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT) !=SUCCESS );// 等待EV5事件
    26. I2C_Send7bitAddress(I2C2, MPU6050_ADDRESS, I2C_Direction_Transmitter); // 发送7位地址(方向:发送者)
    27. while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) !=SUCCESS );// 等待EV6事件(发送完成)
    28. I2C_SendData(I2C2, Address); //发送寄存器地址
    29. while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED) !=SUCCESS );// 等待EV8事件(发送完成)
    30. I2C_GenerateSTART(I2C2, ENABLE); // 行成起始条件
    31. while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT) !=SUCCESS );// 等待EV5事件
    32. I2C_Send7bitAddress(I2C2, MPU6050_ADDRESS, I2C_Direction_Receiver); // 发送7位地址(方向:接收模式)
    33. while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED) !=SUCCESS );// 等待EV6事件(接收完成标志)
    34. I2C_AcknowledgeConfig(I2C2, DISABLE); // 应答位给非应答
    35. I2C_GenerateSTOP(I2C2, ENABLE); // 行成终止条件
    36. while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED) !=SUCCESS );// 等待EV7事件(接收完成)
    37. Data = I2C_ReceiveData(I2C2); //提取接收到的数据
    38. I2C_AcknowledgeConfig(I2C2, ENABLE); // 应答位给应答
    39. return Data; //返回接收到的数据
    40. }
    41. void MPU6050_Init(void)
    42. {
    43. RCC_APB2PeriphClockCmd(GPIO_CLOCK, ENABLE); //第一步:打开GPIOB的时钟(因为I2C2的引脚10,11在GPIOB上)
    44. RCC_APB1PeriphClockCmd(I2C_CLOCK, ENABLE); //第二步:打开I2C2的时钟
    45. GPIO_InitTypeDef GPIO_InitStruct;
    46. GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_OD;
    47. GPIO_InitStruct.GPIO_Pin = SCL | SDA;
    48. GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    49. GPIO_Init(GPIO_POART, &GPIO_InitStruct); // 第三步:初始化GPIO。
    50. I2C_InitTypeDef I2C_InitStruct;
    51. I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
    52. I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
    53. I2C_InitStruct.I2C_ClockSpeed = 100000;
    54. I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_16_9;
    55. I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;
    56. I2C_InitStruct.I2C_OwnAddress1 = 0x00;
    57. I2C_Init(I2C2, &I2C_InitStruct); // 第四步:初始化I2C2。
    58. I2C_Cmd(I2C2, ENABLE); //第五步:开启I2C2。
    59. }
    60. uint8_t MPU6050_GetID(void)
    61. {
    62. return MPU6050_ReadReg(0x75);
    63. }

    这样就形成了最终的结果:

  • 相关阅读:
    代码随想录算法训练营Day58|动态规划16
    基于spring-boot-starter-actuator不同版本(2.1.3和2.3.5)在K8s中做就绪存活检查相关配置的差异
    中集集团人工智能企业CIMCAI中集飞瞳,深入贯彻国家关于智慧港口数字港口建设部署要求全球顶尖港航AI核心技术打造超一流智慧港口
    游戏客户端--个人学习路线总结、指北
    综合案列——产品模块布局
    AUTOSAR知识点 之 SWC (一):基于ETAS工具ISOLAR-AB新建一个SWC并实现与其它SWC通信(动态与静态详细步骤介绍)
    汇编语言ret与call指令
    Android12窗口模糊(二)高斯模糊API源码解析
    搭建个人知识付费应用系统-(6)Sanity 集成
    C++11常用特性
  • 原文地址:https://blog.csdn.net/xingyuncao520025/article/details/137966441