STM32与MPC-6050通讯

来源:互联网 发布:語音英文软件 编辑:程序博客网 时间:2024/05/22 01:56

网上少有STM32与MPC-6050通讯的介绍,可以用的代码就更少了。辛苦了几天,终于将其调通,共享出来与大家分享。

 

什么都不说了,直接上代码,大家看注释就行了:

 

i2c.h

[cpp] view plaincopy
  1. #ifndef __I2C_H  
  2. #define __I2C_H  
  3. #include "sys.h"  
  4.                  
  5. //IO方向设置  
  6. #define SDA_IN()  {GPIOB->CRH&=0XFFFF0FFF;GPIOB->CRH|=8<<12;}  
  7. #define SDA_OUT() {GPIOB->CRH&=0XFFFF0FFF;GPIOB->CRH|=3<<12;}  
  8. //IO操作函数       
  9. #define IIC_SCL    PBout(10) //SCL  
  10. #define IIC_SDA    PBout(11) //SDA     
  11. #define READ_SDA   PBin(11)  //输入SDA   
  12. //IIC所有操作函数  
  13. void IIC_Init(void);                //初始化IIC的IO口                   
  14. void IIC_Start(void);               //发送IIC开始信号  
  15. void IIC_Stop(void);                //发送IIC停止信号  
  16. void IIC_Send_Byte(u8 txd);         //IIC发送一个字节  
  17. u8 IIC_Read_Byte(unsigned char ack);//IIC读取一个字节  
  18. u8 IIC_Wait_Ack(void);              //IIC等待ACK信号  
  19. void IIC_Ack(void);                 //IIC发送ACK信号  
  20. void IIC_NAck(void);                //IIC不发送ACK信号  
  21. void IIC_Write_One_Byte(u8 daddr,u8 addr,u8 data);  
  22. u8 IIC_Read_One_Byte(u8 daddr,u8 addr);     
  23. #endif  


i2c.c

[cpp] view plaincopy
  1. #include "i2c.h"  
  2. #include "delay.h"  
  3.   
  4. //初始化IIC  
  5. void IIC_Init(void)  
  6. {                          
  7.     RCC->APB2ENR|=1<<3;//先使能外设IO PORTB时钟                              
  8.     GPIOB->CRH&=0XFFFF00FF;//PB10/11 推挽输出  
  9.     GPIOB->CRH|=0X00003300;       
  10.     GPIOB->ODR|=3<<10;     //PB10/11 输出高  
  11. }  
  12. //产生IIC起始信号  
  13. void IIC_Start(void)  
  14. {  
  15.     SDA_OUT();     //sda线输出  
  16.     IIC_SDA=1;          
  17.     IIC_SCL=1;  
  18.     delay_us(5);  
  19.     IIC_SDA=0;//START:when CLK is high,DATA change form high to low   
  20.     delay_us(5);  
  21.     IIC_SCL=0;//钳住I2C总线,准备发送或接收数据   
  22. }       
  23. //产生IIC停止信号  
  24. void IIC_Stop(void)  
  25. {  
  26.     SDA_OUT();//sda线输出  
  27.     IIC_SCL=0;  
  28.     IIC_SDA=0;//STOP:when CLK is high DATA change form low to high  
  29.     delay_us(5);  
  30.     IIC_SCL=1;   
  31.     IIC_SDA=1;//发送I2C总线结束信号  
  32.     delay_us(5);                                  
  33. }  
  34. //等待应答信号到来  
  35. //返回值:1,接收应答失败  
  36. //        0,接收应答成功  
  37. u8 IIC_Wait_Ack(void)  
  38. {  
  39.     u8 ucErrTime=0;  
  40.     SDA_IN();      //SDA设置为输入    
  41.     IIC_SDA=1;delay_us(5);       
  42.     IIC_SCL=1;delay_us(5);     
  43.     while(READ_SDA)  
  44.     {  
  45.         ucErrTime++;  
  46.         if(ucErrTime>250)  
  47.         {  
  48.             IIC_Stop();  
  49.             return 1;  
  50.         }  
  51.     }  
  52.     IIC_SCL=0;//时钟输出0        
  53.     return 0;    
  54. }   
  55. //产生ACK应答  
  56. void IIC_Ack(void)  
  57. {  
  58.     IIC_SCL=0;  
  59.     SDA_OUT();  
  60.     IIC_SDA=0;  
  61.     delay_us(5);  
  62.     IIC_SCL=1;  
  63.     delay_us(5);  
  64.     IIC_SCL=0;  
  65. }  
  66. //不产生ACK应答            
  67. void IIC_NAck(void)  
  68. {  
  69.     IIC_SCL=0;  
  70.     SDA_OUT();  
  71.     IIC_SDA=1;  
  72.     delay_us(5);  
  73.     IIC_SCL=1;  
  74.     delay_us(5);  
  75.     IIC_SCL=0;  
  76. }                                          
  77. //IIC发送一个字节  
  78. //返回从机有无应答  
  79. //1,有应答  
  80. //0,无应答             
  81. void IIC_Send_Byte(u8 txd)  
  82. {                          
  83.     u8 t;     
  84.     SDA_OUT();        
  85.     IIC_SCL=0;//拉低时钟开始数据传输  
  86.     for(t=0;t<8;t++)  
  87.     {                
  88.         IIC_SDA=(txd&0x80)>>7;  
  89.         txd<<=1;      
  90.         delay_us(5);   //对TEA5767这三个延时都是必须的  
  91.         IIC_SCL=1;  
  92.         delay_us(5);   
  93.         IIC_SCL=0;    
  94.         delay_us(5);  
  95.     }      
  96. }         
  97. //读1个字节,ack=1时,发送ACK,ack=0,发送nACK     
  98. u8 IIC_Read_Byte(unsigned char ack)  
  99. {  
  100.     unsigned char i,receive=0;  
  101.     SDA_IN();//SDA设置为输入  
  102.     for(i=0;i<8;i++ )  
  103.     {  
  104.         IIC_SCL=0;   
  105.         delay_us(5);  
  106.         IIC_SCL=1;  
  107.         receive<<=1;  
  108.         if(READ_SDA)receive++;     
  109.         delay_us(5);   
  110.     }                      
  111.     if (!ack)  
  112.         IIC_NAck();//发送nACK  
  113.     else  
  114.         IIC_Ack(); //发送ACK     
  115.     return receive;  
  116. }  


