当前位置:   article > 正文

STM32利用软件I2C通讯读MPU6050的ID号

STM32利用软件I2C通讯读MPU6050的ID号

今天的读ID号是建立在上篇文章中有了底层的I2C通讯的6个基本时序来编写的。首先需要完成的就是MPU6050的初始化函数

   然后就是编写 指定地址写函数:
        一:开始
        二:发送 从机地址+读写位(1:读  0:写)
        三:接收应答位
        四:发送 指定寄存器地址(用于指定读写哪个寄存器)
        五:接收应答位
        六:发送(要写入指定寄存器下的数据)
        七:接收应答位
        八:终止

这个过程不是自己瞎编的,而是要根据MPU6050的时序图来确定的:

接下来要写的函数是指定地址读的函数:
        一:开始
        二:发送 从机地址+读写位
        三:接收应答位
        四:发送 指定寄存器地址(用于指定读哪个寄存器)
        五:接收应答位

        六:开始
        七:发送 从机地址+读写位1(1:读  0:写)
        八:接收应答位
        九:接收一个字节(此时,总线控制权交给从机)
        十:发送应答位(0:就是给从机应答(从机继续发数据)   1:就是不给从机应答(从机停止发数据))
      十一:终止

好了,到此读写MPU6050的基本操作就都完成了,剩下的事就是往不同的寄存器内写入不同的数据,实现不同的功能了,这个明天在学习吧,今天的代码贴出来看看吧:

  1. #include "stm32f10x.h" // Device header
  2. #include "MPU6050.h"
  3. #include "MyI2C.h"
  4. #define MPU6050_ADDRESS 0xD0
  5. /*
  6. 指定地址写函数:
  7. 一:开始
  8. 二:发送 从机地址+读写位(1:读 0:写)
  9. 三:接收应答位
  10. 四:发送 指定寄存器地址(用于指定读写哪个寄存器)
  11. 五:接收应答位
  12. 六:发送(要写入指定寄存器下的数据)
  13. 七:接收应答位
  14. 八:终止
  15. */
  16. void MPU6050_WriteReg(uint8_t Address, uint8_t Data)
  17. {
  18. MyI2C_Star();
  19. MyI2C_SendByte(MPU6050_ADDRESS);
  20. MyI2C_ReceiveAck();
  21. MyI2C_SendByte(Address);
  22. MyI2C_ReceiveAck();
  23. MyI2C_SendByte(Data); //如果想实现指定地址写多个数据,可以在此处加循环,循环数据个数次
  24. MyI2C_ReceiveAck(); //每次循环都要加接收应答位
  25. MyI2C_Stop();
  26. }
  27. /*
  28. 指定地址读的函数:
  29. 一:开始
  30. 二:发送 从机地址+读写位
  31. 三:接收应答位
  32. 四:发送 指定寄存器地址(用于指定读哪个寄存器)
  33. 五:接收应答位
  34. 六:开始
  35. 七:发送 从机地址+读写位1(1:读 0:写)
  36. 八:接收应答位
  37. 九:接收一个字节(此时,总线控制权交给从机)
  38. 十:发送应答位(0:就是给从机应答(从机继续发数据) 1:就是不给从机应答(从机停止发数据))
  39. 十一:终止
  40. */
  41. uint8_t MPU6050_ReadReg(uint8_t Address)
  42. {
  43. uint8_t Data;
  44. MyI2C_Star();
  45. MyI2C_SendByte(MPU6050_ADDRESS);
  46. MyI2C_ReceiveAck();
  47. MyI2C_SendByte(Address);
  48. MyI2C_ReceiveAck();
  49. MyI2C_Star();
  50. MyI2C_SendByte(MPU6050_ADDRESS | 0x01);
  51. MyI2C_ReceiveAck();
  52. Data = MyI2C_ReceiveByte();
  53. MyI2C_SendAck(1);
  54. MyI2C_Stop();
  55. return Data;
  56. }
  57. void MPU6050_Init(void)
  58. {
  59. MyI2C_Init();
  60. }

写了一个MPU6050.h文件,方便测试一下今天的功能:

  1. #ifndef __MPU6050_H
  2. #define __MPU6050_H
  3. void MPU6050_Init(void);
  4. uint8_t MPU6050_ReadReg(uint8_t Address);
  5. void MPU6050_WriteReg(uint8_t Address, uint8_t Data);
  6. #endif

然后就是主函数调用一下,验证结果了:

  1. #include "stm32f10x.h" // Device header
  2. #include "OLED.h"
  3. #include "MPU6050.h"
  4. #include "MPU6050_Reg.h"
  5. int main(void)
  6. {
  7. OLED_Init(); //oled 屏幕初始化
  8. MPU6050_Init();
  9. uint8_t ID = MPU6050_ReadReg(MPU6050_WHO_AM_I);
  10. OLED_ShowHexNum(1,1, ID, 2);
  11. while(1)
  12. {
  13. }
  14. }

编译下载后的结果如图:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/440739
推荐阅读
相关标签
  

闽ICP备14008679号