久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 8576|回復(fù): 1
打印 上一主題 下一主題
收起左側(cè)

基于STM8L的MPU6050數(shù)據(jù)分析(上)

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:140343 發(fā)表于 2016-10-9 23:48 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
MPU6050包含了加速度和角速度傳感器,通過(guò)STM8L的I2C可以讀取到這些加速度和角速度數(shù)據(jù).
讀取到的數(shù)據(jù)是MPU6050的內(nèi)部AD在加速度和角速度的X,Y,Z軸的AD采樣值.根據(jù) RX = ADCRx采樣值/靈敏度 ,可以求出各軸的實(shí)際物理值.

對(duì)于靈敏度,拿加速度計(jì)來(lái)說(shuō),如果設(shè)置MPU6050的加速度量程是+-2G,為了表示+2G~-2G這樣一個(gè)范圍,規(guī)定16位的寄存器最高位是符號(hào)位,表示正負(fù),剩下的15位表示數(shù)據(jù).因?yàn)?^15=32768,所以當(dāng)寄存器中的數(shù)據(jù)為32768時(shí),表示+2G,同樣-32768表示-2G.1G應(yīng)該是16384,所以+-2G的量程下,靈敏度為16384.
例如,當(dāng)加速度的X軸讀取到的數(shù)據(jù)是-16384,因?yàn)?16384/16384=-1,所以此時(shí)x軸的加速度為-1G.
如何根據(jù)加速度計(jì)各個(gè)軸的輸出計(jì)算此時(shí)的角度呢?


如上圖,加速度的y軸不動(dòng),x軸繞其旋轉(zhuǎn)一定的角度a,這個(gè)角度是x軸與水平面的夾角.
上圖中的g是重力加速度,當(dāng)MPU6050按照上圖傾斜一定角度a時(shí),此時(shí)重力加速度在gz和gx方向上各有一個(gè)分力.根據(jù)物理中的力的分解合成,gx和gz上的分力合合成重力.
因?yàn)橹亓方向與水平面垂直,所以a+b=90°
因?yàn)間z軸和gx軸垂直,所以c+b=90°
綜上c=a
根據(jù)重力合成,c和d是相等的.所以角a和角d是相等的.
tan(d)=gx/gz,即tan(a)=gx/gz
為了求角a,我們可以根據(jù)mpu6050的輸出數(shù)據(jù)得到gx/gz的比值,再根據(jù)數(shù)學(xué)公式中的反正切,就可以求出此時(shí)的角度值.
當(dāng)加速度的x軸不動(dòng),y軸繞其旋轉(zhuǎn)一定的角度a時(shí),通過(guò)同樣的方法也可以求出此時(shí)的角度.
通過(guò)上面的分析,我們可以通過(guò)mpu6050或其他一些具有加速度計(jì)的傳感器,獲取物體在靜止時(shí),在x軸方向和y軸方向與水平面的夾角.
之所以說(shuō)是靜止,是因?yàn)檫\(yùn)動(dòng)時(shí)會(huì)有運(yùn)動(dòng)加速度,這對(duì)角度的測(cè)量會(huì)產(chǎn)生干擾,所以角速度傳感器測(cè)量角度會(huì)存在易受運(yùn)動(dòng)影響的干擾.


角速度傳感器同樣是為了獲得角度,角速度是單位時(shí)間內(nèi)旋轉(zhuǎn)過(guò)的角度,注定這是一個(gè)動(dòng)態(tài)的物理量,物體靜止時(shí),角速度為0.如上圖,物體繞x軸方向旋轉(zhuǎn)一定角度,我們把旋轉(zhuǎn)這個(gè)動(dòng)態(tài)過(guò)程分解,假設(shè)第1秒時(shí),旋轉(zhuǎn)到1位置,第2秒時(shí),旋轉(zhuǎn)到2位置,第2秒時(shí),旋轉(zhuǎn)到3位置.根據(jù)角速度,可以求出第1秒旋轉(zhuǎn)過(guò)的角度,同樣求出第2秒,第3秒的角度,將這些角度想加,就可以得到3秒的時(shí)間旋轉(zhuǎn)過(guò)的角度.
本例程的總體思路是,通過(guò)STM8L讀取MPU6050的加速度和角速度數(shù)據(jù),根據(jù)加速度值,求出x方向和y方向上的角度變化,僅僅是使用了上文中提及的反正切函數(shù).然后用匿名上位機(jī),動(dòng)態(tài)展示計(jì)算后的角度.