mpc6050.h

[cpp] view plaincopy
  1. #ifndef __MPU6050_H  
  2. #define __MPU6050_H  
  3. #include "sys.h"  
  4.   
  5. //****************************************  
  6. // 定义MPU6050内部地址  
  7. //****************************************  
  8. #define SMPLRT_DIV      0x19    //陀螺仪采样率,典型值:0x07(125Hz)  
  9. #define CONFIG          0x1A    //低通滤波频率,典型值:0x06(5Hz)  
  10. #define GYRO_CONFIG     0x1B    //陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s)  
  11. #define ACCEL_CONFIG    0x1C    //加速计自检、测量范围及高通滤波频率,典型值:0x01(不自检,2G,5Hz)  
  12. #define ACCEL_XOUT_H    0x3B  
  13. #define ACCEL_XOUT_L    0x3C  
  14. #define ACCEL_YOUT_H    0x3D  
  15. #define ACCEL_YOUT_L    0x3E  
  16. #define ACCEL_ZOUT_H    0x3F  
  17. #define ACCEL_ZOUT_L    0x40  
  18. #define TEMP_OUT_H      0x41  
  19. #define TEMP_OUT_L      0x42  
  20. #define GYRO_XOUT_H     0x43  
  21. #define GYRO_XOUT_L     0x44      
  22. #define GYRO_YOUT_H     0x45  
  23. #define GYRO_YOUT_L     0x46  
  24. #define GYRO_ZOUT_H     0x47  
  25. #define GYRO_ZOUT_L     0x48  
  26. #define PWR_MGMT_1      0x6B    //电源管理,典型值:0x00(正常启用)  
  27. #define WHO_AM_I        0x75    //IIC地址寄存器(默认数值0x68,只读)  
  28. #define SlaveAddress    0xD0    //IIC写入时的地址字节数据,+1为读取  
  29.                       
  30. #define MPU_60X0_PWR_MGMT_1_REG_ADDR        0x6B  
  31. #define MPU_60X0_USER_CTRL_REG_ADDR         0x6A  
  32. #define MPU_60X0_SMPLRT_DIV_REG_ADDR        0x19  
  33. #define MPU_60X0_CONFIG_REG_ADDR            0x1A  
  34. #define MPU_60X0_GYRO_CONFIG_REG_ADDR       0x1B  
  35. #define MPU_60X0_ACCEL_CONFIG_REG_ADDR      0x1C  
  36. #define MPU_60X0_FIFO_EN_REG_ADDR           0x23  
  37.   
  38. #define MPU_60X0_RESET_REG_VALU             0x80  
  39. #define MPU_60X0_PWR_MGMT_1_REG_VALU        0x09    // Disable temperature sensor, PLL with X axis gyroscope reference  
  40. #define MPU_60X0_USER_CTRL_REG_VALU         0x45    // Enable FIFO. Reset FIFO and signal paths for all sensors  
  41. #define MPU_60X0_SMPLRT_DIV_REG_VALU        0x00    // DLPF_CFG is 0x01, so Gyroscope Output Rate = 1kHz, divided by 1, still 1kHz  
  42. #define MPU_60X0_CONFIG_REG_VALU            0x03    // 184Hz 2.0ms 188Hz 1.9ms 1kHz. So there will be 6x2 bytes new data in FIFO every 1ms  
  43. #define MPU_60X0_GYRO_CONFIG_REG_VALU       0x08    // Gyroscope works at 500dps. If selftest is needed, REMEMBER to put this to 250dps  
  44. #define MPU_60X0_ACCEL_CONFIG_REG_VALU      0x08    // Accelerometer works at 4g range. If selftest is needed, REMEMBER to put this to 8g range  
  45. #define MPU_60X0_FIFO_EN_REG_VALU           0x78    // Only enable accel and gyro  
  46.   
  47. extern u16 delayTime;  
  48.   
  49. void Single_WriteI2C(u8 REG_Address,u8 REG_data);  
  50. u8 Single_ReadI2C(u8 REG_Address);  
  51. void InitMPU6050(void);  
  52. u16 GetData(u8 REG_Address);  
  53. void I2C1_WriteByte(u8 REG_Address,u8 REG_data);  
  54. u8 I2C1_ReadByte(u8 DataAddr);  
  55.   
  56. void SetDelayTime(u16 delayMs);  
  57. #endif  


