[8/16-bit MCU] LPC54100 iic读取MPU6050相关数据

[复制链接]
1302|3
 楼主| Tennasi 发表于 2016-1-24 20:10 | 显示全部楼层 |阅读模式
既然要做自平衡车,那么小车姿态的获取就相当重要的,通常6050是首选,下面这段话来自与6050的手册:
         MPU-6000(6050)的角速度全格感测范围为±250、±500、±1000与±2000°/sec (dps),可准确追踪快速与慢速动作,并且,用户可程式控制的加速器全格感测范围为±2g、±4g±8g与±16g。产品传输可透过最高至400kHz的IC或最高达20MHz的SPI(MPU-6050没有SPI)。MPU-6000可在不同电压下工作,VDD供电电压介为2.5V±5%、3.0V±5%或3.3V±5%,逻辑接口VVDIO供电为1.8V± 5%(MPU6000仅用VDD)。MPU-6000的包装尺寸4x4x0.9mm(QFN),在业界是革命性的尺寸。其他的特征包含内建的温度感测器、包含在运作环境中仅有±1%变动的振荡器。
     可见,对于小型化的嵌入式系统来说,MPU6050是不二的选择。由于它采用的是IIC来进行通讯,因此我们必须在LPC上面实现IIC。  
     IIC通讯的方式一般有两种:软件模拟和硬件实现。由于硬件IIC的方式前面有朋友已经搞定了,所以我们最终还是选择采用软件模拟IIC的方式来做。开始我们还认为软件模拟的方式会出现速度跟不上的问题,后来发现担心完全是多余的。并且采用软件的方式还具有GPIO灵活的特点。
   


IIC头文件
  1. #ifndef _MYIIC_H_
  2. #define _MYIIC_H_
  3. #include "board.h"





  4. #define IIC_SCL_OUT()    {Chip_GPIO_SetPinDIROutput(LPC_GPIO, 0, 10);}
  5. #define IIC_SCL_IN()    {Chip_GPIO_SetPinDIRInput(LPC_GPIO, 0, 10);}
  6. #define IIC_SCL_1        {Chip_GPIO_SetPinState(LPC_GPIO, 0, 10, 1);}
  7. #define IIC_SCL_0        {Chip_GPIO_SetPinState(LPC_GPIO, 0, 10, 0);}

  8. #define IIC_SDA_OUT()     {Chip_GPIO_SetPinDIROutput(LPC_GPIO, 0, 11);}
  9. #define IIC_SDA_IN()    {Chip_GPIO_SetPinDIRInput(LPC_GPIO, 0, 11);}
  10. #define IIC_SDA_1         {Chip_GPIO_SetPinState(LPC_GPIO, 0, 11, 1);}
  11. #define IIC_SDA_0         {Chip_GPIO_SetPinState(LPC_GPIO, 0, 11, 0);}
  12. #define IIC_SDA_READ    (Chip_GPIO_ReadPortBit(LPC_GPIO, 0, 11))


  13. //IIC所有操作函数

  14. void IIC_Init(void);
  15. void IIC_Start(void);
  16. void IIC_Stop(void);
  17. void IIC_SendACK(unsigned char ack);
  18. unsigned char IIC_RecvACK(void);
  19. void IIC_Send_Byte(unsigned char dat);
  20. unsigned char IIC_Read_Byte(void);


 楼主| Tennasi 发表于 2016-1-24 20:11 | 显示全部楼层
