mpu6050.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  1. /****************************************************************************
  2. * 文 件 名: mpu6050.c
  3. * 作 者: 小浩电子科技
  4. * 修 订: 2020-04-27
  5. * 版 本: 1.0
  6. * 描 述: mpu6050的驱动程序
  7. ****************************************************************************/
  8. #include <ioCC2530.h>
  9. #include "MPU6050.h"
  10. #define I2C_PORT_NUM 1
  11. #define BUFSIZE 14 //确认大小够不够
  12. //函数声明
  13. void DelayI2C(uint32_t m);
  14. void MPU6050_Read(unsigned char SlaveAddress,unsigned char REG_Address,unsigned char readNum);
  15. unsigned char MPU6050_Read_1BYTE(unsigned char SlaveAddress,unsigned char REG_Address);
  16. void MPU6050_Write(unsigned char SlaveAddress,unsigned char REG_Address,unsigned char REG_data) ;
  17. void MPU6050_WriteBit(uint8_t slaveAddr, uint8_t regAddr, uint8_t bitNum, uint8_t data) ;
  18. void MPU6050_ReadBits(uint8_t slaveAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t *data) ;
  19. void MPU6050_Initialize(void);
  20. void MPU6050_Initialize(void);
  21. void accStop(void);
  22. void accWriteReg(uint8 reg, uint8 val);
  23. void accReadReg(uint8 reg, uint8 *pVal);
  24. void accReadAcc(int8 *pXVal, int8 *pYVal, int8 *pZVal);
  25. uint8_t MPU6050_GetDeviceID();
  26. void accReadAccGro(int16_t *pXAcc, int16_t *pYAcc, int16_t *pZAcc, int16_t *pXGro, int16_t *pYGro, int16_t *pZGro);
  27. volatile uint8_t I2CMasterBuffer[I2C_PORT_NUM][BUFSIZE]={0};
  28. volatile uint8_t I2CSlaveBuffer[I2C_PORT_NUM][BUFSIZE]={0};
  29. volatile uint32_t I2CReadLength[I2C_PORT_NUM]={0};
  30. volatile uint32_t I2CWriteLength[I2C_PORT_NUM]={0};
  31. //函数声明
  32. uchar MPU6050_Read_Byte(void);
  33. void MPU6050_IIC_Init(void);//IIC初始化
  34. void MPU6050_Signal_Start(void);//IIC起始信号
  35. void MPU6050_Signal_Stop(void);//IIC停止信号
  36. void MPU6050_Write_Byte(uchar wdata);
  37. void MPU6050_Respons(void);//答应信号
  38. void MPU6050_Write_Addr(uchar add,uchar wdata,uchar comd);
  39. uchar MPU6050_Read_Addr(uchar add,uchar comd);
  40. void MPU6050_IIC_Init(void)//IIC初始化
  41. {
  42. MPU6050_SDA_PIN_OUT(); //P1.5、P1.6定义为输出
  43. MPU6050_SCL_PIN_OUT();
  44. MPU6050_SDA_PIN = 1;
  45. system_delay_us(1000);
  46. MPU6050_SCL_PIN = 1;
  47. system_delay_us(1000);
  48. }
  49. void MPU6050_Signal_Start(void)//IIC起始信号
  50. {
  51. MPU6050_SCL_PIN_OUT(); //P1.5、P1.6定义为输出
  52. MPU6050_SDA_PIN_OUT();
  53. MPU6050_SDA_PIN = 1;
  54. system_delay_us(1000);
  55. MPU6050_SCL_PIN = 1;
  56. system_delay_us(1000);
  57. MPU6050_SDA_PIN = 0;
  58. system_delay_us(1000);
  59. }
  60. void MPU6050_Signal_Stop(void)//IIC停止信号
  61. {
  62. MPU6050_SCL_PIN_OUT(); //P1.5、P1.6定义为输出
  63. MPU6050_SDA_PIN_OUT();
  64. MPU6050_SDA_PIN = 0;
  65. system_delay_us(1000);
  66. MPU6050_SCL_PIN = 1;
  67. system_delay_us(1000);
  68. MPU6050_SDA_PIN = 1;
  69. system_delay_us(1000);
  70. }
  71. void MPU6050_Respons(void)//答应信号
  72. {
  73. uint i = 0;
  74. MPU6050_SCL_PIN_OUT(); //P1.5定义为输出
  75. MPU6050_SDA_PIN_IN(); //P1.6定义为输入
  76. MPU6050_SCL_PIN = 1;
  77. system_delay_us(1000);
  78. MPU6050_SCL_PIN = 0;
  79. system_delay_us(1000);
  80. if(i>=300)
  81. {
  82. system_delay_us(1000);
  83. }
  84. }
  85. void MPU6050_Write_Byte(uchar wdata)
  86. {
  87. uchar i,mdata;
  88. MPU6050_SCL_PIN_OUT(); //P1.5、P1.6定义为输出
  89. MPU6050_SDA_PIN_OUT();
  90. mdata = wdata;
  91. for(i=0;i<8;i++)
  92. {
  93. MPU6050_SCL_PIN = 0;
  94. system_delay_us(1000);
  95. if(mdata & 0x80)
  96. {
  97. MPU6050_SDA_PIN = 1;
  98. }
  99. else
  100. {
  101. MPU6050_SDA_PIN = 0;
  102. }
  103. system_delay_us(1000);
  104. MPU6050_SCL_PIN = 1;
  105. system_delay_us(1000);
  106. mdata <<= 1;
  107. }
  108. MPU6050_SCL_PIN = 0;
  109. system_delay_us(1000);
  110. MPU6050_SCL_PIN = 1;
  111. system_delay_us(1000);
  112. }
  113. uchar MPU6050_Read_Byte(void)
  114. {
  115. uchar i,rdata = 0;
  116. MPU6050_SCL_PIN_OUT(); //P1.5定义为输出
  117. MPU6050_SDA_PIN_IN(); //P1.6定义为输入
  118. MPU6050_SCL_PIN = 0;
  119. system_delay_us(1000);
  120. MPU6050_SCL_PIN = 1;
  121. for(i=0;i<8;i++)
  122. {
  123. MPU6050_SCL_PIN = 1;
  124. system_delay_us(1000);
  125. rdata = (rdata<<1)|MPU6050_SDA_PIN;
  126. MPU6050_SCL_PIN = 0;
  127. system_delay_us(1000);
  128. }
  129. return rdata;
  130. }
  131. void MPU6050_Write_Addr(uchar add,uchar wdata,uchar comd)
  132. {
  133. MPU6050_Signal_Start(); //产生一个起始信号
  134. MPU6050_Write_Byte(comd);
  135. MPU6050_Respons(); //等待答应
  136. MPU6050_Write_Byte(add);
  137. MPU6050_Respons(); //等待答应
  138. MPU6050_Write_Byte(wdata);
  139. MPU6050_Respons(); //等待答应
  140. MPU6050_Signal_Stop(); //产生一个终止信号
  141. }
  142. uchar MPU6050_Read_Addr(uchar add,uchar comd)
  143. {
  144. uchar tdata;
  145. MPU6050_Signal_Start(); //产生一个起始信号
  146. MPU6050_Write_Byte(comd);
  147. MPU6050_Respons(); //等待答应
  148. MPU6050_Write_Byte(add);
  149. MPU6050_Respons(); //等待答应
  150. MPU6050_Signal_Start(); //再产生一个起始信号
  151. MPU6050_Write_Byte(comd|0x01);
  152. MPU6050_Respons(); //等待答应
  153. tdata = MPU6050_Read_Byte();
  154. MPU6050_Signal_Stop(); //产生一个终止信号
  155. return tdata;
  156. }
  157. void DelayI2C(uint32_t m)
  158. {
  159. uint32_t i;
  160. for(; m != 0; m--)
  161. for (i=0; i<5; i++);
  162. }
  163. void MPU6050_Read(unsigned char SlaveAddress,unsigned char REG_Address,unsigned char readNum)
  164. {
  165. unsigned char i;
  166. for(i = 0; i<readNum; i++)
  167. {
  168. //读某个IIC器件的数据
  169. I2CSlaveBuffer[PORT_USED][i] = MPU6050_Read_Addr(REG_Address + i, SlaveAddress);
  170. }
  171. }
  172. unsigned char MPU6050_Read_1BYTE(unsigned char SlaveAddress,unsigned char REG_Address)
  173. {
  174. return MPU6050_Read_Addr(REG_Address, SlaveAddress);
  175. }
  176. void MPU6050_Write(unsigned char SlaveAddress,unsigned char REG_Address,unsigned char REG_data)
  177. {
  178. //向某个IIC器件写指令读某个地址里面的数据
  179. MPU6050_Write_Addr(REG_Address, REG_data, SlaveAddress);
  180. }
  181. /**写入8位寄存器的多个位。
  182. * @参数 slaveAddr I2C从器件内部地址
  183. * @参数 bitStart 第一位的写入位置(0-7)
  184. * @参数 length 写的比特数(不超过8)
  185. * @参数 Data 写入数据
  186. * @返回值 返回状态 (1=成功)
  187. */
  188. void MPU6050_WriteBits(uint8_t slaveAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t data)
  189. {
  190. // 010 value to write
  191. // 76543210 bit numbers
  192. // xxx args: bitStart=4, length=3
  193. // 00011100 mask byte
  194. // 10101111 original value (sample)
  195. // 10100011 original & ~mask
  196. // 10101011 masked | value
  197. // 010 要写入的值
  198. // 76543210 比特位
  199. // xxx args: bitStart=4, length=3
  200. // 00011100 掩码字节
  201. // 10101111 原始值(样本)
  202. // 10100011 原始值 & ~掩码
  203. // 10101011 掩码 | 原始值
  204. uint8_t tmp;
  205. uint8_t mask = ((1 << length) - 1) << (bitStart - length + 1);
  206. MPU6050_Read(slaveAddr, regAddr, 1);
  207. tmp = I2CSlaveBuffer[PORT_USED][0];
  208. // uint8_t mask = ((1 << length) - 1) << (bitStart - length + 1);
  209. data <<= (bitStart - length + 1); // shift data into correct position
  210. data &= mask; // zero all non-important bits in data
  211. tmp &= ~(mask); // zero all important bits in existing byte
  212. tmp |= data; // combine data with existing byte
  213. MPU6050_Write(slaveAddr,regAddr,tmp);
  214. }
  215. void MPU6050_WriteBit(uint8_t slaveAddr, uint8_t regAddr, uint8_t bitNum, uint8_t data)
  216. {
  217. uint8_t tmp;
  218. MPU6050_Read(slaveAddr, regAddr, 1);
  219. tmp = I2CSlaveBuffer[PORT_USED][0];
  220. tmp = (data != 0) ? (tmp | (1 << bitNum)) : (tmp & ~(1 << bitNum));
  221. MPU6050_Write(slaveAddr,regAddr,tmp);
  222. }
  223. /**读取8位寄存器的多个位。
  224. * @参数 addr I2C从器件内部地址
  225. * @参数 bitStart第一位的位置读取(0-7)
  226. * @参数 length 位读取@参数长度数(不超过8)
  227. * @参数 *data 数据存储地址(即'101'任何bitStart位置读取将等于0X05)
  228. * @返回值(1=成功)
  229. */
  230. void MPU6050_ReadBits(uint8_t slaveAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t *data)
  231. {
  232. // 01101001 read byte
  233. // 76543210 bit numbers
  234. // xxx args: bitStart=4, length=3
  235. // 010 masked
  236. // -> 010 shifted
  237. #if 1 // 这里采取了去除屏蔽的位并且右移动
  238. uint8_t tmp;
  239. uint8_t mask = ((1 << length) - 1) << (bitStart - length + 1);
  240. MPU6050_Read(slaveAddr, regAddr, 1);
  241. tmp = I2CSlaveBuffer[PORT_USED][0];
  242. // uint8_t mask = ((1 << length) - 1) << (bitStart - length + 1);
  243. tmp &= mask;
  244. tmp >>= (bitStart - length + 1);
  245. *data = tmp;
  246. #else
  247. uint8_t tmp;
  248. MPU6050_Read(slaveAddr, regAddr, 1);
  249. tmp = I2CSlaveBuffer[PORT_USED][0];
  250. *data = tmp;
  251. #endif
  252. }
  253. void MPU6050_Initialize(void)
  254. {
  255. MPU6050_WriteBits(MPU6050_DEFAULT_ADDRESS, MPU6050_RA_PWR_MGMT_1,
  256. MPU6050_PWR1_CLKSEL_BIT, MPU6050_PWR1_CLKSEL_LENGTH, MPU6050_CLOCK_PLL_XGYRO);
  257. MPU6050_WriteBits(MPU6050_DEFAULT_ADDRESS, MPU6050_RA_GYRO_CONFIG, //设置陀螺仪 量程 ,量程范围 250 /s
  258. MPU6050_GCONFIG_FS_SEL_BIT, MPU6050_GCONFIG_FS_SEL_LENGTH, MPU6050_GYRO_FS_250);
  259. // MPU6050_WriteBits(MPU6050_DEFAULT_ADDRESS, MPU6050_RA_ACCEL_CONFIG,//设置加速度 量程
  260. // MPU6050_ACONFIG_AFS_SEL_BIT, MPU6050_ACONFIG_AFS_SEL_LENGTH, MPU6050_ACCEL_FS_2);// ±2g
  261. MPU6050_WriteBits(MPU6050_DEFAULT_ADDRESS, MPU6050_RA_ACCEL_CONFIG,//设置加速度 量程
  262. MPU6050_ACONFIG_AFS_SEL_BIT, MPU6050_ACONFIG_AFS_SEL_LENGTH, MPU6050_ACCEL_FS_16);// ±16g
  263. MPU6050_WriteBit(MPU6050_DEFAULT_ADDRESS, MPU6050_RA_PWR_MGMT_1, MPU6050_PWR1_SLEEP_BIT, 0);//(DISABLE);
  264. }
  265. uint8_t MPU6050_GetDeviceID()
  266. {
  267. uint8_t tmp;
  268. MPU6050_ReadBits(MPU6050_DEFAULT_ADDRESS, MPU6050_RA_WHO_AM_I, \
  269. MPU6050_WHO_AM_I_BIT, MPU6050_WHO_AM_I_LENGTH, &tmp);
  270. return tmp<<(MPU6050_WHO_AM_I_BIT-MPU6050_WHO_AM_I_LENGTH+1); // 注意这里的移位 amomcu
  271. }
  272. //加速度测量, 温度测量, 陀螺仪测量
  273. void MPU6050_GetRawAccelGyro(int16_t* ax, int16_t* ay, int16_t* az, int16_t* temperature, int16_t* gx, int16_t* gy, int16_t* gz)
  274. {
  275. // u8 tmpBuffer[14];
  276. //int i;
  277. MPU6050_Read(MPU6050_DEFAULT_ADDRESS, MPU6050_RA_ACCEL_XOUT_H, 14);
  278. /* Get acceleration */
  279. // for(i=0; i<3; i++)
  280. // AccelGyro[i]=((int16_t)((uint16_t)I2CSlaveBuffer[PORT_USED][2*i] << 8) + I2CSlaveBuffer[PORT_USED][2*i+1]);
  281. /* Get Angular rate */
  282. // for(i=4; i<7; i++)
  283. // AccelGyro[i-1]=((int16_t)((uint16_t)I2CSlaveBuffer[PORT_USED][2*i] << 8) + I2CSlaveBuffer[PORT_USED][2*i+1]);
  284. *ax = (((int16_t)I2CSlaveBuffer[PORT_USED][0]) << 8) | ((int16_t)I2CSlaveBuffer[PORT_USED][1]);
  285. *ay = (((int16_t)I2CSlaveBuffer[PORT_USED][2]) << 8) | ((int16_t)I2CSlaveBuffer[PORT_USED][3]);
  286. *az = (((int16_t)I2CSlaveBuffer[PORT_USED][4]) << 8) | ((int16_t)I2CSlaveBuffer[PORT_USED][5]);
  287. // 温度
  288. *temperature = (((int16_t)I2CSlaveBuffer[PORT_USED][6]) << 8) | ((int16_t)I2CSlaveBuffer[PORT_USED][7]);
  289. *gx = (((int16_t)I2CSlaveBuffer[PORT_USED][8]) << 8) | ((int16_t)I2CSlaveBuffer[PORT_USED][9]);
  290. *gy = (((int16_t)I2CSlaveBuffer[PORT_USED][10]) << 8) | ((int16_t)I2CSlaveBuffer[PORT_USED][11]);
  291. *gz = (((int16_t)I2CSlaveBuffer[PORT_USED][12]) << 8) | ((int16_t)I2CSlaveBuffer[PORT_USED][13]);
  292. }
  293. #if 1
  294. uint8_t bIfConnected = 0; //是否 mpu6050 已经读到标志位
  295. void accInit(void)
  296. {
  297. unsigned char tempV = 0;
  298. MPU6050_IIC_Init(); //IIC初始化
  299. tempV = MPU6050_GetDeviceID();
  300. if(tempV == MPU6050_ADDRESS_AD0_LOW) //测试是否 mpu6050 已经读到
  301. {
  302. bIfConnected = 1;
  303. }
  304. else
  305. {
  306. bIfConnected = 0;
  307. }
  308. if(bIfConnected)
  309. {
  310. //mpu6050连接成功
  311. //初始化mpu6050
  312. MPU6050_Initialize();
  313. //读取mpu6050的实时数据
  314. //MPU6050_GetRawAccelGyro(&ax, &ay, &az, &gx, &gy, &gz);
  315. //sprintf(strTemp, "%d %d %d : %d %d %d", ax, ay, az, gx, gy, gz);
  316. //串口打印该数据
  317. //UartSendString(strTemp, strlen(strTemp));
  318. }
  319. }
  320. void accStop(void)
  321. {
  322. }
  323. void accWriteReg(uint8 reg, uint8 val)
  324. {
  325. if(bIfConnected)
  326. {
  327. MPU6050_Write(0x68<<1, reg, val);
  328. }
  329. }
  330. void accReadReg(uint8 reg, uint8 *pVal)
  331. {
  332. if(bIfConnected)
  333. {
  334. *pVal = MPU6050_Read_1BYTE(0x68<<1, reg);
  335. }
  336. }
  337. void accReadAcc(int8 *pXVal, int8 *pYVal, int8 *pZVal)
  338. {
  339. int16_t ax, ay, az;
  340. int16_t gx, gy, gz;
  341. int16_t temperature;
  342. if(bIfConnected)
  343. {
  344. //读取mpu6050的实时数据
  345. MPU6050_GetRawAccelGyro(&ax, &ay, &az, &temperature, &gx, &gy, &gz);
  346. *pXVal = ax/100;
  347. *pYVal = ay/100;
  348. *pZVal = az/100;
  349. }
  350. }
  351. //void accReadAccGro(int8 *pXAcc, int8 *pYAcc, int8 *pZAcc, int8 *pXGro, int8 *pYGro, int8 *pZGro)
  352. //{
  353. // int16_t ax, ay, az;
  354. // int16_t gx, gy, gz;
  355. // int16_t temperature;
  356. // if(bIfConnected)
  357. // {
  358. // //读取mpu6050的实时数据
  359. // MPU6050_GetRawAccelGyro(&ax, &ay, &az, &temperature, &gx, &gy, &gz);
  360. //
  361. // *pXAcc = ax/100;
  362. // *pYAcc = ay/100;
  363. // *pZAcc = az/100;
  364. //
  365. // *pXGro = gx/100;
  366. // *pYGro = gy/100;
  367. // *pZGro = gz/100;
  368. // }
  369. //}
  370. void accReadAccGro(int16_t *pXAcc, int16_t *pYAcc, int16_t *pZAcc, int16_t *pXGro, int16_t *pYGro, int16_t *pZGro)
  371. {
  372. int16_t ax, ay, az;
  373. int16_t gx, gy, gz;
  374. int16_t temperature;
  375. if(bIfConnected)
  376. {
  377. //读取mpu6050的实时数据
  378. MPU6050_GetRawAccelGyro(&ax, &ay, &az, &temperature, &gx, &gy, &gz);
  379. *pXAcc = ax; //加速度
  380. *pYAcc = ay;
  381. *pZAcc = az;
  382. *pXGro = gx;//陀螺仪
  383. *pYGro = gy;
  384. *pZGro = gz;
  385. }
  386. }
  387. #endif