mpc6050.c

[cpp] view plaincopy
  1. #include "delay.h"  
  2. #include "mpu6050.h"  
  3. #include "i2c.h"  
  4.   
  5. u16 delayTime = 1000;  
  6.   
  7. //**************************************  
  8. //向I2C设备写入一个字节数据  
  9. //**************************************  
  10. void Single_WriteI2C(u8 REG_Address,u8 REG_data)  
  11. {  
  12.     IIC_Start();                  //起始信号  
  13.     IIC_Send_Byte(SlaveAddress);   //发送设备地址+写信号  
  14.     IIC_Wait_Ack();   
  15.     IIC_Send_Byte(REG_Address);    //内部寄存器地址,  
  16.     IIC_Wait_Ack();   
  17.     IIC_Send_Byte(REG_data);       //内部寄存器数据,  
  18.     IIC_Wait_Ack();   
  19.     IIC_Stop();                   //发送停止信号  
  20. }  
  21. //**************************************  
  22. //从I2C设备读取一个字节数据  
  23. //**************************************  
  24. u8 Single_ReadI2C(u8 REG_Address)  
  25. {  
  26.     u8 REG_data;  
  27.     IIC_Start();                   //起始信号  
  28.     IIC_Send_Byte(SlaveAddress);    //发送设备地址+写信号  
  29.     IIC_Wait_Ack();  
  30.     IIC_Send_Byte(REG_Address);     //发送存储单元地址,从0开始   
  31.     IIC_Wait_Ack();  
  32.     IIC_Start();                   //起始信号  
  33.     IIC_Send_Byte(SlaveAddress+1);  //发送设备地址+读信号  
  34.     IIC_Wait_Ack();  
  35.     REG_data=IIC_Read_Byte(0);       //读出寄存器数据  
  36.     //IIC_SendAck();                //接收应答信号  
  37.     IIC_Stop();                    //停止信号  
  38.     return REG_data;  
  39. }  
  40.   
  41.   
  42. //**************************************  
  43. //初始化MPU6050  
  44. //**************************************  
  45. void InitMPU6050()  
  46. {  
  47. /*  
  48.     Single_WriteI2C(PWR_MGMT_1, 0x00);  //解除休眠状态  
  49.     Single_WriteI2C(SMPLRT_DIV, 0x07);  
  50.     Single_WriteI2C(CONFIG, 0x06);  
  51.     Single_WriteI2C(GYRO_CONFIG, 0x18);  
  52.     Single_WriteI2C(ACCEL_CONFIG, 0x01);  
  53. */  
  54.     u32 i;  
  55.     Single_WriteI2C(MPU_60X0_PWR_MGMT_1_REG_ADDR, MPU_60X0_RESET_REG_VALU);   
  56.     for (i = 0; i < 20000; i++)  
  57.     {  
  58.         delay_us(5);        //上电延时        
  59.     }  
  60.     Single_WriteI2C(MPU_60X0_PWR_MGMT_1_REG_ADDR, MPU_60X0_PWR_MGMT_1_REG_VALU);  
  61.     Single_WriteI2C(MPU_60X0_USER_CTRL_REG_ADDR, MPU_60X0_USER_CTRL_REG_VALU);  
  62.     Single_WriteI2C(MPU_60X0_SMPLRT_DIV_REG_ADDR, MPU_60X0_SMPLRT_DIV_REG_VALU);  
  63.     Single_WriteI2C(MPU_60X0_CONFIG_REG_ADDR, MPU_60X0_CONFIG_REG_VALU);  
  64.     Single_WriteI2C(MPU_60X0_GYRO_CONFIG_REG_ADDR, MPU_60X0_GYRO_CONFIG_REG_VALU);  
  65.     Single_WriteI2C(MPU_60X0_ACCEL_CONFIG_REG_ADDR, MPU_60X0_ACCEL_CONFIG_REG_VALU);  
  66.     Single_WriteI2C(MPU_60X0_FIFO_EN_REG_ADDR, MPU_60X0_FIFO_EN_REG_VALU);  
  67.   
  68. }  
  69. //**************************************  
  70. //合成数据  
  71. //**************************************  
  72. u16 GetData(u8 REG_Address)  
  73. {  
  74.     u8 H,L;  
  75.     H=Single_ReadI2C(REG_Address);  
  76.     L=Single_ReadI2C(REG_Address+1);  
  77.     return (H<<8)+L;   //合成数据  
  78. }  
  79.   
  80. void SetDelayTime(u16 delayMs)  
  81. {  
  82.     delayTime = delayMs;  
  83. }