IIC实现文件
  1. #include "myiic.h"



  2. void IIC_Delay()
  3. {
  4.     int i;
  5.     for(i=0;i<10;i++);
  6.    
  7. }

  8. //初始化IIC
  9. void IIC_Init(void)
  10. {            
  11.     //Chip_GPIO_Init(LPC_GPIO);
  12.     Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 10,
  13.                          (IOCON_FUNC0 | IOCON_MODE_INACT | IOCON_DIGITAL_EN));
  14.     Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 11,
  15.                          (IOCON_FUNC0 | IOCON_MODE_INACT | IOCON_DIGITAL_EN));
  16.     IIC_SCL_OUT()
  17.     IIC_SDA_OUT()
  18. }
  19. //产生IIC起始信号
  20. void IIC_Start(void)
  21. {
  22.     IIC_SDA_OUT();     //sda线输出
  23.     IIC_SDA_1;            
  24.     IIC_SCL_1;
  25.     IIC_Delay();
  26.      IIC_SDA_0;//START:when CLK is high,DATA change form high to low
  27.     IIC_Delay();
  28.     IIC_SCL_0;//钳住I2C总线,准备发送或接收数据
  29. }

  30. //产生IIC停止信号
  31. void IIC_Stop(void)
  32. {
  33.     IIC_SDA_OUT();//sda线输出
  34.    
  35.     IIC_SDA_0;
  36.     IIC_SCL_1;
  37.      IIC_Delay();
  38.     IIC_SDA_1;
  39.     IIC_Delay();                                   
  40. }
  41. //**************************************
  42. //I2C发送应答信号
  43. //入口参数:ack (0:ACK 1:NAK)
  44. //**************************************
  45. void IIC_SendACK(unsigned char ack)
  46. {
  47.    
  48.                      
  49.     if(ack==1)                    //写应答信号
  50.         IIC_SDA_1
  51.     else
  52.         IIC_SDA_0;
  53.     IIC_SCL_1;                    //拉高时钟线
  54.     IIC_Delay();                 //延时
  55.     IIC_SCL_0;                    //拉低时钟线
  56.     IIC_Delay();                 //延时
  57. }
  58. //**************************************
  59. //I2C接收应答信号
  60. //**************************************
  61. unsigned char IIC_RecvACK(void)
  62. {
  63.     /*
  64.     IIC_SDA_OUT();
  65.     IIC_SCL_0;
  66.     IIC_Delay();
  67.     IIC_SDA_1;
  68.     IIC_Delay();
  69.     IIC_SDA_IN();
  70.     IIC_SCL_1;            //拉高时钟线
  71.     IIC_Delay();                 //延时
  72.     if(IIC_SDA_READ)
  73.     {
  74.         IIC_SCL_0;
  75.         return 0;
  76.     }
  77.     IIC_SCL_0;
  78.     return 1;*/
  79.    
  80.     IIC_SDA_IN();
  81.     IIC_SCL_1;                    //拉高时钟线
  82.     IIC_Delay();                 //延时
  83.     if(IIC_SDA_READ)
  84.     {
  85.         IIC_SCL_0;
  86.         return 0;
  87.     }                //读应答信号
  88.     IIC_SCL_0;                    //拉低时钟线
  89.     IIC_Delay();                 //延时
  90.     return 1;
  91.    
  92.    
  93.    
  94. }
 楼主| Tennasi 发表于 2016-1-24 20:12 | 显示全部楼层
  1. //IIC发送一个字节
  2. //返回从机有无应答
  3. //1,有应答
  4. //0,无应答              
  5. void IIC_Send_Byte(unsigned char dat)
  6. {                        
  7.     unsigned char i,a;   
  8.     IIC_SDA_OUT();
  9.     for (i=0; i<8; i++)         
  10.     {
  11.         a=(dat>>(7-i))&1;
  12.         if(a==1)
  13.             IIC_SDA_1
  14.         else
  15.             IIC_SDA_0;
  16.         IIC_SCL_1;              
  17.         IIC_Delay();           
  18.         IIC_SCL_0;            
  19.         IIC_Delay();         
  20.     }
  21.     //IIC_RecvACK();
  22. }         
  23. //读1个字节   
  24. unsigned char IIC_Read_Byte(void)
  25. {
  26.     unsigned char i,dat=0;
  27.     IIC_SDA_IN();//SDA设置为输入               
  28.     for(i=0;i<8;i++)
  29.     {
  30.         dat<<=1;
  31.         IIC_SCL_1;
  32.         IIC_Delay();
  33.         if(IIC_SDA_READ==1)
  34.             dat|=1;
  35.         else
  36.             dat|=0;
  37.         IIC_SCL_0;
  38.         IIC_Delay();
  39.     }
  40.     IIC_SDA_OUT();

  41.     return dat;
  42. }

ideafor 发表于 2016-1-25 21:09 | 显示全部楼层
这个是用模拟方式写的,用这个IIC_delay是不是影响速度
和硬件相比速度有什么缺陷
您需要登录后才可以回帖 登录 | 注册

本版积分规则

22

主题

169

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部