1回答

1收藏

GD32方案分享⑥:读取MPU6050

GD32 GD32 6296 人阅读 | 1 人回复 | 2017-05-27

先上效果图:


MPU6050 由于其性价比高,被广泛由于各种需要检测姿态角和惯性导航的系统中。其读取也是很方便,使用的模拟IIC,移植性较强,但要注意设置为开漏输出,废话不多说,上代码。

  1. #include "include.h"

  2. int main(void)
  3. {
  4.     systick_config();
  5.        
  6.           UART_Init(Debug_UART,115200);
  7.        
  8.     LED_Init();          
  9.           MPU6050_Init();
  10.           while(1)
  11.          {
  12.                           LED_Troggle();
  13.                     delay_1ms(50);
  14.                     printf("%d %d %d %d %d %d\r\n",getAccX(),getAccY(),getAccZ(),getGyroX(),getGyroY(),getGyroZ());
  15.     }
  16. }
复制代码

  1. #include "IIC_Analog_6050.h"

  2. int read_buff[6];

  3. void I2C_Start(void);
  4. void I2C_Stop(void);
  5. void I2C_Ack(void);
  6. void I2C_NoAck(void);
  7. void I2C_SendByte(uint8);
  8. uint8 I2C_ReceiveByte(void);
  9. void I2C_Delay(uint16);

  10. void I2C_SDA_OUT(void)
  11. {
  12.          //使能时钟
  13.     rcu_periph_clock_enable(MPU6050_PORT_CLK);
  14.           //设置模式
  15.     gpio_mode_set(MPU6050_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE,SDA_Pin);
  16.     gpio_output_options_set(MPU6050_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ,SDA_Pin);
  17. }

  18. void I2C_SDA_IN(void)
  19. {
  20.           rcu_periph_clock_enable(MPU6050_PORT_CLK);
  21.     rcu_periph_clock_enable(RCU_SYSCFG);
  22.     gpio_mode_set(MPU6050_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE,SDA_Pin);     
  23. }       
  24. /*
  25. * I2C_Init
  26. * 初始化I2C所需引脚
  27. */
  28. void I2C_Init(void)
  29. {
  30.           //使能时钟
  31.     rcu_periph_clock_enable(MPU6050_PORT_CLK);
  32.           //设置模式
  33.     gpio_mode_set(MPU6050_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE,SDA_Pin|SCL_Pin);
  34.     gpio_output_options_set(MPU6050_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ,SDA_Pin|SCL_Pin);
  35.           //清零
  36.           GPIO_BOP(MPU6050_PORT) = SDA_Pin|SCL_Pin;
  37. }
  38. /*
  39. * I2C_WriteReg
  40. * 写I2C设备寄存器
  41. */
  42. void I2C_WriteReg(uint8 dev_addr,uint8 reg_addr , uint8 data)
  43. {               
  44.   I2C_Start();
  45.   I2C_SendByte(dev_addr<<1);         
  46.   I2C_SendByte(reg_addr );   
  47.   I2C_SendByte(data);   
  48.   I2C_Stop();
  49. }

  50. //读寄存器
  51. uint8 I2C_ReadByte(uint8 dev_addr,uint8 reg_addr)
  52. {
  53.   uint8 data;
  54.   I2C_Start();
  55.   I2C_SendByte(dev_addr<<1);
  56.   I2C_SendByte(reg_addr);
  57.   I2C_Start();       
  58.   I2C_SendByte((dev_addr<<1)+1);
  59.   data= I2C_ReceiveByte();
  60.   I2C_NoAck();
  61.   I2C_Stop();
  62.   return data;
  63. }

  64. //读寄存器
  65. int16 I2C_ReadWord(uint8 dev_addr,uint8 reg_addr)
  66. {
  67.   char h,l;
  68.   I2C_Start();
  69.   I2C_SendByte( dev_addr<<1);
  70.   I2C_SendByte( reg_addr);
  71.   I2C_Start();       
  72.   I2C_SendByte((dev_addr<<1)+1);
  73.   h= I2C_ReceiveByte();
  74.   I2C_Ack();
  75.   l= I2C_ReceiveByte();
  76.   I2C_NoAck();
  77.   I2C_Stop();
  78.   return (h<<8)+l;
  79. }

  80. void I2C_ReadGryo(uint8 dev_addr,uint8 reg_addr,int16 *x,int16 *y)
  81. {
  82.   char h,l;
  83.   I2C_Start();
  84.   I2C_SendByte( dev_addr<<1);
  85.   I2C_SendByte( reg_addr);
  86.   I2C_Start();       
  87.   I2C_SendByte((dev_addr<<1)+1);
  88.   h= I2C_ReceiveByte();
  89.   I2C_Ack();
  90.   l= I2C_ReceiveByte();
  91.   I2C_Ack();
  92.   *x=(h<<8)+l;
  93.   h= I2C_ReceiveByte();
  94.   I2C_Ack();
  95.   l= I2C_ReceiveByte();
  96.   I2C_Ack();
  97.   h= I2C_ReceiveByte();
  98.   I2C_Ack();
  99.   l= I2C_ReceiveByte();
  100.   I2C_NoAck();
  101.   *y=(h<<8)+l;
  102.   I2C_Stop();
  103. }
  104. /*
  105. * I2C_Start
  106. * I2C起始信号,内部调用
  107. */
  108. void I2C_Start(void)
  109. {
  110.   I2C_SDA_OUT();
  111.   I2C_DELAY();
  112.   I2C_DELAY();
  113.   I2C_SDA_H;
  114.   I2C_SCL_H;
  115.   I2C_DELAY();
  116.   I2C_DELAY();
  117.   I2C_SDA_L;
  118.   I2C_DELAY();
  119.   I2C_DELAY();
  120.   I2C_SCL_L;
  121.   I2C_DELAY();
  122.   I2C_DELAY();
  123. }

  124. /*
  125. * I2C_Stop
  126. * I2C停止信号,内部调用
  127. */
  128. void I2C_Stop(void)
  129. {
  130.   I2C_SDA_L;
  131.   I2C_SCL_L;
  132.   I2C_DELAY();
  133.   I2C_DELAY();
  134.   I2C_SCL_H;
  135.   I2C_DELAY();
  136.   I2C_DELAY();
  137.   I2C_SDA_H;
  138.   I2C_DELAY();
  139.   I2C_DELAY();
  140.   I2C_SCL_L;
  141. }

  142. /*
  143. * I2C_Stop
  144. * I2C应答信号,内部调用
  145. */
  146. void I2C_Ack(void)
  147. {       
  148.   I2C_SCL_L;
  149.   I2C_DELAY();
  150.   
  151.   I2C_SDA_L;
  152.   I2C_DELAY();
  153.   
  154.   I2C_SCL_H;
  155.   I2C_DELAY();
  156.   
  157.   I2C_SCL_L;
  158.   I2C_DELAY();
  159. }

  160. /*
  161. * I2C_NoAck
  162. * I2C无应答信号,内部调用
  163. */
  164. void I2C_NoAck(void)
  165. {       
  166.   I2C_SCL_L;
  167.   I2C_DELAY();
  168.   I2C_SDA_H;
  169.   I2C_DELAY();
  170.   I2C_SCL_H;
  171.   I2C_DELAY();
  172.   I2C_SCL_L;
  173.   I2C_DELAY();
  174. }


  175. /*
  176. * I2C_SendByte
  177. * I2C发送数据,内部调用
  178. */
  179. void I2C_SendByte(uint8 data)
  180. {
  181.   uint8 i=8;
  182.   while(i--)
  183.   {
  184.     I2C_SCL_L;
  185.     if(data&0x80)
  186.       I2C_SDA_H;
  187.     else
  188.       I2C_SDA_L;   
  189.     data<<=1;
  190.     I2C_DELAY();
  191.     I2C_SCL_H;
  192.     I2C_DELAY();
  193.   }
  194.   I2C_SCL_L;
  195.   I2C_DELAY();
  196.   I2C_SDA_H;
  197.   I2C_DELAY();
  198.   I2C_SCL_H;
  199.   I2C_DELAY();
  200.   I2C_SCL_L;
  201. }

  202. /*
  203. * I2C_SendByte
  204. * I2C接收数据,内部调用
  205. */
  206. uint8 I2C_ReceiveByte(void)  
  207. {
  208.   uint8 i=8;
  209.   uint8 ReceiveByte=0;
  210.   
  211.   I2C_SDA_H;       
  212.   I2C_SDA_IN();       
  213.   
  214.   while(i--)
  215.   {
  216.     ReceiveByte<<=1;      
  217.     I2C_SCL_L;
  218.     I2C_DELAY();
  219.     I2C_SCL_H;
  220.     I2C_DELAY();       
  221.     if(I2C_SDA_I)
  222.     {
  223.       ReceiveByte|=0x01;
  224.     }
  225.    
  226.   }
  227.   I2C_SDA_OUT();
  228.   I2C_SCL_L;
  229.   
  230.   return ReceiveByte;
  231. }

  232. /*
  233. * I2C_SendByte
  234. * I2C延时函数,内部调用
  235. */
  236. void I2C_Delay(uint16 i)
  237. {       
  238.                 while(i)
  239.                 i--;
  240. }

  241. uint8 MPU6050_Init(void)
  242. {
  243.         I2C_Init();
  244.         delay_1ms(100);
  245.         //解除休眠
  246.         I2C_WriteReg( SLAVEADRESS , PWR_MGMT_1 ,  0x00 );//电源管理
  247.         I2C_WriteReg( SLAVEADRESS , SMPLRT_DIV ,  0x07 );//采样率分频
  248.         I2C_WriteReg( SLAVEADRESS , MPU_CONFIG ,  0x07 );//低通滤波频率
  249.         I2C_WriteReg( SLAVEADRESS , GYRO_CONFIG , 0x18 );//陀螺仪
  250.         I2C_WriteReg( SLAVEADRESS , ACCEL_CONFIG ,0x00 );//加速度计
  251.         if(I2C_ReadByte(SLAVEADRESS , WHO_AM_I)==0x68 ) return 1;
  252.         else return 0;
  253. }


  254. int16 getAccX(void)
  255. {
  256.         short AccX = 0;
  257.         char AccXH = 0 , AccXL = 0;

  258.         AccXH = I2C_ReadByte( SLAVEADRESS , ACCEL_XOUT_H );
  259.         AccXL = I2C_ReadByte( SLAVEADRESS , ACCEL_XOUT_L );

  260.         AccX = (AccXH<<8)|AccXL;

  261.         return AccX;
  262. }

  263. int16 getAccY(void)
  264. {
  265.         int16 AccY = 0;
  266.         char AccYH = 0 , AccYL = 0;

  267.         AccYH = I2C_ReadByte( SLAVEADRESS , ACCEL_YOUT_H );
  268.         AccYL = I2C_ReadByte( SLAVEADRESS , ACCEL_YOUT_L );

  269.         AccY = (AccYH<<8)|AccYL;

  270.         return AccY;
  271. }

  272. int16 getAccZ(void)
  273. {
  274.         int16 AccZ = 0;
  275.         char AccZH = 0 , AccZL = 0;

  276.         AccZH = I2C_ReadByte( SLAVEADRESS , ACCEL_ZOUT_H );
  277.         AccZL = I2C_ReadByte( SLAVEADRESS , ACCEL_ZOUT_L );

  278.         AccZ = (AccZH<<8)|AccZL;

  279.         return AccZ;
  280. }

  281. int16 getGyroX(void)
  282. {
  283.         int16 GyroX = 0;
  284.         char GyroXH = 0 , GyroXL = 0;
  285.        
  286.         GyroXH = I2C_ReadByte( SLAVEADRESS , GYRO_XOUT_H );
  287.         GyroXL = I2C_ReadByte( SLAVEADRESS , GYRO_XOUT_H );
  288.        
  289.         GyroX = (GyroXH<<8)|GyroXL;
  290.        
  291.         return GyroX;       
  292. }

  293. int16 getGyroY(void)
  294. {
  295.   int16 GyroY = 0;
  296.         char GyroYH = 0 , GyroYL = 0;
  297.        
  298.         GyroYH = I2C_ReadByte( SLAVEADRESS , GYRO_YOUT_H );
  299.         GyroYL = I2C_ReadByte( SLAVEADRESS , GYRO_YOUT_H );
  300.        
  301.         GyroY = (GyroYH<<8)|GyroYL;
  302.        
  303.         return GyroY;       
  304. }

  305. int16 getGyroZ(void)
  306. {
  307.   int16 GyroZ = 0;
  308.         char GyroZH = 0 , GyroZL = 0;
  309.        
  310.         GyroZH = I2C_ReadByte( SLAVEADRESS , GYRO_ZOUT_H );
  311.         GyroZL = I2C_ReadByte( SLAVEADRESS , GYRO_ZOUT_H );
  312.        
  313.         GyroZ = (GyroZH<<8)|GyroZL;
  314.        
  315.         return GyroZ;       
  316. }

  317. short getTemperature(void)
  318. {
  319.         short temperature = 0;
  320.         char temperatureH = 0 , temperatureL = 0;

  321.         temperatureH = I2C_ReadByte( SLAVEADRESS , TEMP_OUT_H );
  322.         temperatureL = I2C_ReadByte( SLAVEADRESS , TEMP_OUT_L );

  323.         temperature = (temperatureH<<8)|temperatureL;

  324.         return temperature;
  325. }
  326.        
复制代码
有需求的自行下载附件
myGD32 - 副本.rar (7.04 MB, 下载次数: 47)

分享到:
回复

使用道具 举报

回答|共 1 个

倒序浏览

沙发

nana96

发表于 2017-6-21 15:30:31 | 只看该作者

good  data for me
您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

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