Tsinghua Icenter ChenHuan

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
heroistired
Date:
Thu Mar 16 13:07:14 2017 +0000
Commit message:
DongGanPingTai

Changed in this revision

PinMap.h Show annotated file Show diff for this revision Revisions of this file
TFT/SimpleFont.cpp Show annotated file Show diff for this revision Revisions of this file
TFT/TFT_ILI9340.cpp Show annotated file Show diff for this revision Revisions of this file
TFT/TFT_ILI9340.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
mpu6050_config.h Show annotated file Show diff for this revision Revisions of this file
servo/Servo.h Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 9b8df4f9b792 PinMap.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PinMap.h	Thu Mar 16 13:07:14 2017 +0000
@@ -0,0 +1,33 @@
+#ifndef __PINMAP_H
+#define __PINMAP_H
+
+//管脚的宏定义 提高用户友好性
+#define Pin_Servo1 PA_8
+#define Pin_Servo2 PA_9
+#define Pin_Servo3 PA_10
+#define Pin_Servo4 PA_11
+#define Pin_Servo5 PA_15
+#define Pin_Servo6 PB_3
+#define Pin_Servo7 PB_10
+#define Pin_Servo8 PB_11
+#define Pin_Servo9 PC_6
+#define Pin_Servo10 PC_7
+#define Pin_Servo11 PC_8
+#define Pin_Servo12 PC_9
+#define Pin_UserUartTx PC_10
+#define Pin_UserUartRx PC_11
+#define Pin_MPU6050SCL PA_13
+#define Pin_MPU6050SDA PA_14
+#define Pin_LeftJoystickX PA_0
+#define Pin_LeftJoystickY PA_1
+#define Pin_RightJoystickX PC_1
+#define Pin_RightJoystickY PC_0
+#define Pin_TFT_CS PA_4
+#define Pin_TFT_SCLK PA_5
+#define Pin_TFT_MISO PA_6
+#define Pin_TFT_MOSI PA_7
+#define Pin_TFT_LED  PB_13
+#define Pin_TFT_DC PB_14
+#define Pin_TFT_RESET PB_15
+
+#endif
\ No newline at end of file
diff -r 000000000000 -r 9b8df4f9b792 TFT/SimpleFont.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TFT/SimpleFont.cpp	Thu Mar 16 13:07:14 2017 +0000
@@ -0,0 +1,110 @@
+/***************************************************************
+功能 : mbed的ILI9340液晶显示芯片的驱动程序与图形库的字体库
+作者 : 陈欢 清华大学电机工程与应用电子技术系
+邮箱 : h-che14@mails.tsinghua.edu.cn OR heroistired@gmail.com
+声明 : 
+本程序移植自 https://developer.mbed.org/users/dextorslabs/code/ILI9340_Driver/
+在原有基础上做了改进与丰富,本程序仅供学习与交流使用,如需他用,须联系作者
+All rights reserved
+2017.1.30
+***************************************************************/
+
+const unsigned char simpleFont[][8] =
+{
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+  {0x00,0x00,0x5F,0x00,0x00,0x00,0x00,0x00},
+  {0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00},
+  {0x00,0x14,0x7F,0x14,0x7F,0x14,0x00,0x00},
+  {0x00,0x24,0x2A,0x7F,0x2A,0x12,0x00,0x00},
+  {0x00,0x23,0x13,0x08,0x64,0x62,0x00,0x00},
+  {0x00,0x36,0x49,0x55,0x22,0x50,0x00,0x00},
+  {0x00,0x00,0x05,0x03,0x00,0x00,0x00,0x00},
+  {0x00,0x1C,0x22,0x41,0x00,0x00,0x00,0x00},
+  {0x00,0x41,0x22,0x1C,0x00,0x00,0x00,0x00},
+  {0x00,0x08,0x2A,0x1C,0x2A,0x08,0x00,0x00},
+  {0x00,0x08,0x08,0x3E,0x08,0x08,0x00,0x00},
+  {0x00,0xA0,0x60,0x00,0x00,0x00,0x00,0x00},
+  {0x00,0x08,0x08,0x08,0x08,0x08,0x00,0x00},
+  {0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x00},
+  {0x00,0x20,0x10,0x08,0x04,0x02,0x00,0x00},
+  {0x00,0x3E,0x51,0x49,0x45,0x3E,0x00,0x00},
+  {0x00,0x00,0x42,0x7F,0x40,0x00,0x00,0x00},
+  {0x00,0x62,0x51,0x49,0x49,0x46,0x00,0x00},
+  {0x00,0x22,0x41,0x49,0x49,0x36,0x00,0x00},
+  {0x00,0x18,0x14,0x12,0x7F,0x10,0x00,0x00},
+  {0x00,0x27,0x45,0x45,0x45,0x39,0x00,0x00},
+  {0x00,0x3C,0x4A,0x49,0x49,0x30,0x00,0x00},
+  {0x00,0x01,0x71,0x09,0x05,0x03,0x00,0x00},
+  {0x00,0x36,0x49,0x49,0x49,0x36,0x00,0x00},
+  {0x00,0x06,0x49,0x49,0x29,0x1E,0x00,0x00},
+  {0x00,0x00,0x36,0x36,0x00,0x00,0x00,0x00},
+  {0x00,0x00,0xAC,0x6C,0x00,0x00,0x00,0x00},
+  {0x00,0x08,0x14,0x22,0x41,0x00,0x00,0x00},
+  {0x00,0x14,0x14,0x14,0x14,0x14,0x00,0x00},
+  {0x00,0x41,0x22,0x14,0x08,0x00,0x00,0x00},
+  {0x00,0x02,0x01,0x51,0x09,0x06,0x00,0x00},
+  {0x00,0x32,0x49,0x79,0x41,0x3E,0x00,0x00},
+  {0x00,0x7E,0x09,0x09,0x09,0x7E,0x00,0x00},
+  {0x00,0x7F,0x49,0x49,0x49,0x36,0x00,0x00},
+  {0x00,0x3E,0x41,0x41,0x41,0x22,0x00,0x00},
+  {0x00,0x7F,0x41,0x41,0x22,0x1C,0x00,0x00},
+  {0x00,0x7F,0x49,0x49,0x49,0x41,0x00,0x00},
+  {0x00,0x7F,0x09,0x09,0x09,0x01,0x00,0x00},
+  {0x00,0x3E,0x41,0x41,0x51,0x72,0x00,0x00},
+  {0x00,0x7F,0x08,0x08,0x08,0x7F,0x00,0x00},
+  {0x00,0x41,0x7F,0x41,0x00,0x00,0x00,0x00},
+  {0x00,0x20,0x40,0x41,0x3F,0x01,0x00,0x00},
+  {0x00,0x7F,0x08,0x14,0x22,0x41,0x00,0x00},
+  {0x00,0x7F,0x40,0x40,0x40,0x40,0x00,0x00},
+  {0x00,0x7F,0x02,0x0C,0x02,0x7F,0x00,0x00},
+  {0x00,0x7F,0x04,0x08,0x10,0x7F,0x00,0x00},
+  {0x00,0x3E,0x41,0x41,0x41,0x3E,0x00,0x00},
+  {0x00,0x7F,0x09,0x09,0x09,0x06,0x00,0x00},
+  {0x00,0x3E,0x41,0x51,0x21,0x5E,0x00,0x00},
+  {0x00,0x7F,0x09,0x19,0x29,0x46,0x00,0x00},
+  {0x00,0x26,0x49,0x49,0x49,0x32,0x00,0x00},
+  {0x00,0x01,0x01,0x7F,0x01,0x01,0x00,0x00},
+  {0x00,0x3F,0x40,0x40,0x40,0x3F,0x00,0x00},
+  {0x00,0x1F,0x20,0x40,0x20,0x1F,0x00,0x00},
+  {0x00,0x3F,0x40,0x38,0x40,0x3F,0x00,0x00},
+  {0x00,0x63,0x14,0x08,0x14,0x63,0x00,0x00},
+  {0x00,0x03,0x04,0x78,0x04,0x03,0x00,0x00},
+  {0x00,0x61,0x51,0x49,0x45,0x43,0x00,0x00},
+  {0x00,0x7F,0x41,0x41,0x00,0x00,0x00,0x00},
+  {0x00,0x02,0x04,0x08,0x10,0x20,0x00,0x00},
+  {0x00,0x41,0x41,0x7F,0x00,0x00,0x00,0x00},
+  {0x00,0x04,0x02,0x01,0x02,0x04,0x00,0x00},
+  {0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00},
+  {0x00,0x01,0x02,0x04,0x00,0x00,0x00,0x00},
+  {0x00,0x20,0x54,0x54,0x54,0x78,0x00,0x00},
+  {0x00,0x7F,0x48,0x44,0x44,0x38,0x00,0x00},
+  {0x00,0x38,0x44,0x44,0x28,0x00,0x00,0x00},
+  {0x00,0x38,0x44,0x44,0x48,0x7F,0x00,0x00},
+  {0x00,0x38,0x54,0x54,0x54,0x18,0x00,0x00},
+  {0x00,0x08,0x7E,0x09,0x02,0x00,0x00,0x00},
+  {0x00,0x18,0xA4,0xA4,0xA4,0x7C,0x00,0x00},
+  {0x00,0x7F,0x08,0x04,0x04,0x78,0x00,0x00},
+  {0x00,0x00,0x7D,0x00,0x00,0x00,0x00,0x00},
+  {0x00,0x80,0x84,0x7D,0x00,0x00,0x00,0x00},
+  {0x00,0x7F,0x10,0x28,0x44,0x00,0x00,0x00},
+  {0x00,0x41,0x7F,0x40,0x00,0x00,0x00,0x00},
+  {0x00,0x7C,0x04,0x18,0x04,0x78,0x00,0x00},
+  {0x00,0x7C,0x08,0x04,0x7C,0x00,0x00,0x00},
+  {0x00,0x38,0x44,0x44,0x38,0x00,0x00,0x00},
+  {0x00,0xFC,0x24,0x24,0x18,0x00,0x00,0x00},
+  {0x00,0x18,0x24,0x24,0xFC,0x00,0x00,0x00},
+  {0x00,0x00,0x7C,0x08,0x04,0x00,0x00,0x00},
+  {0x00,0x48,0x54,0x54,0x24,0x00,0x00,0x00},
+  {0x00,0x04,0x7F,0x44,0x00,0x00,0x00,0x00},
+  {0x00,0x3C,0x40,0x40,0x7C,0x00,0x00,0x00},
+  {0x00,0x1C,0x20,0x40,0x20,0x1C,0x00,0x00},
+  {0x00,0x3C,0x40,0x30,0x40,0x3C,0x00,0x00},
+  {0x00,0x44,0x28,0x10,0x28,0x44,0x00,0x00},
+  {0x00,0x1C,0xA0,0xA0,0x7C,0x00,0x00,0x00},
+  {0x00,0x44,0x64,0x54,0x4C,0x44,0x00,0x00},
+  {0x00,0x08,0x36,0x41,0x00,0x00,0x00,0x00},
+  {0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00},
+  {0x00,0x41,0x36,0x08,0x00,0x00,0x00,0x00},
+  {0x00,0x02,0x01,0x01,0x02,0x01,0x00,0x00},
+  {0x00,0x02,0x05,0x05,0x02,0x00,0x00,0x00} 
+};
diff -r 000000000000 -r 9b8df4f9b792 TFT/TFT_ILI9340.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TFT/TFT_ILI9340.cpp	Thu Mar 16 13:07:14 2017 +0000
@@ -0,0 +1,751 @@
+/***************************************************************
+功能 : mbed的ILI9340液晶显示芯片的驱动程序与图形库,使用硬件SPI
+作者 : 陈欢 清华大学电机工程与应用电子技术系
+邮箱 : h-che14@mails.tsinghua.edu.cn OR heroistired@gmail.com
+声明 : 
+本程序移植自 https://developer.mbed.org/users/dextorslabs/code/ILI9340_Driver/
+在原有基础上做了改进与丰富,本程序仅供学习与交流使用,如需他用,须联系作者
+All rights reserved
+2017.1.30
+***************************************************************/
+
+
+#include "mbed.h"
+#include "TFT_ILI9340.h"
+#include "SimpleFont.cpp"
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+// Constructor, assigns the pins to the SPI object, set orientation, and sets screen dims.
+////////////////////////////////////////////////////////////////////////////////////////////////
+ILI9340_Display::ILI9340_Display(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName rst, PinName dc)
+    : spi(mosi, miso, sclk), cs(cs), rst(rst), dc(dc) {
+    _height = _TFTHEIGHT;
+    _width = _TFTWIDTH;
+    orientation = 0;
+    }
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+// Command writing code
+////////////////////////////////////////////////////////////////////////////////////////////////
+void ILI9340_Display::WriteCommand(uint8_t command) {
+    dc = 0;
+    cs = 0;
+    spi.write(command);
+    cs = 1;
+    }
+  
+  
+  
+////////////////////////////////////////////////////////////////////////////////////////////////  
+// Data writing code
+////////////////////////////////////////////////////////////////////////////////////////////////
+void ILI9340_Display::WriteData(uint8_t data) {
+    cs = 0;
+    dc = 1;
+    spi.write(data);
+    cs = 1;    
+    }
+    
+    
+    
+////////////////////////////////////////////////////////////////////////////////////////////////
+// Initilise the display
+////////////////////////////////////////////////////////////////////////////////////////////////
+void ILI9340_Display::DispInit(void) {
+    //CtrlOutput();
+    
+    rst = 0;
+    
+    // Setup the spi for 8 bit data, high steady state clock,
+    // second edge capture, with a 1MHz clock rate
+    //spi.format(8,3);
+    spi.frequency(24000000); // actually seems to work up to about 20Mhz... way better than the 8mhz as std.
+    
+    // Toggle rst to reset
+    rst = 1;
+    wait(0.005);
+    rst = 0;
+    wait(0.020);
+    rst = 1;
+    wait(0.150);
+    
+    WriteCommand(0xEF);
+    WriteData(0x03);
+    WriteData(0x80);
+    WriteData(0x02);
+
+    WriteCommand(0xCF);  
+    WriteData(0x00); 
+    WriteData(0xC1); 
+    WriteData(0x30); 
+
+    WriteCommand(0xED);  
+    WriteData(0x64); 
+    WriteData(0x03); 
+    WriteData(0x12); 
+    WriteData(0x81); 
+ 
+    WriteCommand(0xE8);  
+    WriteData(0x85); 
+    WriteData(0x00); 
+    WriteData(0x78); 
+
+    WriteCommand(0xCB);  
+    WriteData(0x39); 
+    WriteData(0x2C); 
+    WriteData(0x00); 
+    WriteData(0x34); 
+    WriteData(0x02); 
+ 
+    WriteCommand(0xF7);  
+    WriteData(0x20); 
+
+    WriteCommand(0xEA);  
+    WriteData(0x00); 
+    WriteData(0x00); 
+ 
+    WriteCommand(ILI9340_PWCTR1);    //Power control 
+    WriteData(0x23);   //VRH[5:0] 
+ 
+    WriteCommand(ILI9340_PWCTR2);    //Power control 
+    WriteData(0x10);   //SAP[2:0];BT[3:0] 
+ 
+    WriteCommand(ILI9340_VMCTR1);    //VCM control 
+    WriteData(0x3e); //
+    WriteData(0x28); 
+  
+    WriteCommand(ILI9340_VMCTR2);    //VCM control2 
+    WriteData(0x86);  //--
+ 
+    WriteCommand(ILI9340_MADCTL);    // Memory Access Control 
+    WriteData(ILI9340_MADCTL_MX | ILI9340_MADCTL_BGR);
+
+    WriteCommand(ILI9340_PIXFMT);    
+    WriteData(0x55); 
+  
+    WriteCommand(ILI9340_FRMCTR1);    
+    WriteData(0x00);  
+    WriteData(0x18); 
+ 
+    WriteCommand(ILI9340_DFUNCTR);    // Display Function Control 
+    WriteData(0x08); 
+    WriteData(0x82);
+    WriteData(0x27);  
+ 
+    WriteCommand(0xF2);    // 3Gamma Function Disable 
+    WriteData(0x00); 
+ 
+    WriteCommand(ILI9340_GAMMASET);    //Gamma curve selected 
+    WriteData(0x01); 
+ 
+    WriteCommand(ILI9340_GMCTRP1);    //Set Gamma 
+    WriteData(0x0F); 
+    WriteData(0x31); 
+    WriteData(0x2B); 
+    WriteData(0x0C); 
+    WriteData(0x0E); 
+    WriteData(0x08); 
+    WriteData(0x4E); 
+    WriteData(0xF1); 
+    WriteData(0x37); 
+    WriteData(0x07); 
+    WriteData(0x10); 
+    WriteData(0x03); 
+    WriteData(0x0E); 
+    WriteData(0x09); 
+    WriteData(0x00); 
+  
+    WriteCommand(ILI9340_GMCTRN1);    //Set Gamma 
+    WriteData(0x00); 
+    WriteData(0x0E); 
+    WriteData(0x14); 
+    WriteData(0x03); 
+    WriteData(0x11); 
+    WriteData(0x07); 
+    WriteData(0x31); 
+    WriteData(0xC1); 
+    WriteData(0x48); 
+    WriteData(0x08); 
+    WriteData(0x0F); 
+    WriteData(0x0C); 
+    WriteData(0x31); 
+    WriteData(0x36); 
+    WriteData(0x0F); 
+
+    WriteCommand(ILI9340_SLPOUT);    //Exit Sleep 
+    wait(0.120);       
+    WriteCommand(ILI9340_DISPON);    //Display on 
+    
+    }
+    
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+// Sets the rotation of the display
+////////////////////////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////////   
+//功能 : 设置屏幕的方向
+//参数 : m 方向 以接线的方向为向下 0 向上 1 向右 2 向下 3 向左
+//返回值 : 无                              
+//////////////////////////////////////////////////////////////////////////////////
+void ILI9340_Display::SetRotation(uint8_t m) {
+
+  WriteCommand(ILI9340_MADCTL);
+  orientation = m % 4; // can't be higher than 3
+  
+  switch (orientation) {
+   case 0:
+     WriteData(ILI9340_MADCTL_MX | ILI9340_MADCTL_BGR);
+     _width  = _TFTWIDTH;
+     _height = _TFTHEIGHT;
+     break;
+   case 1:
+     WriteData(ILI9340_MADCTL_MV | ILI9340_MADCTL_BGR);
+     _width  = _TFTHEIGHT;
+     _height = _TFTWIDTH;
+     break;
+  case 2:
+    WriteData(ILI9340_MADCTL_MY | ILI9340_MADCTL_BGR);
+     _width  = _TFTWIDTH;
+     _height = _TFTHEIGHT;
+    break;
+   case 3:
+     WriteData(ILI9340_MADCTL_MV | ILI9340_MADCTL_MY | ILI9340_MADCTL_MX | ILI9340_MADCTL_BGR);
+     _width  = _TFTHEIGHT;
+     _height = _TFTWIDTH;
+     break;
+  }
+}
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+// Invert the colours of the display in hardware
+////////////////////////////////////////////////////////////////////////////////////////////////
+void ILI9340_Display::InvertDisplay(bool i) {
+  WriteCommand(i ? ILI9340_INVON : ILI9340_INVOFF);
+}
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////    
+// Set address window for writing data to.
+////////////////////////////////////////////////////////////////////////////////////////////////
+void ILI9340_Display::SetAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
+
+  WriteCommand(ILI9340_CASET); // Column addr set
+  WriteData(x0 >> 8);
+  WriteData(x0 & 0xFF);     // XSTART 
+  WriteData(x1 >> 8);
+  WriteData(x1 & 0xFF);     // XEND
+
+  WriteCommand(ILI9340_PASET); // Row addr set
+  WriteData(y0>>8);
+  WriteData(y0);     // YSTART
+  WriteData(y1>>8);
+  WriteData(y1);     // YEND
+
+  WriteCommand(ILI9340_RAMWR); // write to RAM
+}
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+// To draw the humble pixel
+////////////////////////////////////////////////////////////////////////////////////////////////
+void ILI9340_Display::DrawPixel(uint16_t x, uint16_t y, uint16_t colour) {
+    if((x < 1) ||(x >= _width) || (y < 1) || (y >= _height)) return;
+   
+    SetAddrWindow(x,y,x+1,y+1);
+    
+    dc = 1;
+    cs = 0;
+    
+    spi.write(colour >> 8);
+    spi.write(colour);
+    
+    cs = 1;
+    }
+    
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+// Fill the screen with a colour
+////////////////////////////////////////////////////////////////////////////////////////////////
+void ILI9340_Display::FillScreen(uint16_t colour) {
+    SetAddrWindow(0,0,_width,_height);
+    
+    dc = 1;
+    cs = 0;
+    
+    unsigned int total = _width * _height;
+    unsigned int position = 0;
+    
+    while (position < total) {
+        spi.write(colour >> 8);
+        spi.write(colour);
+        position++;
+        }
+    cs = 1;
+    }
+    
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+// Draws a vertical line fast
+////////////////////////////////////////////////////////////////////////////////////////////////
+void ILI9340_Display::DrawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t colour) {
+
+  // Rudimentary clipping
+  if((x >= _width) || (y >= _height)) return;
+
+  if((y+h-1) >= _height) 
+    h = _height-y;
+
+  SetAddrWindow(x, y, x, y+h-1);
+
+  uint8_t hi = colour >> 8, lo = colour;
+
+  dc = 1;
+  cs = 0;
+
+  while (h--) {
+    spi.write(hi);
+    spi.write(lo);
+  }
+  cs = 1;
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+// Draws a horizontal line fast
+////////////////////////////////////////////////////////////////////////////////////////////////
+void ILI9340_Display::DrawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t colour) {
+
+  // Rudimentary clipping
+  if((x >= _width) || (y >= _height)) return;
+  if((x+w-1) >= _height)  w = _width-x;
+  SetAddrWindow(x, y, x+w-1, y);
+
+  uint8_t hi = colour >> 8, lo = colour;
+  dc = 1;
+  cs = 0;
+  while (w--) {
+    spi.write(hi);
+    spi.write(lo);
+  }
+  cs = 1;
+}
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+// Draws a filled rectangle 
+////////////////////////////////////////////////////////////////////////////////////////////////
+void ILI9340_Display::FillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t colour) {
+
+  // rudimentary clipping (drawChar w/big text requires this)
+  if((x >= _width) || (y >= _height)) return;
+  if((x + w - 1) >= _width)  w = _width  - x;
+  if((y + h - 1) >= _height) h = _height - y;
+
+  SetAddrWindow(x, y, x+w-1, y+h-1);
+
+  uint8_t hi = colour >> 8, lo = colour;
+
+  dc = 1;
+  cs = 0;
+
+  for(y=h; y>0; y--) {
+    for(x=w; x>0; x--) {
+      spi.write(hi);
+      spi.write(lo);
+    }
+  }
+  cs = 1;
+}
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+// Draw an unfilled rectangle
+////////////////////////////////////////////////////////////////////////////////////////////////
+void ILI9340_Display::DrawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color){
+    DrawFastHLine(x, y, w, color);
+    DrawFastHLine(x, y+h-1, w, color);
+    DrawFastVLine(x, y, h, color);
+    DrawFastVLine(x+w-1, y, h, color);
+}
+
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+// draw an unfilled circle
+////////////////////////////////////////////////////////////////////////////////////////////////
+void ILI9340_Display::DrawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t colour){
+    int16_t f = 1 - r;
+    int16_t ddF_x = 1;
+    int16_t ddF_y = -2 * r;
+    int16_t x = 0;
+    int16_t y = r;
+ 
+    DrawPixel(x0  , y0+r, colour);
+    DrawPixel(x0  , y0-r, colour);
+    DrawPixel(x0+r, y0  , colour);
+    DrawPixel(x0-r, y0  , colour);
+ 
+    while (x<y) {
+        if (f >= 0) {
+            y--;
+            ddF_y += 2;
+            f += ddF_y;
+        }
+        x++;
+        ddF_x += 2;
+        f += ddF_x;
+ 
+        DrawPixel(x0 + x, y0 + y, colour);
+        DrawPixel(x0 - x, y0 + y, colour);
+        DrawPixel(x0 + x, y0 - y, colour);
+        DrawPixel(x0 - x, y0 - y, colour);
+        DrawPixel(x0 + y, y0 + x, colour);
+        DrawPixel(x0 - y, y0 + x, colour);
+        DrawPixel(x0 + y, y0 - x, colour);
+        DrawPixel(x0 - y, y0 - x, colour);
+    }
+}
+
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+// Draw a filled circle
+////////////////////////////////////////////////////////////////////////////////////////////////
+void ILI9340_Display::FillCircle(int16_t x0, int16_t y0, int16_t r, uint16_t colour) {
+  DrawFastVLine(x0, y0-r, 2*r+1, colour);
+  FillCircleHelper(x0, y0, r, 3, 0, colour);
+}
+
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+// used to draw circles and roundrects!
+////////////////////////////////////////////////////////////////////////////////////////////////
+void ILI9340_Display::FillCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername, int16_t delta, uint16_t colour) {
+ 
+  int16_t f     = 1 - r;
+  int16_t ddF_x = 1;
+  int16_t ddF_y = -2 * r;
+  int16_t x     = 0;
+  int16_t y     = r;
+ 
+  while (x<y) {
+    if (f >= 0) {
+      y--;
+      ddF_y += 2;
+      f     += ddF_y;
+    }
+    x++;
+    ddF_x += 2;
+    f     += ddF_x;
+ 
+    if (cornername & 0x1) {
+      DrawFastVLine(x0+x, y0-y, 2*y+1+delta, colour);
+      DrawFastVLine(x0+y, y0-x, 2*x+1+delta, colour);
+    }
+    if (cornername & 0x2) {
+      DrawFastVLine(x0-x, y0-y, 2*y+1+delta, colour);
+      DrawFastVLine(x0-y, y0-x, 2*x+1+delta, colour);
+    }
+  }
+}
+
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+// used for drawing rounded corner radii
+////////////////////////////////////////////////////////////////////////////////////////////////
+void ILI9340_Display::DrawCircleHelper( int16_t x0, int16_t y0, int16_t r, uint8_t cornername, uint16_t colour) {
+  int16_t f     = 1 - r;
+  int16_t ddF_x = 1;
+  int16_t ddF_y = -2 * r;
+  int16_t x     = 0;
+  int16_t y     = r;
+ 
+  while (x<y) {
+    if (f >= 0) {
+      y--;
+      ddF_y += 2;
+      f     += ddF_y;
+    }
+    x++;
+    ddF_x += 2;
+    f     += ddF_x;
+    if (cornername & 0x4) {
+      DrawPixel(x0 + x, y0 + y, colour);
+      DrawPixel(x0 + y, y0 + x, colour);
+    } 
+    if (cornername & 0x2) {
+      DrawPixel(x0 + x, y0 - y, colour);
+      DrawPixel(x0 + y, y0 - x, colour);
+    }
+    if (cornername & 0x8) {
+      DrawPixel(x0 - y, y0 + x, colour);
+      DrawPixel(x0 - x, y0 + y, colour);
+    }
+    if (cornername & 0x1) {
+      DrawPixel(x0 - y, y0 - x, colour);
+      DrawPixel(x0 - x, y0 - y, colour);
+    }
+  }
+}
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+// draw a rounded rectangle!
+////////////////////////////////////////////////////////////////////////////////////////////////
+void ILI9340_Display::DrawRoundRect(int16_t x, int16_t y, int16_t w, int16_t h, int16_t r, uint16_t colour) {
+  // smarter version
+  DrawFastHLine(x+r  , y    , w-2*r, colour); // Top
+  DrawFastHLine(x+r  , y+h-1, w-2*r, colour); // Bottom
+  DrawFastVLine(  x    , y+r  , h-2*r, colour); // Left
+  DrawFastVLine(  x+w-1, y+r  , h-2*r, colour); // Right
+  // draw four corners
+  DrawCircleHelper(x+r    , y+r    , r, 1, colour);
+  DrawCircleHelper(x+w-r-1, y+r    , r, 2, colour);
+  DrawCircleHelper(x+w-r-1, y+h-r-1, r, 4, colour);
+  DrawCircleHelper(x+r    , y+h-r-1, r, 8, colour);
+}
+
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+// fill a rounded rectangle!
+////////////////////////////////////////////////////////////////////////////////////////////////
+void ILI9340_Display::FillRoundRect(int16_t x, int16_t y, int16_t w, int16_t h, int16_t r, uint16_t colour) {
+  // smarter version
+  FillRect(x+r, y, w-2*r, h, colour);
+ 
+  // draw four corners
+  FillCircleHelper(x+w-r-1, y+r, r, 1, h-2*r-1, colour);
+  FillCircleHelper(x+r    , y+r, r, 2, h-2*r-1, colour);
+}
+
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+// Pass 8-bit (each) R,G,B, get back 16-bit packed color
+////////////////////////////////////////////////////////////////////////////////////////////////
+uint16_t ILI9340_Display::Colour565(uint8_t r, uint8_t g, uint8_t b) {
+  return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);
+}
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+// Writes an ascii character to the display
+////////////////////////////////////////////////////////////////////////////////////////////////
+void ILI9340_Display::DrawAscii(unsigned char ascii, uint16_t x, uint16_t y, uint16_t size, uint16_t colour) {
+    SetAddrWindow(x, y, x+size, y+size);
+    
+    if( (ascii < 0x20) || (ascii > 0x7e) )      //check for valid ASCII char
+    {
+        ascii = '?';                            //char not supported
+    }
+    for(unsigned char i=0; i<8; i++)
+    {
+        unsigned char temp = simpleFont[ascii - 0x20][i];
+        for(unsigned char f=0; f<8; f++)
+        {
+            if( (temp>>f) & 0x01 )
+            {
+                switch(orientation)
+                {                
+                case '0':
+                    FillRect(x+f*size, y-i*size, size, size, colour);
+                    break;
+                case '1':
+                     FillRect(x-i*size, x-f*size, size, size, colour);
+                     break;
+                case '2':
+                     FillRect(x-f*size, y+i*size, size, size, colour);
+                     break;
+                case '3':
+                default:
+                       FillRect(x+i*size, y+f*size, size, size, colour);
+                }
+            }    
+        }
+    }
+}
+
+
+
+
+
+//////////////////////////////////////////////////////////////////////////////////   
+//功能 : 将一个字符串显示屏幕上
+//参数 : string 要显示的字符串
+//      x,y 字符串中第一个字符的左上角像素的坐标值
+//      size 字号 可选 1 2 3
+//      colour 像素颜色
+//返回值 : 无                              
+//////////////////////////////////////////////////////////////////////////////////
+void ILI9340_Display::DrawString(char *string, uint16_t x, uint16_t y, uint8_t size, uint16_t colour)
+{
+    while(*string)
+    {
+        DrawAscii(*string, x, y, size, colour);
+        *string++;
+        switch(orientation)
+        {        
+        case '0':          
+            if(y > 0) y-=8*size;              //Change position to next char 
+              break;
+        case '1':        
+            if(x > 0) x-=8*size;                       
+            break;
+        case '2':          
+            if(y < _height) y+=8*size;   
+            break;
+        case '3':
+        default:        
+              if(x < _width) x+=8*size; 
+        }          
+    }
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////   
+//功能 : 将一个整数数据显示屏幕上
+//参数 : buffer 显示数据的字符串形式(输出量)
+//      value 要显示的整数
+//      spaceonbuffer 对整数的位数限制
+//      countbase 计数进制
+//      x,y 最高位数字的左上角像素的坐标值 如spaceonbuffer为5,则是万位数字的相应坐标,不论实际上该位有无数字
+//      size 字号 可选 1 2 3
+//      colour 像素颜色
+//返回值 : 无                              
+//////////////////////////////////////////////////////////////////////////////////
+void ILI9340_Display::IntToChars (char* buffer, int value, uint8_t spaceonbuffer, uint8_t countbase, uint16_t x, uint16_t y, uint8_t size, uint16_t colour) {
+    int workvalue = value;
+    int i;
+    int valuetowrite;
+    int  end_i = 0;
+
+    if (value < 0)
+    {
+        workvalue = -value;
+        end_i = 1;
+        buffer[0] = '-';
+    }
+
+    for (i = spaceonbuffer - 1; i >= end_i; i--)
+    {
+        valuetowrite = (workvalue % countbase);
+        if (workvalue == 0)
+        {
+            if (i == (spaceonbuffer - 1))
+            {
+                buffer[i] = 48;                        // ASCII 0
+            } else {
+                buffer[i] = 32;                        // ASCII SPACE
+            }
+        } else {
+            if (valuetowrite > 9)
+            {
+                buffer[i] = valuetowrite + 55;        // ASCII A-Z
+            } else {
+                buffer[i] = valuetowrite + 48;        // ASCII of that character
+            }
+        };
+        workvalue = (workvalue - valuetowrite) / countbase;
+    }
+    
+    DrawString(buffer, x, y, size, colour);
+}
+
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+// Functional code to swap data contents of 16bit registers
+////////////////////////////////////////////////////////////////////////////////////////////////
+void ILI9340_Display::Swap(int16_t *a, int16_t *b) {
+    
+    int16_t x = *a;
+    *a = *b;
+    *b = x;    
+    }
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+// Draws a line with any length and orientation
+////////////////////////////////////////////////////////////////////////////////////////////////
+void ILI9340_Display::DrawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t colour){
+    int16_t steep = abs(y1 - y0) > abs(x1 - x0);
+    if (steep) {
+        Swap(&x0, &y0);
+        Swap(&x1, &y1);
+    }
+ 
+    if (x0 > x1) {
+        Swap(&x0, &x1);
+        Swap(&y0, &y1);
+    }
+ 
+    int16_t dx, dy;
+    dx = x1 - x0;
+    dy = abs(y1 - y0);
+ 
+    int16_t err = dx / 2;
+    int16_t ystep;
+ 
+    if (y0 < y1) {
+        ystep = 1;
+    } else {
+        ystep = -1;
+    }
+ 
+    for (; x0<=x1; x0++) {
+        if (steep) {
+            DrawPixel(y0, x0, colour);
+        } else {
+            DrawPixel(x0, y0, colour);
+        }
+        err -= dy;
+        if (err < 0) {
+            y0 += ystep;
+            err += dx;
+        }
+    }
+}
+
diff -r 000000000000 -r 9b8df4f9b792 TFT/TFT_ILI9340.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TFT/TFT_ILI9340.h	Thu Mar 16 13:07:14 2017 +0000
@@ -0,0 +1,145 @@
+#ifndef __TFT_ILI9340_H
+#define __TFT_ILI9340_H
+/***************************************************************
+功能 : mbed的ILI9340液晶显示芯片的驱动程序与图形库,使用硬件SPI
+作者 : 陈欢 清华大学电机工程与应用电子技术系
+邮箱 : h-che14@mails.tsinghua.edu.cn OR heroistired@gmail.com
+声明 : 
+本程序移植自 https://developer.mbed.org/users/dextorslabs/code/ILI9340_Driver/
+在原有基础上做了改进与丰富,本程序仅供学习与交流使用,如需他用,须联系作者
+All rights reserved
+2017.1.30
+***************************************************************/
+
+#include "mbed.h"
+#include "PinMap.h"
+
+#define _TFTWIDTH  240
+#define _TFTHEIGHT 320
+
+#define ILI9340_NOP     0x00
+#define ILI9340_SWRESET 0x01
+#define ILI9340_RDDID   0x04
+#define ILI9340_RDDST   0x09
+
+#define ILI9340_SLPIN   0x10
+#define ILI9340_SLPOUT  0x11
+#define ILI9340_PTLON   0x12
+#define ILI9340_NORON   0x13
+
+#define ILI9340_RDMODE  0x0A
+#define ILI9340_RDMADCTL  0x0B
+#define ILI9340_RDPIXFMT  0x0C
+#define ILI9340_RDIMGFMT  0x0A
+#define ILI9340_RDSELFDIAG  0x0F
+
+#define ILI9340_INVOFF  0x20
+#define ILI9340_INVON   0x21
+#define ILI9340_GAMMASET 0x26
+#define ILI9340_DISPOFF 0x28
+#define ILI9340_DISPON  0x29
+
+#define ILI9340_CASET   0x2A
+#define ILI9340_PASET   0x2B
+#define ILI9340_RAMWR   0x2C
+#define ILI9340_RAMRD   0x2E
+
+#define ILI9340_PTLAR   0x30
+#define ILI9340_MADCTL  0x36
+
+
+#define ILI9340_MADCTL_MY  0x80
+#define ILI9340_MADCTL_MX  0x40
+#define ILI9340_MADCTL_MV  0x20
+#define ILI9340_MADCTL_ML  0x10
+#define ILI9340_MADCTL_RGB 0x00
+#define ILI9340_MADCTL_BGR 0x08
+#define ILI9340_MADCTL_MH  0x04
+
+#define ILI9340_PIXFMT  0x3A
+
+#define ILI9340_FRMCTR1 0xB1
+#define ILI9340_FRMCTR2 0xB2
+#define ILI9340_FRMCTR3 0xB3
+#define ILI9340_INVCTR  0xB4
+#define ILI9340_DFUNCTR 0xB6
+
+#define ILI9340_PWCTR1  0xC0
+#define ILI9340_PWCTR2  0xC1
+#define ILI9340_PWCTR3  0xC2
+#define ILI9340_PWCTR4  0xC3
+#define ILI9340_PWCTR5  0xC4
+#define ILI9340_VMCTR1  0xC5
+#define ILI9340_VMCTR2  0xC7
+
+#define ILI9340_RDID1   0xDA
+#define ILI9340_RDID2   0xDB
+#define ILI9340_RDID3   0xDC
+#define ILI9340_RDID4   0xDD
+
+#define ILI9340_GMCTRP1 0xE0
+#define ILI9340_GMCTRN1 0xE1
+/*
+#define ILI9340_PWCTR6  0xFC
+
+*/
+
+// Color definitions
+#define ILI9340_BLACK   0x0000
+#define ILI9340_BLUE    0x001F
+#define ILI9340_RED     0xF800
+#define ILI9340_GREEN   0x07E0
+#define ILI9340_CYAN    0x07FF
+#define ILI9340_MAGENTA 0xF81F
+#define ILI9340_YELLOW  0xFFE0  
+#define ILI9340_WHITE   0xFFFF
+
+
+
+class ILI9340_Display {
+    
+    public:
+    
+    uint16_t _height;
+    uint16_t _width;
+    
+    ILI9340_Display(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName rst, PinName dc);
+    
+    void DispInit();
+    void WriteCommand(uint8_t);
+    void WriteData(uint8_t);
+    void SetRotation(uint8_t);
+    void InvertDisplay(bool);
+    void SetAddrWindow(uint16_t, uint16_t, uint16_t, uint16_t);
+    
+    void DrawPixel(uint16_t, uint16_t, uint16_t);
+    void FillScreen(uint16_t);
+    void DrawFastVLine(int16_t, int16_t, int16_t, uint16_t);
+    void DrawFastHLine(int16_t, int16_t, int16_t, uint16_t);
+    void FillRect(int16_t, int16_t, int16_t, int16_t, uint16_t);
+    void DrawRect(int16_t, int16_t, int16_t, int16_t, uint16_t);
+    void DrawCircle(int16_t, int16_t, int16_t, uint16_t);
+    void FillCircle(int16_t, int16_t, int16_t, uint16_t);
+    void FillCircleHelper(int16_t, int16_t, int16_t, uint8_t, int16_t, uint16_t);
+    void DrawCircleHelper( int16_t, int16_t, int16_t, uint8_t, uint16_t);
+    void DrawRoundRect(int16_t, int16_t, int16_t, int16_t, int16_t, uint16_t);
+    void FillRoundRect(int16_t, int16_t, int16_t, int16_t, int16_t, uint16_t);
+    uint16_t Colour565(uint8_t, uint8_t, uint8_t);
+    
+    void DrawAscii(unsigned char, uint16_t, uint16_t, uint16_t, uint16_t);
+    void DrawString(char *string, uint16_t, uint16_t, uint8_t, uint16_t);
+    void IntToChars (char*, int, uint8_t, uint8_t, uint16_t, uint16_t, uint8_t, uint16_t);
+    
+    void Swap(int16_t*, int16_t*);
+    void DrawLine(int16_t, int16_t, int16_t, int16_t, uint16_t);
+    
+    protected:
+    SPI spi; // mosi, miso, sclk
+    DigitalOut cs;
+    DigitalOut rst;
+    DigitalOut dc;
+    
+    uint8_t orientation;
+       
+    };
+#endif
\ No newline at end of file
diff -r 000000000000 -r 9b8df4f9b792 main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Thu Mar 16 13:07:14 2017 +0000
@@ -0,0 +1,768 @@
+/***************************************************************
+功能 : 基于mbed的动感平台SDK 包含摇杆 位置传感器 舵机 以及液晶屏等外设
+作者 : 陈欢 清华大学电机工程与应用电子技术系
+邮箱 : h-che14@mails.tsinghua.edu.cn OR heroistired@gmail.com
+声明 : 
+本程序仅供学习与交流使用,如需他用,须联系作者
+All rights reserved
+2017.2.15
+***************************************************************/
+
+#include "mbed.h"
+#include "mpu6050_config.h"
+#include "Servo.h"
+#include "TFT_ILI9340.h"
+#include "PinMap.h"
+Serial SystemUart(SERIAL_TX, SERIAL_RX);  //系统串口初始化
+
+//////////////////////////////////////////////////////////////////////////////////   
+//头文件部分
+//////////////////////////////////////////////////////////////////////////////////   
+
+///////////////////////////////////////
+//系统相关
+///////////////////////////////////////
+
+//系统监控 
+//接受外部调用的变量
+int TimeNow = 0;  //当前的系统时间
+float CpuUsage = 0.0; //当前的CPU使用率 以主中断为基准
+unsigned int MainInterruptCounter = 0; //存储系统主中断的总执行次数
+float MainInterruptFreq = 0.0; //存储系统主中断的实际频率 Hz
+//中间变量 不接受外部调用
+int FreqTime = 0; //计算系统中断的实际频率 存储的是测量开始时的系统时间
+int FreqCounter = 0; //计算系统中断的实际频率 存储的是测量开始时的中断执行次数
+bool Flag_MeasureFreq = true;  //标志 是否要进行一次频率测量
+
+
+///////////////////////////////////////
+//mpuiic.h
+///////////////////////////////////////
+
+//声明IIC需要用到的IO口
+DigitalOut MPU_IIC_SCL(Pin_MPU6050SCL); //SCL
+DigitalInOut MPU_IIC_SDA(Pin_MPU6050SDA); //SDA 
+
+//弥补屏幕LED画错的bug
+DigitalOut TFT_LED(Pin_TFT_LED);
+
+               
+//定义IO操作的宏
+#define MPU_SDA_IN()  MPU_IIC_SDA.input()
+#define MPU_SDA_OUT() MPU_IIC_SDA.output() 
+#define MPU_READ_SDA   MPU_IIC_SDA.read() //读取SDA
+
+//兼容性宏定义
+#define delay_us wait_us
+#define delay_ms wait_ms
+#define u8 unsigned char
+#define u16 unsigned short 
+
+//IIC所有操作函数
+void MPU_IIC_Delay(void);               //MPU IIC延时函数
+void MPU_IIC_Init(void);                //初始化IIC的IO口                 
+void MPU_IIC_Start(void);               //发送IIC开始信号
+void MPU_IIC_Stop(void);                //发送IIC停止信号
+void MPU_IIC_Send_Byte(u8 txd);         //IIC发送一个字节
+u8 MPU_IIC_Read_Byte(unsigned char ack);//IIC读取一个字节
+u8 MPU_IIC_Wait_Ack(void);              //IIC等待ACK信号
+void MPU_IIC_Ack(void);                 //IIC发送ACK信号
+void MPU_IIC_NAck(void);                //IIC不发送ACK信号
+
+void IMPU_IC_Write_One_Byte(u8 daddr,u8 addr,u8 data);
+u8 MPU_IIC_Read_One_Byte(u8 daddr,u8 addr);  
+
+///////////////////////////////////////
+//mp6050.h
+///////////////////////////////////////
+u8 MPU_Init(void);                              //初始化MPU6050
+u8 MPU_Write_Len(u8 addr,u8 reg,u8 len,u8 *buf);//IIC连续写
+u8 MPU_Read_Len(u8 addr,u8 reg,u8 len,u8 *buf); //IIC连续读 
+u8 MPU_Write_Byte(u8 reg,u8 data);              //IIC写一个字节
+u8 MPU_Read_Byte(u8 reg);                       //IIC读一个字节
+
+u8 MPU_Set_Gyro_Fsr(u8 fsr);
+u8 MPU_Set_Accel_Fsr(u8 fsr);
+u8 MPU_Set_LPF(u16 lpf);
+u8 MPU_Set_Rate(u16 rate);
+u8 MPU_Set_Fifo(u8 sens);
+
+
+short MPU_Get_Temperature(void);
+u8 MPU_Get_Gyroscope(short *gx,short *gy,short *gz);
+u8 MPU_Get_Accelerometer(short *ax,short *ay,short *az);
+
+///////////////////////////////////////
+//软件方法解算姿态
+///////////////////////////////////////
+Timer SystemTimer; //系统计时器
+Ticker MainInterrupt;  //主中断 100Hz
+//加速度 角速度 温度(原始值)
+short aacx = 0, aacy = 0, aacz = 0, gyrox = 0, gyroy = 0, gyroz = 0, temp = 0;
+float Pitch = 0, Yaw = 0, Roll = 0; //绕x,y,z轴的转角
+float ThetaXz = 0, ThetaYz = 0; //重力加速度在XOZ、YOZ面上与z轴夹角
+
+//卡尔曼滤波器相关参量
+#define PI 3.1415926
+struct KalmanStruct
+{
+    float K1; 
+    float angle, angle_dot;     
+    float Q_angle;// 过程噪声的协方差
+    float Q_gyro;//0.003 过程噪声的协方差 过程噪声的协方差为一个一行两列矩阵
+    float R_angle;// 测量噪声的协方差 既测量偏差
+    float dt;//                 
+    char  C_0;
+    float Q_bias, Angle_err;
+    float PCt_0, PCt_1, E;
+    float K_0, K_1, t_0, t_1;
+    float Pdot[4];
+    float PP[2][2];
+};
+
+struct KalmanStruct X_Axis = {0}, Y_Axis = {0};
+
+void MainInterruptIRQ(void);  //主中断服务函数
+void Kalman_Filter(float AccelX,float GyroX, float AccelY,float GyroY); //卡尔曼滤波器
+void Processing(void);  //用户进程函数
+
+//系统初始化函数
+void System_Init(void);
+
+//////////////////////////////////////////////////////////////////////////////////   
+//函数实现部分
+//////////////////////////////////////////////////////////////////////////////////   
+
+///////////////////////////////////////
+//mpuiic.c
+///////////////////////////////////////
+
+//MPU IIC 延时函数
+void MPU_IIC_Delay(void)
+{
+    delay_us(2);
+}
+//初始化IIC
+void MPU_IIC_Init(void)
+{                        
+    RCC->APB2ENR|=1<<4;     //先使能外设IO PORTC时钟                            
+    GPIOC->CRH&=0XFFF00FFF; //PC11/12 推挽输出
+    GPIOC->CRH|=0X00033000;    
+    GPIOC->ODR|=3<<11;      //PC11,12 输出高
+}
+//产生IIC起始信号
+void MPU_IIC_Start(void)
+{
+    MPU_SDA_OUT();     //sda线输出
+    MPU_IIC_SDA=1;        
+    MPU_IIC_SCL=1;
+    MPU_IIC_Delay();
+    MPU_IIC_SDA=0;//START:when CLK is high,DATA change form high to low 
+    MPU_IIC_Delay();
+    MPU_IIC_SCL=0;//钳住I2C总线,准备发送或接收数据 
+}     
+//产生IIC停止信号
+void MPU_IIC_Stop(void)
+{
+    MPU_SDA_OUT();//sda线输出
+    MPU_IIC_SCL=0;
+    MPU_IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
+    MPU_IIC_Delay();
+    MPU_IIC_SCL=1;  
+    MPU_IIC_SDA=1;//发送I2C总线结束信号
+    MPU_IIC_Delay();                                
+}
+//等待应答信号到来
+//返回值:1,接收应答失败
+//        0,接收应答成功
+u8 MPU_IIC_Wait_Ack(void)
+{
+    u8 ucErrTime=0;
+    MPU_SDA_IN();      //SDA设置为输入  
+    MPU_IIC_SDA=1;MPU_IIC_Delay();     
+    MPU_IIC_SCL=1;MPU_IIC_Delay();   
+    while(MPU_READ_SDA)
+    {
+        ucErrTime++;
+        if(ucErrTime>250)
+        {
+            MPU_IIC_Stop();
+            return 1;
+        }
+    }
+    MPU_IIC_SCL=0;//时钟输出0      
+    return 0;  
+} 
+//产生ACK应答
+void MPU_IIC_Ack(void)
+{
+    MPU_IIC_SCL=0;
+    MPU_SDA_OUT();
+    MPU_IIC_SDA=0;
+    MPU_IIC_Delay();
+    MPU_IIC_SCL=1;
+    MPU_IIC_Delay();
+    MPU_IIC_SCL=0;
+}
+//不产生ACK应答          
+void MPU_IIC_NAck(void)
+{
+    MPU_IIC_SCL=0;
+    MPU_SDA_OUT();
+    MPU_IIC_SDA=1;
+    MPU_IIC_Delay();
+    MPU_IIC_SCL=1;
+    MPU_IIC_Delay();
+    MPU_IIC_SCL=0;
+}                                        
+//IIC发送一个字节
+//返回从机有无应答
+//1,有应答
+//0,无应答           
+void MPU_IIC_Send_Byte(u8 txd)
+{                        
+    u8 t;   
+    MPU_SDA_OUT();      
+    MPU_IIC_SCL=0;//拉低时钟开始数据传输
+    for(t=0;t<8;t++)
+    {              
+        MPU_IIC_SDA=(txd&0x80)>>7;
+        txd<<=1;      
+        MPU_IIC_SCL=1;
+        MPU_IIC_Delay(); 
+        MPU_IIC_SCL=0;  
+        MPU_IIC_Delay();
+    }    
+}       
+//读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
+u8 MPU_IIC_Read_Byte(unsigned char ack)
+{
+    unsigned char i,receive=0;
+    MPU_SDA_IN();//SDA设置为输入
+    for(i=0;i<8;i++ )
+    {
+        MPU_IIC_SCL=0; 
+        MPU_IIC_Delay();
+        MPU_IIC_SCL=1;
+        receive<<=1;
+        if(MPU_READ_SDA)receive++;   
+        MPU_IIC_Delay(); 
+    }                    
+    if (!ack)
+        MPU_IIC_NAck();//发送nACK
+    else
+        MPU_IIC_Ack(); //发送ACK   
+    return receive;
+}
+
+///////////////////////////////////////
+//mp6050.c
+///////////////////////////////////////
+//初始化MPU6050
+//返回值:0,成功
+//    其他,错误代码
+u8 MPU_Init(void)
+{ 
+    u8 res; 
+    MPU_IIC_Init();//初始化IIC总线
+    MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X80); //复位MPU6050
+    delay_ms(100);
+    MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X00); //唤醒MPU6050 
+    MPU_Set_Gyro_Fsr(3);                    //陀螺仪传感器,±2000dps
+    MPU_Set_Accel_Fsr(0);                   //加速度传感器,±2g
+    MPU_Set_Rate(200);                      //设置采样率200Hz
+    MPU_Write_Byte(MPU_INT_EN_REG,0X00);    //关闭所有中断
+    MPU_Write_Byte(MPU_USER_CTRL_REG,0X00); //I2C主模式关闭
+    MPU_Write_Byte(MPU_FIFO_EN_REG,0X00);   //关闭FIFO
+    MPU_Write_Byte(MPU_INTBP_CFG_REG,0X80); //INT引脚低电平有效
+    res=MPU_Read_Byte(MPU_DEVICE_ID_REG); 
+    if(res==MPU_ADDR)//器件ID正确
+    {
+        MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X01); //设置CLKSEL,PLL X轴为参考
+        MPU_Write_Byte(MPU_PWR_MGMT2_REG,0X00); //加速度与陀螺仪都工作
+        MPU_Set_Rate(200);                      //设置采样率为200Hz
+    }else return 1;
+    return 0;
+}
+//设置MPU6050陀螺仪传感器满量程范围
+//fsr:0,±250dps;1,±500dps;2,±1000dps;3,±2000dps
+//返回值:0,设置成功
+//    其他,设置失败 
+u8 MPU_Set_Gyro_Fsr(u8 fsr)
+{
+    return MPU_Write_Byte(MPU_GYRO_CFG_REG,fsr<<3);//设置陀螺仪满量程范围  
+}
+//设置MPU6050加速度传感器满量程范围
+//fsr:0,±2g;1,±4g;2,±8g;3,±16g
+//返回值:0,设置成功
+//    其他,设置失败 
+u8 MPU_Set_Accel_Fsr(u8 fsr)
+{
+    return MPU_Write_Byte(MPU_ACCEL_CFG_REG,fsr<<3);//设置加速度传感器满量程范围  
+}
+//设置MPU6050的数字低通滤波器
+//lpf:数字低通滤波频率(Hz)
+//返回值:0,设置成功
+//    其他,设置失败 
+u8 MPU_Set_LPF(u16 lpf)
+{
+    u8 data=0;
+    if(lpf>=188)data=1;
+    else if(lpf>=98)data=2;
+    else if(lpf>=42)data=3;
+    else if(lpf>=20)data=4;
+    else if(lpf>=10)data=5;
+    else data=6; 
+    return MPU_Write_Byte(MPU_CFG_REG,data);//设置数字低通滤波器  
+}
+//设置MPU6050的采样率(假定Fs=1KHz)
+//rate:4~1000(Hz)
+//返回值:0,设置成功
+//    其他,设置失败 
+u8 MPU_Set_Rate(u16 rate)
+{
+    u8 data;
+    if(rate>1000)rate=1000;
+    if(rate<4)rate=4;
+    data=1000/rate-1;
+    data=MPU_Write_Byte(MPU_SAMPLE_RATE_REG,data);  //设置数字低通滤波器
+    return MPU_Set_LPF(rate/2); //自动设置LPF为采样率的一半
+}
+
+//得到温度值
+//返回值:温度值(扩大了100倍)
+short MPU_Get_Temperature(void)
+{
+    u8 buf[2]; 
+    short raw;
+    float temp;
+    MPU_Read_Len(MPU_ADDR,MPU_TEMP_OUTH_REG,2,buf); 
+    raw=((u16)buf[0]<<8)|buf[1];  
+    temp=36.53+((double)raw)/340;  
+    return temp*100;;
+}
+//得到陀螺仪值(原始值)
+//gx,gy,gz:陀螺仪x,y,z轴的原始读数(带符号)
+//返回值:0,成功
+//    其他,错误代码
+u8 MPU_Get_Gyroscope(short *gx,short *gy,short *gz)
+{
+    u8 buf[6],res;  
+    res=MPU_Read_Len(MPU_ADDR,MPU_GYRO_XOUTH_REG,6,buf);
+    if(res==0)
+    {
+        *gx=((u16)buf[0]<<8)|buf[1];  
+        *gy=((u16)buf[2]<<8)|buf[3];  
+        *gz=((u16)buf[4]<<8)|buf[5];
+    }   
+    return res;;
+}
+//得到加速度值(原始值)
+//gx,gy,gz:陀螺仪x,y,z轴的原始读数(带符号)
+//返回值:0,成功
+//    其他,错误代码
+u8 MPU_Get_Accelerometer(short *ax,short *ay,short *az)
+{
+    u8 buf[6],res;  
+    res=MPU_Read_Len(MPU_ADDR,MPU_ACCEL_XOUTH_REG,6,buf);
+    if(res==0)
+    {
+        *ax=((u16)buf[0]<<8)|buf[1];  
+        *ay=((u16)buf[2]<<8)|buf[3];  
+        *az=((u16)buf[4]<<8)|buf[5];
+    }   
+    return res;;
+}
+//IIC连续写
+//addr:器件地址 
+//reg:寄存器地址
+//len:写入长度
+//buf:数据区
+//返回值:0,正常
+//    其他,错误代码
+u8 MPU_Write_Len(u8 addr,u8 reg,u8 len,u8 *buf)
+{
+    u8 i; 
+    MPU_IIC_Start(); 
+    MPU_IIC_Send_Byte((addr<<1)|0);//发送器件地址+写命令 
+    if(MPU_IIC_Wait_Ack())  //等待应答
+    {
+        MPU_IIC_Stop();      
+        return 1;       
+    }
+    MPU_IIC_Send_Byte(reg); //写寄存器地址
+    MPU_IIC_Wait_Ack();     //等待应答
+    for(i=0;i<len;i++)
+    {
+        MPU_IIC_Send_Byte(buf[i]);  //发送数据
+        if(MPU_IIC_Wait_Ack())      //等待ACK
+        {
+            MPU_IIC_Stop();  
+            return 1;        
+        }       
+    }    
+    MPU_IIC_Stop();  
+    return 0;   
+} 
+//IIC连续读
+//addr:器件地址
+//reg:要读取的寄存器地址
+//len:要读取的长度
+//buf:读取到的数据存储区
+//返回值:0,正常
+//    其他,错误代码
+u8 MPU_Read_Len(u8 addr,u8 reg,u8 len,u8 *buf)
+{ 
+    MPU_IIC_Start(); 
+    MPU_IIC_Send_Byte((addr<<1)|0);//发送器件地址+写命令 
+    if(MPU_IIC_Wait_Ack())  //等待应答
+    {
+        MPU_IIC_Stop();      
+        return 1;       
+    }
+    MPU_IIC_Send_Byte(reg); //写寄存器地址
+    MPU_IIC_Wait_Ack();     //等待应答
+    MPU_IIC_Start();
+    MPU_IIC_Send_Byte((addr<<1)|1);//发送器件地址+读命令 
+    MPU_IIC_Wait_Ack();     //等待应答 
+    while(len)
+    {
+        if(len==1)*buf=MPU_IIC_Read_Byte(0);//读数据,发送nACK 
+        else *buf=MPU_IIC_Read_Byte(1);     //读数据,发送ACK  
+        len--;
+        buf++; 
+    }    
+    MPU_IIC_Stop(); //产生一个停止条件 
+    return 0;   
+}
+//IIC写一个字节 
+//reg:寄存器地址
+//data:数据
+//返回值:0,正常
+//    其他,错误代码
+u8 MPU_Write_Byte(u8 reg,u8 data)                
+{ 
+    MPU_IIC_Start(); 
+    MPU_IIC_Send_Byte((MPU_ADDR<<1)|0);//发送器件地址+写命令 
+    if(MPU_IIC_Wait_Ack())  //等待应答
+    {
+        MPU_IIC_Stop();      
+        return 1;       
+    }
+    MPU_IIC_Send_Byte(reg); //写寄存器地址
+    MPU_IIC_Wait_Ack();     //等待应答 
+    MPU_IIC_Send_Byte(data);//发送数据
+    if(MPU_IIC_Wait_Ack())  //等待ACK
+    {
+        MPU_IIC_Stop();  
+        return 1;        
+    }        
+    MPU_IIC_Stop();  
+    return 0;
+}
+//IIC读一个字节 
+//reg:寄存器地址 
+//返回值:读到的数据
+u8 MPU_Read_Byte(u8 reg)
+{
+    u8 res;
+    MPU_IIC_Start(); 
+    MPU_IIC_Send_Byte((MPU_ADDR<<1)|0);//发送器件地址+写命令 
+    MPU_IIC_Wait_Ack();     //等待应答 
+    MPU_IIC_Send_Byte(reg); //写寄存器地址
+    MPU_IIC_Wait_Ack();     //等待应答
+    MPU_IIC_Start();
+    MPU_IIC_Send_Byte((MPU_ADDR<<1)|1);//发送器件地址+读命令 
+    MPU_IIC_Wait_Ack();     //等待应答 
+    res=MPU_IIC_Read_Byte(0);//读取数据,发送nACK 
+    MPU_IIC_Stop();         //产生一个停止条件 
+    return res;     
+}
+
+///////////////////////////////////////
+//软件方法解算姿态
+///////////////////////////////////////
+
+/**************************************************************************
+函数功能:简易卡尔曼滤波
+入口参数:加速度、角速度
+返回  值:无
+**************************************************************************/
+
+void Kalman_Filter(float AccelX,float GyroX, float AccelY,float GyroY)      
+{
+    X_Axis.angle+=(GyroX - X_Axis.Q_bias) * X_Axis.dt; //先验估计
+    X_Axis.Pdot[0]=X_Axis.Q_angle - X_Axis.PP[0][1] - X_Axis.PP[1][0]; // Pk-先验估计误差协方差的微分
+
+    X_Axis.Pdot[1]=-X_Axis.PP[1][1];
+    X_Axis.Pdot[2]=-X_Axis.PP[1][1];
+    X_Axis.Pdot[3]=X_Axis.Q_gyro;
+    X_Axis.PP[0][0] += X_Axis.Pdot[0] * X_Axis.dt;   // Pk-先验估计误差协方差微分的积分
+    X_Axis.PP[0][1] += X_Axis.Pdot[1] * X_Axis.dt;   // =先验估计误差协方差
+    X_Axis.PP[1][0] += X_Axis.Pdot[2] * X_Axis.dt;
+    X_Axis.PP[1][1] += X_Axis.Pdot[3] * X_Axis.dt;
+        
+    X_Axis.Angle_err = AccelX - X_Axis.angle;  //zk-先验估计
+    
+    X_Axis.PCt_0 = X_Axis.C_0 * X_Axis.PP[0][0];
+    X_Axis.PCt_1 = X_Axis.C_0 * X_Axis.PP[1][0];
+    
+    X_Axis.E = X_Axis.R_angle + X_Axis.C_0 * X_Axis.PCt_0;
+    
+    X_Axis.K_0 = X_Axis.PCt_0 / X_Axis.E;
+    X_Axis.K_1 = X_Axis.PCt_1 / X_Axis.E;
+    
+    X_Axis.t_0 = X_Axis.PCt_0;
+    X_Axis.t_1 = X_Axis.C_0 * X_Axis.PP[0][1];
+
+    X_Axis.PP[0][0] -= X_Axis.K_0 * X_Axis.t_0;       //后验估计误差协方差
+    X_Axis.PP[0][1] -= X_Axis.K_0 * X_Axis.t_1;
+    X_Axis.PP[1][0] -= X_Axis.K_1 * X_Axis.t_0;
+    X_Axis.PP[1][1] -= X_Axis.K_1 * X_Axis.t_1;
+        
+    X_Axis.angle   += X_Axis.K_0 * X_Axis.Angle_err;  //后验估计
+    X_Axis.Q_bias  += X_Axis.K_1 * X_Axis.Angle_err;  //后验估计
+    X_Axis.angle_dot   = GyroX - X_Axis.Q_bias;     //输出值(后验估计)的微分=角速度
+    
+    Y_Axis.angle+=(GyroY - Y_Axis.Q_bias) * Y_Axis.dt; //先验估计
+    Y_Axis.Pdot[0]=Y_Axis.Q_angle - Y_Axis.PP[0][1] - Y_Axis.PP[1][0]; // Pk-先验估计误差协方差的微分
+
+    Y_Axis.Pdot[1]=-Y_Axis.PP[1][1];
+    Y_Axis.Pdot[2]=-Y_Axis.PP[1][1];
+    Y_Axis.Pdot[3]=Y_Axis.Q_gyro;
+    Y_Axis.PP[0][0] += Y_Axis.Pdot[0] * Y_Axis.dt;   // Pk-先验估计误差协方差微分的积分
+    Y_Axis.PP[0][1] += Y_Axis.Pdot[1] * Y_Axis.dt;   // =先验估计误差协方差
+    Y_Axis.PP[1][0] += Y_Axis.Pdot[2] * Y_Axis.dt;
+    Y_Axis.PP[1][1] += Y_Axis.Pdot[3] * Y_Axis.dt;
+        
+    Y_Axis.Angle_err = AccelY - Y_Axis.angle;  //zk-先验估计
+    
+    Y_Axis.PCt_0 = Y_Axis.C_0 * Y_Axis.PP[0][0];
+    Y_Axis.PCt_1 = Y_Axis.C_0 * Y_Axis.PP[1][0];
+    
+    Y_Axis.E = Y_Axis.R_angle + Y_Axis.C_0 * Y_Axis.PCt_0;
+    
+    Y_Axis.K_0 = Y_Axis.PCt_0 / Y_Axis.E;
+    Y_Axis.K_1 = Y_Axis.PCt_1 / Y_Axis.E;
+    
+    Y_Axis.t_0 = Y_Axis.PCt_0;
+    Y_Axis.t_1 = Y_Axis.C_0 * Y_Axis.PP[0][1];
+
+    Y_Axis.PP[0][0] -= Y_Axis.K_0 * Y_Axis.t_0;       //后验估计误差协方差
+    Y_Axis.PP[0][1] -= Y_Axis.K_0 * Y_Axis.t_1;
+    Y_Axis.PP[1][0] -= Y_Axis.K_1 * Y_Axis.t_0;
+    Y_Axis.PP[1][1] -= Y_Axis.K_1 * Y_Axis.t_1;
+        
+    Y_Axis.angle   += Y_Axis.K_0 * Y_Axis.Angle_err;  //后验估计
+    Y_Axis.Q_bias  += Y_Axis.K_1 * Y_Axis.Angle_err;  //后验估计
+    Y_Axis.angle_dot   = GyroY - Y_Axis.Q_bias;     //输出值(后验估计)的微分=角速度
+}
+
+//////////////////////////////////////////////////////////////////////////////////   
+//功能 : 主中断的服务函数
+//参数 : 无
+//返回值 : 无                              
+//////////////////////////////////////////////////////////////////////////////////
+
+void MainInterruptIRQ(void)
+{
+    float cpu_usage = 0;
+    //系统监控部分代码
+    TimeNow = SystemTimer.read_us();
+    if(Flag_MeasureFreq)
+    {
+        FreqTime = TimeNow;
+        FreqCounter = MainInterruptCounter;
+        Flag_MeasureFreq = false;
+    } 
+    if((MainInterruptCounter - FreqCounter) == 100)
+    {
+        MainInterruptFreq = 100.0 * 1000000 / (TimeNow - FreqTime);
+        Flag_MeasureFreq = true;
+    }
+    MainInterruptCounter++;
+    
+    
+    //temp=MPU_Get_Temperature(); //得到温度值
+    MPU_Get_Accelerometer(&aacx,&aacy,&aacz);   //得到加速度传感器数据
+    MPU_Get_Gyroscope(&gyrox,&gyroy,&gyroz);    //得到陀螺仪数据
+    if(gyroy>32768)  gyroy-=65536;                       //数据类型转换  也可通过short强制类型转换
+    if(gyroz>32768)  gyroz-=65536;                       //数据类型转换
+    if(gyrox>32768)  gyrox-=65536;                       //数据类型转换
+    if(aacx>32768) aacx-=65536;                      //数据类型转换
+    if(aacz>32768) aacz-=65536;                      //数据类型转换
+    if(aacy>32768) aacy-=65536;                      //数据类型转换
+
+    ThetaXz=atan2((double)aacy,(double)aacz)*180/PI;  //重力加速度在XOZ、YOZ面上与z轴夹角
+    ThetaYz=atan2((double)aacx,(double)aacz)*180/PI;                 //计算倾角   
+    gyroy=gyroy/16.4;                                    //陀螺仪量程转换
+    gyrox=gyrox/16.4;                                    //陀螺仪量程转换
+    Kalman_Filter(ThetaXz,-gyrox, ThetaYz,-gyroy);
+
+    Processing(); //用户进程
+    cpu_usage = (float)(SystemTimer.read_us() - TimeNow) / 10000; //计算CPU使用率
+    if(cpu_usage > 0)
+        CpuUsage = cpu_usage;
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////////////   
+//功能 : 系统初始化
+//参数 : 无
+//返回值 : 无                              
+//////////////////////////////////////////////////////////////////////////////////
+void System_Init(void)
+{
+    SystemTimer.start();
+
+    //TFT.DispInit();
+    //TFT.FillScreen(ILI9340_BLACK);
+    //TFT.SetRotation(3);
+    //TFT.DrawString("System initing......", 50, 120, 3, ILI9340_WHITE);
+    
+    MPU_Init();
+    MainInterrupt.attach(&MainInterruptIRQ, 0.01);
+    
+    Flag_MeasureFreq = true; //开始一次测量
+    
+    X_Axis.K1 = 0.02;
+    X_Axis.Q_angle=0.001;
+    X_Axis.Q_gyro=0.003;
+    X_Axis.R_angle=0.5;
+    X_Axis.dt=0.005;
+    X_Axis.C_0 = 1;
+    X_Axis.Pdot[0] = 0;
+    X_Axis.Pdot[1] = 0;
+    X_Axis.Pdot[2] = 0;
+    X_Axis.Pdot[3] = 0;
+    X_Axis.PP[0][0]=1;
+    X_Axis.PP[0][1]=0;
+    X_Axis.PP[1][0]=1;
+    X_Axis.PP[1][1]=0;
+    
+    Y_Axis.K1 = 0.02;
+    Y_Axis.Q_angle=0.001;
+    Y_Axis.Q_gyro=0.003;
+    Y_Axis.R_angle=0.5;
+    Y_Axis.dt=0.005;
+    Y_Axis.C_0 = 1;
+    Y_Axis.Pdot[0] = 0;
+    Y_Axis.Pdot[1] = 0;
+    Y_Axis.Pdot[2] = 0;
+    Y_Axis.Pdot[3] = 0;
+    Y_Axis.PP[0][0]=1;
+    Y_Axis.PP[0][1]=0;
+    Y_Axis.PP[1][0]=1;
+    Y_Axis.PP[1][1]=0;
+}
+
+//此处--推荐--配置外设、定义全局变量
+//-------------------代码块开始
+
+//DigitalOut myled(LED1);
+AnalogIn LeftJoystickX(Pin_LeftJoystickX);
+AnalogIn LeftJoystickY(Pin_LeftJoystickY);
+AnalogIn RightJoystickX(Pin_RightJoystickX);
+AnalogIn RightJoystickY(Pin_RightJoystickY);
+
+float LeftJoystickValueX = 0.0, LeftJoystickValueY = 0.0, RightJoystickValueX = 0.0, RightJoystickValueY = 0.0;  //摇杆x,y轴的读数 归一化到 0-1
+
+Servo Servo1(Pin_Servo1);
+Servo Servo2(Pin_Servo2);
+Servo Servo3(Pin_Servo3);
+Servo Servo4(Pin_Servo4);
+Servo Servo5(Pin_Servo5);
+Servo Servo6(Pin_Servo6);
+Servo Servo7(Pin_Servo7);
+Servo Servo8(Pin_Servo8);
+Servo Servo9(Pin_Servo9);
+Servo Servo10(Pin_Servo10);
+Servo Servo11(Pin_Servo11);
+Servo Servo12(Pin_Servo12);
+
+Serial UserUart(PC_10, PC_11);
+
+
+//-------------------代码块结束
+
+    int i = 0, j;
+        float degree1 =  45.0, degree2 = 135.0;
+//////////////////////////////////////////////////////////////////////////////////   
+//功能 : 用户进程函数 用于执行用户自定义的后台任务 执行频率是100Hz
+//参数 : 无
+//返回值 : 无                              
+//////////////////////////////////////////////////////////////////////////////////
+void Processing(void)
+{
+    LeftJoystickValueX = LeftJoystickX.read();
+    LeftJoystickValueY = LeftJoystickY.read();
+    RightJoystickValueX = RightJoystickX.read();
+    RightJoystickValueY = RightJoystickY.read();
+    if((MainInterruptCounter % 50) == 0)
+        {
+            if(i == 0)
+            {
+                i = !i;
+                Servo1.SetDegree(degree1);
+                Servo2.SetDegree(degree1);
+                Servo3.SetDegree(degree1);
+                Servo4.SetDegree(degree1);
+                Servo5.SetDegree(degree1);
+                Servo6.SetDegree(degree1);
+                Servo7.SetDegree(degree1);
+                Servo8.SetDegree(degree1);
+                Servo9.SetDegree(degree1);
+                Servo10.SetDegree(degree1);
+                Servo11.SetDegree(degree1);
+                Servo12.SetDegree(degree1);
+            }
+            else
+            {
+                i = !i;
+                Servo1.SetDegree(degree2);
+                Servo2.SetDegree(degree2);
+                Servo3.SetDegree(degree2);
+                Servo4.SetDegree(degree2);
+                Servo5.SetDegree(degree2);
+                Servo6.SetDegree(degree2);
+                Servo7.SetDegree(degree2);
+                Servo8.SetDegree(degree2);
+                Servo9.SetDegree(degree2);
+                Servo10.SetDegree(degree2);
+                Servo11.SetDegree(degree2);
+                Servo12.SetDegree(degree2);
+            }
+        }
+}
+ 
+int main() 
+{
+    ILI9340_Display TFT = ILI9340_Display(Pin_TFT_MOSI, Pin_TFT_MISO, Pin_TFT_SCLK, Pin_TFT_CS, Pin_TFT_RESET, Pin_TFT_DC); //液晶屏初始化 已知bug 液晶屏类的定义必须在所有DigitalOut类的定义之后否则无法正常工作
+    TFT_LED = 1; //点亮TFT背光
+    TFT.DispInit();
+    TFT.FillScreen(ILI9340_BLACK);
+    TFT.SetRotation(3);
+    TFT.DrawString("iCenter", 76, 86, 3, ILI9340_WHITE);
+    TFT.DrawString("System initing...", 24, 146, 2, ILI9340_WHITE);
+    System_Init();
+    TFT.DrawString("iCenter", 76, 86, 3, ILI9340_BLACK);
+    TFT.DrawString("System initing...", 24, 146, 2, ILI9340_BLACK);
+    
+    while(true) {    
+        printf("CPU Usage : %.2f\r\n", CpuUsage);
+        printf("Pitch : %.2f\r\n", Y_Axis.angle);
+        printf("Roll : %.2f\r\n", X_Axis.angle);
+        printf("LeftJoystickValueX : %.2f\r\n", LeftJoystickValueX);
+        printf("LeftJoystickValueY : %.2f\r\n", LeftJoystickValueY);
+        printf("RightJoystickValueX : %.2f\r\n", RightJoystickValueX);
+        printf("RightJoystickValueY : %.2f\r\n", RightJoystickValueY);
+        
+        // Small amount of text to the display.
+        
+        
+        // Do the waiting thang...
+        wait(0.5);
+
+    }
+}
diff -r 000000000000 -r 9b8df4f9b792 mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Thu Mar 16 13:07:14 2017 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/ad3be0349dc5
\ No newline at end of file
diff -r 000000000000 -r 9b8df4f9b792 mpu6050_config.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mpu6050_config.h	Thu Mar 16 13:07:14 2017 +0000
@@ -0,0 +1,92 @@
+#ifndef __MPU6050_CONFIG_H
+#define __MPU6050_CONFIG_H
+                                                   
+//////////////////////////////////////////////////////////////////////////////////   
+//本程序只供学习使用,未经作者许可,不得用于其它任何用途                                  
+////////////////////////////////////////////////////////////////////////////////// 
+
+///////////////////////////////////////
+//mp6050.h
+///////////////////////////////////////
+  
+//#define MPU_ACCEL_OFFS_REG        0X06    //accel_offs寄存器,可读取版本号,寄存器手册未提到
+//#define MPU_PROD_ID_REG           0X0C    //prod id寄存器,在寄存器手册未提到
+#define MPU_SELF_TESTX_REG      0X0D    //自检寄存器X
+#define MPU_SELF_TESTY_REG      0X0E    //自检寄存器Y
+#define MPU_SELF_TESTZ_REG      0X0F    //自检寄存器Z
+#define MPU_SELF_TESTA_REG      0X10    //自检寄存器A
+#define MPU_SAMPLE_RATE_REG     0X19    //采样频率分频器
+#define MPU_CFG_REG             0X1A    //配置寄存器
+#define MPU_GYRO_CFG_REG        0X1B    //陀螺仪配置寄存器
+#define MPU_ACCEL_CFG_REG       0X1C    //加速度计配置寄存器
+#define MPU_MOTION_DET_REG      0X1F    //运动检测阀值设置寄存器
+#define MPU_FIFO_EN_REG         0X23    //FIFO使能寄存器
+#define MPU_I2CMST_CTRL_REG     0X24    //IIC主机控制寄存器
+#define MPU_I2CSLV0_ADDR_REG    0X25    //IIC从机0器件地址寄存器
+#define MPU_I2CSLV0_REG         0X26    //IIC从机0数据地址寄存器
+#define MPU_I2CSLV0_CTRL_REG    0X27    //IIC从机0控制寄存器
+#define MPU_I2CSLV1_ADDR_REG    0X28    //IIC从机1器件地址寄存器
+#define MPU_I2CSLV1_REG         0X29    //IIC从机1数据地址寄存器
+#define MPU_I2CSLV1_CTRL_REG    0X2A    //IIC从机1控制寄存器
+#define MPU_I2CSLV2_ADDR_REG    0X2B    //IIC从机2器件地址寄存器
+#define MPU_I2CSLV2_REG         0X2C    //IIC从机2数据地址寄存器
+#define MPU_I2CSLV2_CTRL_REG    0X2D    //IIC从机2控制寄存器
+#define MPU_I2CSLV3_ADDR_REG    0X2E    //IIC从机3器件地址寄存器
+#define MPU_I2CSLV3_REG         0X2F    //IIC从机3数据地址寄存器
+#define MPU_I2CSLV3_CTRL_REG    0X30    //IIC从机3控制寄存器
+#define MPU_I2CSLV4_ADDR_REG    0X31    //IIC从机4器件地址寄存器
+#define MPU_I2CSLV4_REG         0X32    //IIC从机4数据地址寄存器
+#define MPU_I2CSLV4_DO_REG      0X33    //IIC从机4写数据寄存器
+#define MPU_I2CSLV4_CTRL_REG    0X34    //IIC从机4控制寄存器
+#define MPU_I2CSLV4_DI_REG      0X35    //IIC从机4读数据寄存器
+
+#define MPU_I2CMST_STA_REG      0X36    //IIC主机状态寄存器
+#define MPU_INTBP_CFG_REG       0X37    //中断/旁路设置寄存器
+#define MPU_INT_EN_REG          0X38    //中断使能寄存器
+#define MPU_INT_STA_REG         0X3A    //中断状态寄存器
+
+#define MPU_ACCEL_XOUTH_REG     0X3B    //加速度值,X轴高8位寄存器
+#define MPU_ACCEL_XOUTL_REG     0X3C    //加速度值,X轴低8位寄存器
+#define MPU_ACCEL_YOUTH_REG     0X3D    //加速度值,Y轴高8位寄存器
+#define MPU_ACCEL_YOUTL_REG     0X3E    //加速度值,Y轴低8位寄存器
+#define MPU_ACCEL_ZOUTH_REG     0X3F    //加速度值,Z轴高8位寄存器
+#define MPU_ACCEL_ZOUTL_REG     0X40    //加速度值,Z轴低8位寄存器
+
+#define MPU_TEMP_OUTH_REG       0X41    //温度值高八位寄存器
+#define MPU_TEMP_OUTL_REG       0X42    //温度值低8位寄存器
+
+#define MPU_GYRO_XOUTH_REG      0X43    //陀螺仪值,X轴高8位寄存器
+#define MPU_GYRO_XOUTL_REG      0X44    //陀螺仪值,X轴低8位寄存器
+#define MPU_GYRO_YOUTH_REG      0X45    //陀螺仪值,Y轴高8位寄存器
+#define MPU_GYRO_YOUTL_REG      0X46    //陀螺仪值,Y轴低8位寄存器
+#define MPU_GYRO_ZOUTH_REG      0X47    //陀螺仪值,Z轴高8位寄存器
+#define MPU_GYRO_ZOUTL_REG      0X48    //陀螺仪值,Z轴低8位寄存器
+
+#define MPU_I2CSLV0_DO_REG      0X63    //IIC从机0数据寄存器
+#define MPU_I2CSLV1_DO_REG      0X64    //IIC从机1数据寄存器
+#define MPU_I2CSLV2_DO_REG      0X65    //IIC从机2数据寄存器
+#define MPU_I2CSLV3_DO_REG      0X66    //IIC从机3数据寄存器
+
+#define MPU_I2CMST_DELAY_REG    0X67    //IIC主机延时管理寄存器
+#define MPU_SIGPATH_RST_REG     0X68    //信号通道复位寄存器
+#define MPU_MDETECT_CTRL_REG    0X69    //运动检测控制寄存器
+#define MPU_USER_CTRL_REG       0X6A    //用户控制寄存器
+#define MPU_PWR_MGMT1_REG       0X6B    //电源管理寄存器1
+#define MPU_PWR_MGMT2_REG       0X6C    //电源管理寄存器2 
+#define MPU_FIFO_CNTH_REG       0X72    //FIFO计数寄存器高八位
+#define MPU_FIFO_CNTL_REG       0X73    //FIFO计数寄存器低八位
+#define MPU_FIFO_RW_REG         0X74    //FIFO读写寄存器
+#define MPU_DEVICE_ID_REG       0X75    //器件ID寄存器
+ 
+//如果AD0脚(9脚)接地,IIC地址为0X68(不包含最低位).
+//如果接V3.3,则IIC地址为0X69(不包含最低位).
+#define MPU_ADDR                0X68
+
+
+////因为模块AD0默认接GND,所以转为读写地址后,为0XD1和0XD0(如果接VCC,则为0XD3和0XD2)  
+//#define MPU_READ    0XD1
+//#define MPU_WRITE   0XD0
+
+
+
+#endif
diff -r 000000000000 -r 9b8df4f9b792 servo/Servo.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/servo/Servo.h	Thu Mar 16 13:07:14 2017 +0000
@@ -0,0 +1,33 @@
+#ifndef __SERVO_H
+#define __SERVO_H
+#include "mbed.h"
+
+//舵机类 
+/*class Servo
+{
+    public:
+        Servo(PinName pin);
+        void SetDegree(float degree);
+  
+    private:  
+        PwmOut _pin;
+};*/
+
+class Servo
+{
+    public:
+        Servo(PinName pin) : _pin(pin) 
+        {
+            _pin = 0;
+        }
+        void SetDegree(float degree)
+        {
+            float duty = (degree/180.0*2+0.5)/20;
+            _pin.period_ms(20);
+            _pin.write(duty);
+        }
+    private:  
+        PwmOut _pin;
+};
+
+#endif
\ No newline at end of file