本例程中,對(duì)加速度和角速度數(shù)據(jù),進(jìn)行了簡(jiǎn)單的滑動(dòng)窗口濾波.STM8L的主頻為8MHz,I2C的通信速率為400KHz,USART通信速率為115200.
本例程的視頻演示,由于只使用了加速度可以看到,角度輸出并不是什么平穩(wěn),受到運(yùn)動(dòng)加速度的干擾.

  1. /*硬件連接*/
  2. // PC0<--->SDA   PC1---->SCL
  3. //USART1_TX on PC3 and USART1_RX on PC2
  4. /****************************************************************************************
  5. *開(kāi)發(fā)環(huán)境:IAR for stm8 v6.5.3
  6. *硬件平臺(tái):STM8L-DISCOVERY
  7. *功能說(shuō)明:通過(guò)硬件I2C等待的方法,
  8. *作    者:茗風(fēng)
  9. ****************************************************************************************/
  10. #include"iostm8l152c6.h"
  11. #include"stdbool.h"
  12. #include"stdint.h"
  13. #include "math.h"
  14. #define x 0
  15. #define y 1
  16. #define z 2
  17. #define _gx mpu6050data_struct.gyro_data[x]
  18. #define _gy mpu6050data_struct.gyro_data[y]
  19. #define _gz mpu6050data_struct.gyro_data[z]
  20. #define _ax mpu6050data_struct.accel_data[x]
  21. #define _ay mpu6050data_struct.accel_data[y]
  22. #define _az mpu6050data_struct.accel_data[z]

  23. float Pitch=0;//
  24. float Roll=0;
  25. float Yaw=0;

  26. //Att_Angle.pit


  27. struct mpu6050data
  28. {
  29.   int16_t gyro_data[3];//MPU6050原始陀螺儀角速度值
  30.   int16_t accel_data[3];//MPU6050原始加速度計(jì)值
  31. //  int16_t temp;//溫度數(shù)據(jù)
  32.   int16_t gyro_offset_data[3];//水平靜止時(shí)陀螺儀偏移值
  33.   int16_t accel_offset_data[3];//水平靜止時(shí)加速度計(jì)偏移值
  34. };
  35. struct mpu6050data mpu6050data_struct;

  36. bool bTX_finished=true;

  37. uint8_t ui8TX_buffer[25]={0};
  38. uint8_t ui8TX_counter=0;
  39. uint8_t ui8Read_mpu6050_buffer[14]={0};
  40. /******************************************************************************************************
  41. *  名    稱(chēng):void delay_10ms(uint8_t x_ms)
  42. *  功    能:延時(shí)10ms
  43. *  入口參數(shù):無(wú)
  44. *  出口參數(shù):無(wú)
  45. *  說(shuō)    明:
  46. *  范    例:無(wú)
  47. ******************************************************************************************************/
  48. void delay_100ms(void)
  49. {
  50.   uint8_t i,j;
  51.   for(i=0;i<255;i++)//2*255個(gè)指令周期
  52.     for(j=0;j<255;j++);//2*255個(gè)指令周期
  53.   // delay_10ms共消耗 x_ms*2*255+2*x_ms個(gè)指令周期  
  54.   // 255*2*255+2*255=130610us=130ms
  55.   // 此延時(shí)函數(shù),延時(shí)時(shí)間為130ms
  56.   // 16M/8/2=1M 一個(gè)指令周期為1us
  57. }
  58. /******************************************************************************************************
  59. *  名    稱(chēng):void GPIO_Init(void)
  60. *  功    能:初始化PC7為高速推挽輸出
  61. *  入口參數(shù):無(wú)
  62. *  出口參數(shù):無(wú)
  63. *  說(shuō)    明:
  64. *  范    例:無(wú)
  65. ******************************************************************************************************/
  66. void GPIO_Init(void)
  67. {
  68.    PC_CR1_C17  =1;//推挽輸出
  69.    PC_CR2_C27  =1;//高速輸出
  70.    PC_DDR_DDR7 =1;//PC7輸出
  71.    PC_ODR_ODR7 =0;//輸出低電平

  72.    PE_CR1_C17  =1;//推挽輸出
  73.    PE_CR2_C27  =1;//高速輸出
  74.    PE_DDR_DDR7 =1;//PC7輸出
  75.    PE_ODR_ODR7 =0;//輸出低電平
  76. }
  77. /******************************************************************************************************
  78. * 名             稱(chēng):void UART_Init(void)
  79. * 功            能:UART定時(shí)器初始化系統(tǒng)
  80. * 入口   參數(shù):無(wú)
  81. * 出口   參數(shù):無(wú)
  82. * 說(shuō)       明:UART初始化為 115200 1 8 n
  83. * 范      例:無(wú)
  84. ******************************************************************************************************/
  85. void UART_Init(void)
  86. {
  87.   /*********************************/
  88.   PC_DDR_DDR2 =0;//輸入
  89.   PC_CR1_C12  =1;//上拉輸入
  90.   PC_CR2_C22 =0;

  91.   PC_ODR_ODR3 =1;
  92.   PC_CR1_C13  =1;//推挽輸出
  93.   PC_CR2_C23  =1;//輸出擺率10M   
  94.   PC_DDR_DDR3 =1;//輸出高電平,TX空閑狀態(tài)為高電平,如果不設(shè)置,會(huì)莫名奇妙的發(fā)送0x00


  95.   CLK_PCKENR1_PCKEN15=1;//開(kāi)啟USART外設(shè)時(shí)鐘

  96.   //開(kāi)啟引腳的UART功能
  97.   //00: USART1_TX on PC3 and USART1_RX on PC2
  98.   //01: USART1_TX on PA2 and USART1_RX on PA3
  99.   //10: USART1_TX on PC5 and USART1_RX on PC6
  100.   SYSCFG_RMPCR1_USART1TR_REMAP =0;//PC2,PC3
  101.   //如果需要使用其他引腳作為串口發(fā)送接收引腳,請(qǐng)?jiān)谶@里選擇


  102.   //設(shè)置串口工作方式
  103.   USART1_CR1_M =0;//1 start bit,8 data bit,n stop bit
  104.   USART1_CR3_STOP0=0;USART1_CR3_STOP1=0;//1 stop bit
  105.   //設(shè)置波特率
  106.   //波特率設(shè)置為115200
  107.   // 8000000/115200=69    //8000000是此時(shí)系統(tǒng)的主時(shí)鐘頻率,4分頻,16M/2=8M
  108.   //69(DEC)=0045(HEX)
  109.   USART1_BRR2 =0x05;//the BRR2 should be programmed before BRR1
  110.   USART1_BRR1 =0x04;

  111. //    USART1_CR2_TEN=0;//使能發(fā)送
  112. //    USART1_CR2_TIEN=0;//打開(kāi)發(fā)送中斷
  113. //    USART1_CR2_REN=1;//使能接收
  114. //    USART1_CR2_RIEN=1;//打開(kāi)接收中斷
  115. }
  116. /******************************************************************************************************
  117. * 名     稱(chēng): IIC_init()
  118. * 功     能:初始化I2C,系統(tǒng)主頻位4MHz,I2C通信速度位333KHz
  119. * 入口參數(shù):無(wú)
  120. * 出口參數(shù):無(wú)
  121. * 說(shuō)    明:PC0--SDA   PC1--SCL
  122. * 范   例:無(wú)
  123. ******************************************************************************************************/
  124. void I2C_Init(void)
  125. {
  126.   //----打開(kāi)IIC外設(shè)時(shí)鐘----
  127.   CLK_PCKENR1_PCKEN13=1;//
  128.   I2C1_CR1_PE=0;
  129.   I2C1_CR2_ACK=1;

  130.   //----I2C輸入時(shí)鐘頻率選擇----
  131.   I2C1_FREQR_FREQ=0x08;//8MHz
  132.   /*  The allowed range is between 1 MHz and 16 MHz
  133.   000000: not allowed
  134.   000001: 1 MHz
  135.   000010: 2 MHz
  136.   ...
  137.   010000: 16 MHz                                 */

  138.   //----配置時(shí)鐘控制寄存器----
  139.   I2C1_CCRH=0;
  140.   I2C1_CCRH_F_S=1; //Fast mode I2C
  141.   I2C1_CCRH_DUTY=0;
  142. /* If DUTY = 0:
  143. Period(I2C) = 3* CCR * tMASTER
  144. thigh = CCR * tMASTER
  145. tlow = 2 * CCR * tMASTER*/
  146.   I2C1_CCRL=7;    //SCL高電平時(shí)間配置
  147.   //I2C的SCK時(shí)鐘設(shè)置為400KHz,則SCK周期為2.5us   2.5us/0.125/3=7   
  148.   //因?yàn)镮2C1_FREQR_FREQ=0x08,即I2C輸入時(shí)鐘頻率為8M,周期為0.125us  
  149.   //CCR=7時(shí),SCK的低電平時(shí)間為2*tlow=2*7*0.125us=1.75us,SCk高電平時(shí)間為thigh=7*0.125us=0.875us
  150.   //所以CCR=7時(shí),SCK輸出頻率為380KHz

  151.   //----配置上升時(shí)間寄存器----
  152.   I2C1_TRISER_TRISE=5;//in standard mode, the maximum allowed SCL rise time is 1000 ns.
  153.   //1 us / 0.125 us = 8
  154.   //+1
  155.   I2C1_CR1_PE=1;//

  156. }
  157. /******************************************************************************************************
  158. * 名 稱(chēng): uint8_t I2C_ReadOneByteDataFromSlave(uint8_t address)
  159. * 功 能:從I2C從設(shè)備中讀取一字節(jié)的數(shù)據(jù)
  160. * 入口參數(shù):address:讀取數(shù)據(jù)的寄存器地址
  161. * 出口參數(shù):返回一個(gè)從I2C從設(shè)備指定地址讀到的數(shù)據(jù)
  162. * 說(shuō) 明:
  163. * 范 例:無(wú)
  164. ******************************************************************************************************/
  165. uint8_t I2C_ReadOneByteDataFromSlave(uint8_t address)
  166. {
  167.   volatile uint8_t t;
  168.   //----------I2C起始信號(hào)--------------
  169.   I2C1_CR2_START=1;//產(chǎn)生一個(gè)起始條件
  170.   while(!(I2C1_SR1_SB==1));//讀SR1寄存器,清除SB標(biāo)志位
  171. //  _5NOPS;//根據(jù)數(shù)據(jù)手冊(cè),檢測(cè)到標(biāo)志位后,需插入5個(gè)NOP進(jìn)行延時(shí)

  172.   //-------發(fā)送寫(xiě)I2C從器件地址---------
  173.   I2C1_DR=0xD0;//發(fā)送從設(shè)備地址
  174.   while(!(I2C1_SR1_ADDR==1));//讀SR1寄存器,清除ADDR標(biāo)志位
  175. // _5NOPS;//根據(jù)數(shù)據(jù)手冊(cè),檢測(cè)到標(biāo)志位后,需插入5個(gè)NOP進(jìn)行延時(shí)
  176.   if(I2C1_SR3_TRA==0)return 1;//讀SR3寄存器,清除ADDR標(biāo)志位
  177.   //  0: Data bytes received
  178.   //  1: Data bytes transmitted

  179.   //-----寫(xiě)I2C從器件寄存器地址--------
  180.   I2C1_DR=address;
  181.   while(!(I2C1_SR1_BTF==1));//等待地址發(fā)送完成
  182. //  _5NOPS;//根據(jù)數(shù)據(jù)手冊(cè),檢測(cè)到標(biāo)志位后,需插入5個(gè)NOP進(jìn)行延時(shí)

  183.   //--------I2C重復(fù)起始信號(hào)-----------
  184.   I2C1_CR2_START=1;//重復(fù)產(chǎn)生一個(gè)起始條件
  185.   while(!(I2C1_SR1_SB==1));//讀SR1寄存器,清除SB標(biāo)志位
  186. //  _5NOPS;//根據(jù)數(shù)據(jù)手冊(cè),檢測(cè)到標(biāo)志位后,需插入5個(gè)NOP進(jìn)行延時(shí)

  187.   //-------發(fā)送讀I2C從器件地址---------
  188.   I2C1_DR=0xD1;//發(fā)送從設(shè)備地址
  189.   while(!(I2C1_SR1_ADDR==1));//讀SR1寄存器,清除ADDR標(biāo)志位
  190. //  _5NOPS;//根據(jù)數(shù)據(jù)手冊(cè),檢測(cè)到標(biāo)志位后,需插入5個(gè)NOP進(jìn)行延時(shí)
  191.   if(I2C1_SR3_TRA==1)return 1;//讀SR3寄存器,清除ADDR標(biāo)志位

  192.   //-------------停止信號(hào)-------------
  193.   I2C1_CR2_ACK=0;//ACK位控制著ACK信號(hào),此位為0可以產(chǎn)生一個(gè)NOACK信號(hào)
  194.   I2C1_CR2_STOP=1;

  195.   //-------------等待接收到數(shù)據(jù)-------------
  196.   while(!(I2C1_SR1_RXNE==1));//等待地址發(fā)送完成

  197.   //-------------讀取數(shù)據(jù)-------------
  198.   t=I2C1_DR;

  199.   return t;
  200. }
  201. /******************************************************************************************************
  202. * 名 稱(chēng):void I2C_WriteOneByteDataToSlave(uint8_t address,uint8_t dat)
  203. * 功 能:寫(xiě)入一字節(jié)的數(shù)據(jù)到I2C設(shè)備中
  204. * 入口參數(shù):address:寫(xiě)入的數(shù)據(jù)存儲(chǔ)地址    dat:待寫(xiě)入的數(shù)據(jù)
  205. * 出口參數(shù):無(wú)
  206. * 說(shuō) 明: 通過(guò)MSTM8L硬件寫(xiě)入I2C設(shè)備一個(gè)字節(jié)的數(shù)據(jù)
  207. * 范 例:無(wú)
  208. ******************************************************************************************************/
  209. uint8_t I2C_WriteOneByteDataToSlave(uint8_t address,uint8_t dat)
  210. {
  211.   volatile uint8_t t;
  212.   I2C1_CR2_ACK=1;
  213.   //----------I2C起始信號(hào)--------------
  214.   I2C1_CR2_START=1;//產(chǎn)生一個(gè)起始條件
  215.   while(!(I2C1_SR1_SB==1));
  216. // _5NOPS;//根據(jù)數(shù)據(jù)手冊(cè),檢測(cè)到標(biāo)志位后,需插入5個(gè)NOP進(jìn)行延時(shí)
  217.   I2C1_DR=0xD0;

  218.   //--------寫(xiě)I2C從器件地址-----------
  219.   while(!(I2C1_SR1_ADDR==1));
  220. //  _5NOPS;//根據(jù)數(shù)據(jù)手冊(cè),檢測(cè)到標(biāo)志位后,需插入5個(gè)NOP進(jìn)行延時(shí)
  221.   if(I2C1_SR3_TRA==0)return 1;//讀SR3寄存器,清除ADDR標(biāo)志位

  222.   //-----寫(xiě)I2C從器件寄存器地址--------
  223.   while(!(I2C1_SR1_TXE==1));
  224.   I2C1_DR=address;

  225.   //-------寫(xiě)I2C數(shù)據(jù)到寄存器中--------
  226.   while(!(I2C1_SR1_TXE==1));
  227.   I2C1_DR=dat;
  228.   while(!(I2C1_SR1_TXE==1));
  229.   while(!(I2C1_SR1_BTF==1));
  230. // _5NOPS;//根據(jù)數(shù)據(jù)手冊(cè),檢測(cè)到標(biāo)志位后,需插入5個(gè)NOP進(jìn)行延時(shí)

  231.   //-------------停止信號(hào)-------------
  232.   I2C1_CR2_STOP=1;
  233.   return 0;
  234. }
  235. /******************************************************************************************************
  236. * 功    能:從I2C從設(shè)備讀取多個(gè)字節(jié)數(shù)據(jù)
  237. * 入口函數(shù):
  238. * 出口函數(shù):
  239. * 說(shuō)    明:
  240. * 范    例:
  241. * 日    期:
  242. ******************************************************************************************************/
  243. uint8_t I2C_ReadMultiBytesFromSlave(uint8_t address,uint8_t *rxbuf,uint8_t len)
  244. {
  245.   volatile uint8_t i=0;

  246.   if(len==0)return 1;//如果寫(xiě)入字節(jié)長(zhǎng)度為0退出

  247.   I2C1_CR2_ACK=1;
  248.   //----------I2C起始信號(hào)--------------
  249.   I2C1_CR2_START=1;//產(chǎn)生一個(gè)起始條件
  250.   while(!(I2C1_SR1_SB==1));//讀SR1寄存器,清除SB標(biāo)志位

  251.   //-------發(fā)送寫(xiě)I2C從器件地址---------
  252.   I2C1_DR=0xD0;//發(fā)送從設(shè)備地址
  253.   while(!(I2C1_SR1_ADDR==1));//讀SR1寄存器,清除ADDR標(biāo)志位
  254.   if(I2C1_SR3_TRA==0)return 1;//讀SR3寄存器,清除ADDR標(biāo)志位
  255.   //  0: Data bytes received
  256.   //  1: Data bytes transmitted

  257.   //-----寫(xiě)I2C從器件寄存器地址--------
  258.   I2C1_DR=address;
  259.   while(!(I2C1_SR1_BTF==1));//等待地址發(fā)送完成

  260.   //--------I2C重復(fù)起始信號(hào)-----------
  261.   I2C1_CR2_START=1;//重復(fù)產(chǎn)生一個(gè)起始條件
  262.   while(!(I2C1_SR1_SB==1));//讀SR1寄存器,清除SB標(biāo)志位

  263.   //-------發(fā)送讀I2C從器件地址---------
  264.   I2C1_DR=0xD1;//發(fā)送從設(shè)備地址
  265.   while(!(I2C1_SR1_ADDR==1));//讀SR1寄存器,清除ADDR標(biāo)志位
  266.   if(I2C1_SR3_TRA==1)return 1;//讀SR3寄存器,清除ADDR標(biāo)志位
  267.   //-------------讀取數(shù)據(jù)-------------
  268.   if(len>1)
  269.   {
  270.       for( i=len;i>1;i-- )
  271.       {
  272.         while(!(I2C1_SR1_RXNE==1));//等待I2C1_DR接收到數(shù)
  273.         *rxbuf++ = I2C1_DR;  
  274.       }
  275.   }

  276.   //-------------停止信號(hào)-------------
  277.   I2C1_CR2_ACK=0;//ACK位控制著ACK信號(hào),此位為0可以產(chǎn)生一個(gè)NOACK信號(hào)
  278.   I2C1_CR2_STOP=1;

  279.   while(!(I2C1_SR1_RXNE==1));//等待I2C1_DR接收到數(shù)
  280.   *rxbuf++ = I2C1_DR;

  281.   return 0;
  282. }
  283. /******************************************************************************************************
  284. * 功    能:MPU6050初始化
  285. * 入口函數(shù):
  286. * 出口函數(shù):
  287. * 說(shuō)    明:
  288. * 范    例:
  289. * 日    期:
  290. ******************************************************************************************************/
  291. void MPU6050_Config(void)
  292. {
  293.   I2C_WriteOneByteDataToSlave(0x6B,0x02);//電源管理,喚醒MPU6050,時(shí)鐘源選擇:Y軸陀螺儀時(shí)鐘倍頻
  294. //  I2C_WriteOneByteDataToSlave(0x6B,0x00);//電源管理,喚醒MPU6050,時(shí)鐘源選擇:Y軸陀螺儀時(shí)鐘倍頻
  295.   I2C_WriteOneByteDataToSlave(0x1B,0x18);//陀螺儀最大量程 +-2000度每秒
  296.   I2C_WriteOneByteDataToSlave(0x1C,0x1F);//加速度度最大量程 +-2G

  297.   I2C_WriteOneByteDataToSlave(0x19,0x00);//陀螺儀采樣率,不分頻,8khz
  298.   I2C_WriteOneByteDataToSlave(0x1A,0x00);//不啟用低通濾波器
  299. //  I2C_WriteOneByteDataToSlave(0x1A,0x01);//使用數(shù)字低通濾波器
  300. }
  301. /******************************************************************************************************
  302. * 功    能:該函數(shù)連續(xù)讀取,MPU6050輸出的加速度和角速度數(shù)據(jù)
  303. * 入口函數(shù):a為存放讀取到數(shù)據(jù)的數(shù)組名
  304. * 出口函數(shù):
  305. * 說(shuō)    明:在mpu6050.h頭文件中宏定義了這個(gè)讀取mpu6050數(shù)據(jù)的函數(shù),一行不足寫(xiě)函數(shù),所以進(jìn)行了宏定義
  306. * 范    例:
  307. * 日    期:
  308. ******************************************************************************************************/
  309. #define Read_Data_form_MPU6050(a)  I2C_ReadMultiBytesFromSlave(0x3B,a,14)//讀取mpu6050輸出的加速度和角速度數(shù)據(jù)
  310. /******************************************************************************************************
  311. * 功    能:
  312. * 入口函數(shù):
  313. * 出口函數(shù):
  314. * 說(shuō)    明:將讀取到的高8位和低8位數(shù)據(jù)合并成一個(gè)完整的16位數(shù)據(jù)
  315. * 范    例:
  316. * 日    期:
  317. ******************************************************************************************************/
  318. #define ACC_N   10
  319. #define GYRO_N  2
  320. void MPU6050_Data_Compose(uint8_t *buf)
  321. {
  322.   static uint8_t  acc_cnts=0,gyro_cnts=0;
  323.   static int16_t Data_ACC[3][ACC_N]={0};
  324.   static int16_t Data_GYRO[3][GYRO_N]={0};
  325.   static int32_t sum_acc_x=0,sum_acc_y=0,sum_acc_z=0;
  326.   static int32_t sum_gyro_x=0,sum_gyro_y=0,sum_gyro_z=0;
  327.   //----合成加速度和角速度數(shù)據(jù)----        
  328.         mpu6050data_struct.accel_data[x]=((int16_t)buf[0]<<8) + buf[1];// - mpu6050data_struct.accel_offset_data[x] ;
  329.         mpu6050data_struct.accel_data[y]=((int16_t)buf[2]<<8) + buf[3];// - mpu6050data_struct.accel_offset_data[y];
  330.         mpu6050data_struct.accel_data[z]=((int16_t)buf[4]<<8) + buf[5];// - mpu6050data_struct.accel_offset_data[z];

  331.         mpu6050data_struct.gyro_data[x] = ((int16_t)buf[8]<<8) + buf[9];// - mpu6050data_struct.gyro_offset_data[x];
  332.         mpu6050data_struct.gyro_data[y] = ((int16_t)buf[10]<<8) + buf[11];// - mpu6050data_struct.gyro_offset_data[y];
  333.         mpu6050data_struct.gyro_data[z] = ((int16_t)buf[12]<<8) + buf[13];// - mpu6050data_struct.gyro_offset_data[z];
  334.   //----對(duì)加速度進(jìn)行滑動(dòng)窗口濾波----        
  335.   sum_acc_x-=Data_ACC[x][acc_cnts]; //減去最舊的一個(gè)數(shù)據(jù)
  336.   sum_acc_y-=Data_ACC[y][acc_cnts];
  337.   sum_acc_z-=Data_ACC[z][acc_cnts];
  338.   Data_ACC[x][acc_cnts]=mpu6050data_struct.accel_data[x];//減去最舊的一個(gè)數(shù)據(jù)
  339.   Data_ACC[y][acc_cnts]=mpu6050data_struct.accel_data[y];
  340.   Data_ACC[z][acc_cnts]=mpu6050data_struct.accel_data[z];
  341.   sum_acc_x+=Data_ACC[x][acc_cnts];
  342.   sum_acc_y+=Data_ACC[y][acc_cnts];
  343.   sum_acc_z+=Data_ACC[z][acc_cnts];
  344.   acc_cnts++;
  345.   if(acc_cnts==ACC_N)acc_cnts=0;
  346.   mpu6050data_struct.accel_data[x]=sum_acc_x/ACC_N;//求平均值
  347.   mpu6050data_struct.accel_data[y]=sum_acc_y/ACC_N;
  348.   mpu6050data_struct.accel_data[z]=sum_acc_z/ACC_N;
  349.   //----對(duì)角速度進(jìn)行滑動(dòng)窗口濾波----        
  350.   sum_gyro_x-=Data_GYRO[x][gyro_cnts];//減去最舊的一個(gè)數(shù)據(jù)
  351.   sum_gyro_y-=Data_GYRO[y][gyro_cnts];
  352.   sum_gyro_z-=Data_GYRO[z][gyro_cnts];
  353.   Data_GYRO[x][gyro_cnts]=mpu6050data_struct.gyro_data[x];
  354.   Data_GYRO[y][gyro_cnts]=mpu6050data_struct.gyro_data[y];
  355.   Data_GYRO[z][gyro_cnts]=mpu6050data_struct.gyro_data[z];
  356.   sum_gyro_x+=Data_GYRO[x][gyro_cnts];//加上最新的數(shù)據(jù)
  357.   sum_gyro_y+=Data_GYRO[y][gyro_cnts];
  358.   sum_gyro_z+=Data_GYRO[z][gyro_cnts];
  359.   gyro_cnts++;
  360.   if(gyro_cnts==GYRO_N)gyro_cnts=0;
  361.   mpu6050data_struct.gyro_data[x]=sum_gyro_x/GYRO_N;//求平均值
  362.   mpu6050data_struct.gyro_data[y]=sum_gyro_y/GYRO_N;
  363.   mpu6050data_struct.gyro_data[z]=sum_gyro_z/GYRO_N;  
  364. }
  365. /******************************************************************************************************
  366. * 功    能:
  367. * 入口函數(shù):
  368. * 出口函數(shù):
  369. * 說(shuō)    明:
  370. * 范    例:
  371. * 日    期:
  372. ******************************************************************************************************/
  373. void Prepare_Data(void)
  374. {
  375.   Read_Data_form_MPU6050(ui8Read_mpu6050_buffer);
  376.   MPU6050_Data_Compose(ui8Read_mpu6050_buffer);        
  377. }

  378. /******************************************************************************************************
  379. * 功    能:發(fā)送飛行姿態(tài)數(shù)據(jù)給匿名上位機(jī)
  380. * 入口函數(shù):
  381. * 出口函數(shù):
  382. * 說(shuō)    明:根據(jù)匿名上位機(jī)協(xié)議發(fā)送數(shù)據(jù)
  383. * 范    例:
  384. * 日    期:
  385. ******************************************************************************************************/
  386. void SendDataToStatus(void)
  387. {
  388.         int16_t _tmp;
  389.         uint8_t sum = 0,i=0;
  390.         ui8TX_buffer[0]=0xAA;
  391.         ui8TX_buffer[1]=0xAA;
  392.         ui8TX_buffer[2]=0x01;
  393.         ui8TX_buffer[3]=12;
  394.         
  395.         _tmp = (int16_t)(Roll*100);//翻滾腳
  396.         ui8TX_buffer[4] = (_tmp&0xFF00)>>8;//acc
  397.         ui8TX_buffer[5] = _tmp&0x00FF;
  398.         
  399.         _tmp = (int16_t)(Pitch*100);//俯仰角
  400.         ui8TX_buffer[6] = (_tmp&0xFF00)>>8;
  401.         ui8TX_buffer[7] = _tmp&0x00FF;
  402.         
  403.   _tmp = (int16_t)(Yaw*100);//偏航角
  404.         ui8TX_buffer[8] = (_tmp&0xFF00)>>8;
  405.         ui8TX_buffer[9] = _tmp&0x00FF;
  406.         
  407.         ui8TX_buffer[10]=0;//沒(méi)有超聲波,只好發(fā)送無(wú)效數(shù)據(jù)
  408.         ui8TX_buffer[11]=0;
  409.         ui8TX_buffer[12]=0;
  410.         ui8TX_buffer[13]=0;
  411.         ui8TX_buffer[14]=0;//飛行模式
  412.         ui8TX_buffer[15]=0;//解鎖/加鎖
  413.         
  414.         for(i=0;i<16;i++)
  415.                 sum += ui8TX_buffer[i];
  416.                
  417.         ui8TX_buffer[16] = sum;
  418.         ui8TX_counter=17;
  419.   PC_ODR_ODR7 ^=0x01;
  420.   USART1_CR2_TEN=1;//打開(kāi)發(fā)送
  421.   USART1_CR2_TIEN=1;//打開(kāi)發(fā)送中斷
  422. }

  423. void main(void)
  424. {
  425.   delay_100ms();
  426.   CLK_CKDIVR =0x01;//8M
  427.   GPIO_Init();
  428.   UART_Init();
  429.   I2C_Init();
  430.   MPU6050_Config();
  431.   asm("rim");               //enable interrupts
  432.   while(1)
  433.   {
  434.     if(true==bTX_finished)
  435.           {
  436.       bTX_finished=false;
  437.       Prepare_Data();    //讀取MPU6050原始數(shù)據(jù),并對(duì)數(shù)據(jù)進(jìn)行簡(jiǎn)單濾波

  438.       Pitch=atan((float)_ax/(float)_az)*57.3;  //y軸固定,x軸方向與水平方向夾角
  439.       Roll=atan((float)_ay/(float)_az)*57.3;  //x軸固定,y軸方向與水平方向夾角
  440.       SendDataToStatus();//發(fā)送姿態(tài)數(shù)據(jù)到上位機(jī)
  441.           }
  442. //    asm("wfi");
  443.   }
  444. }
  445. /*************************************************************************************************** ***
  446. * 名 稱(chēng): UART_OnTx()
  447. * 功 能: UART的Tx事件處理函數(shù)
  448. * 入口參數(shù):無(wú)
  449. * 出口參數(shù):無(wú)
  450. * 說(shuō) 明:發(fā)送ui8TX_buffer數(shù)組中的數(shù)據(jù),發(fā)送完成后,置位bTX_finished標(biāo)志位,下一次進(jìn)入中斷后關(guān)閉發(fā)送
  451. * 范 例:無(wú)
  452. ******************************************************************************************************/
  453. #pragma vector=USART_T_TXE_vector
  454. __interrupt void USART_TX_ISR (void)
  455. {
  456.   static uint8_t cnts=0;
  457.   static bool    bSend_EndByte=false;//發(fā)送最后一字節(jié)數(shù)據(jù)
  458.   if(bSend_EndByte && USART1_SR_TC==1)
  459.   {
  460.     USART1_CR2_TIEN=0;//關(guān)閉發(fā)送中斷
  461.     USART1_CR2_TEN=0;//關(guān)閉發(fā)送
  462.           bSend_EndByte=false;
  463.           bTX_finished=true;
  464.   }
  465.   else if(USART1_SR_TC==1)
  466.   {
  467.     USART1_DR=ui8TX_buffer[cnts++];
  468.     if(cnts==ui8TX_counter)
  469.     {
  470.       cnts=0;
  471.       bSend_EndByte=true;
  472.     }
  473.   }
  474. }
  475. /******************************************************************************************************
  476. * 名               稱(chēng): UART_OnRx()
  477. * 功         能: UART的Tx事件處理函數(shù)
  478. * 入口           參數(shù):無(wú)
  479. * 出口           參數(shù):無(wú)
  480. * 說(shuō)               明:
  481. * 范              例:無(wú)
  482. ******************************************************************************************************/
  483. //#pragma vector=USART_R_RXNE_vector
  484. //__interrupt void USART_RX_ISR(void)
  485. //{
  486. //  static uint8_t ui8RX_temp=0;
  487. //  if(USART1_SR_RXNE==1)
  488. //  {
  489. //    ui8RX_temp = USART1_DR;
  490. //  }
  491. //}
復(fù)制代碼
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:221145 發(fā)表于 2017-10-16 17:36 | 只看該作者
樓主牛逼,下在那里,沒(méi)看到啊~~·
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 天天曰天天曰 | 天堂一区二区三区 | 亚洲综合国产精品 | 日本国产欧美 | 欧美激情综合 | 日韩av三区 | 国产免费人成xvideos视频 | 午夜精品在线 | 国产午夜精品理论片a大结局 | 美国一级黄色片 | 欧美日韩一区二区在线观看 | 日韩免费视频一区二区 | 亚洲精品视频在线 | 国产精品久久久久久久久久免费看 | 99精品视频免费观看 | 日韩免| 国产精品波多野结衣 | 久久久久久久国产 | 国产精品三级久久久久久电影 | 国产色爽 | 久久精品免费观看 | 黑人精品 | 超碰最新在线 | 一级特黄色毛片 | 黄色免费av | 久久国产电影 | 欧美国产日韩一区 | 日韩中文一区 | 99re视频在线 | 精品少妇v888av| 国产色爽| 成人欧美一区二区三区1314 | 日韩在线高清 | 国产黄色在线 | 毛片网站在线观看 | 午夜视频在线视频 | 国产精品一区二区免费 | 久久福利电影 | 91精品久久久久久久久 | 九九久久这里只有精品 | 久草成人|