STM32CubeMX配置工程移植dmp库配合匿名四轴上位机三维动态显示测试
创始人
2024-06-02 01:28:47

STM32CubeMX配置工程移植dmp库配合匿名四轴上位机三维动态显示测试

  • 📌相关篇《STM32F1基于STM32CubeMX配置移植dmp库通过串口打印MPU6050数据》
  • 📍参考文章《STM32 MPU6050与匿名上位机通讯(V2.6版)》
  • ✨该工程代码匹配的是匿名四轴上位机软件的2.6版本通讯协议,所以支持使用2.6版本的,最新的版本不支持
  • 🔖STM32CubeMX默认配置的是stm32F103C8T6
  • 📺演示效果:
    在这里插入图片描述

🌼STM32CubeMX工程配置说明

  • 🌿使用STM32CubeMX仅配置了串口1和I2C1。

在这里插入图片描述

🛠接线说明

匿名四轴上位机软件是通过对串口1数据进行解析后才能正确读取和显示出来的。

stm32 ------ MPU6050
PB6(SCL)  ----  SCL
PB7(SDA)  ----  SDAVCC 	----  VCC(3.3V)GND  	----  GND-------串口1:PA9 、 PA10

📑匿名四轴上位机2.6版本通讯协议介绍

通讯代码都是基于通讯协议编写的,就好像对暗号一样,暗号正确才会进行数据传输。

  • 🎉通讯协议可以打开匿名上位机软件,按F12查看,以下是2.6版本通讯协议的全部内容:

一 :基本收发

1:收码和发码格式均可设为HEX或者CHR。
2:定时发送功能可以精确到毫秒,但是不能太快(发送为独占式,数据不发送完函数不会返回),如果上一帧
数据还没发送完毕就发送下一帧数据会出错。
3:请使用ft232串口芯片或支持高波特率的芯片,否则波特率无法设置过高。

二:高级收码

  1. 收码显示为HEX格式。
  2. 下位机发送自定义数据,格式为:0x88+FUN+LEN+DATA+SUM
    FUN可以是 0xA1到0xAA,共10个;LEN为DATA的长度(不包括0x88、FUN、LEN、SUM)。
    SUM是0x88一直到DATA最后一字节的和,uint8格式。(记得打开需要使用帧的开关,更改设置后点击保存设置使设置生效)
  3. 数据可以是uint8、int16、uint16、int32、float这几个常用格式,多字节数据高位在前。
  4. 共有20个数据存储器,每个存储器的数据可以分别设置为来自10个自定义帧的30个数据。
  5. 高速通讯时(2ms一帧数据或者更快),请关闭高级收码页面的数据显示按钮和基本收码,否则更新过快有可能会造成程序卡死。
  6. 飞控显示对应的帧FUN为0xAF,(帧格式:0x88+0xAF+0x1C+ACC DATA+GYRO DATA+MAG DATA+ANGLE DATA + 0x00 0x00 + 0x00 0x00+SUM,共32字节,ACC/GYRO/MAG/ANGLE(roll/pitch/yaw)数据为int16格式,其中ANGLE的roll和pitch数据为实际值乘以100以后得到的整数值,yaw为乘以10以后得到的整数值,上位机在显示时再 除以100和10)。
  7. 遥控,电机pwm,电压显示对应的帧FUN为0xAE,(帧格式:0x88+0xAE+0x12+THROT YAW ROLL PITCH+AUX1 2 3 4 5 + PWM:1 2 3 4 + VOTAGE + SUM,共28字节),数据为uint16格式,遥控数据最小在1000左右,最大在2000左右。数据都为uint16格式,其中pwm范围1-100,votage为实际值*100。
    小技巧:如果高速通讯时是为了画波形,就只开波形显示,并只保留需要观察的波形,如果是为了观察数据,就关闭波形显示,只保留收码显示,这样可以加快程序响应速度。
  8. 最快通讯速度测试过下位机用500K波特率,每1ms发送32字节的数据,上位机显示其中6条波形,OK!(有可能和电脑配置有关)

三:波形显示

1:共有20条波形,对应20个数据存储器。
2:双击波形绘制区域,可以打开波形显示开关。
3:按住Ctrl用鼠标左键点击某一条波形,可以显示数据标签,再次点击隐藏。
4:按住鼠标左键,在绘图区域从一点向右下方拖动,然后松开,可以放大显示框住的波形区域,可以多次放大;
5:按住鼠标左键,在绘图区域从一点向左上方拖动,然后松开,可以将放大后的波形还原。
6:按住鼠标右键,在绘图区域上下左右拖动,可以移动波形。
7:显示波形时按F9键,可以打开波形高级设置。

四:DEBUG功能

  1. 在调试过程中可以将某些标志位、寄存器、变量实时发回上位机,并在DEBUG页面显示。
  2. 通讯格式为:0x88 + 0xAD + len + num + DATA + SUM, len为num与DATA的总长度,num表示要改变哪个显示状态,例如num=0x01即是要改变第一个LED,num=0x07即是改变第一个数字输出显示。当要改变LED时,DATA只需一字节,DATA=0x00表示关闭LED,大于0x00表示点亮LED;当要改变数字输出时,DATA需要两字节,表示 一个uint16数字,高字节在前。SUM为从0x88开始到SUM前一字节的和校验,uint8格式。

例如:发送 0x88 + 0xAD + 0x02 + 0x01 + 0x01 + 0x39 表示点亮第一个LED
发送 0x88 + 0xAD + 0x03 + 0x07 + 0x00 + 0x05 + 0x44 表示在第一个数字输出位置显示 5 。

五:键鼠控制

  1. 控制数据发送格式为:0x8A + 0x8A + 0X1C + THROT YAW ROLL PITCH AUX1 AUX2 AUX3 AUX4 AUX5 + 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 + SUM,遥控数据都为int16格式,中值1500,最小最大值为1000、 2000。
  2. 发送频率 50Hz。
  3. 鼠标上下控制油门,左右控制YAW,键盘的WASD控制ROLL/PITCH,键盘12345控制AUX12345。共9通道。

六:飞控参数

  1. 点击3D模型显示右下方的校正按钮,上位机会发送0X8A 0X8B 0X1C 0XAA 0XA3 +无用数据+SUM给下位机,
    其中0X8B表示飞控参数,0XAA表示零偏,0XA3表示ACC GYRO都要校正。
  2. 点击飞控参数界面传感器矫正功能里面的校正按钮,分别表示ACC 和GYRO的校正,不会同时校正两个传感器,上位机校正ACC发送格式为:0X8A 0X8B 0X1C 0XAA 0XA1+无用数据+SUM上位机校正GYRO发送格式为:0X8A 0X8B 0X1C 0XAA 0XA2+无用数据+SUM(送有数据整个长度都为32字节)
  3. 上位机发送微调后的offset数据(仅为ACC的 X 和 Y ),格式为0X8A 0X8B 0X1C 0XAB + offset.x + offset.y +无用数据 +SUM,数据为int16格式。
  4. 上位机发送读offset的命令格式为:0X8A 0X8B 0X1C 0XAC + 无用数据 + SUM
  5. 上位机发送读PID数据的命令为:0X8A 0X8B 0X1C 0XAD + 无用数据 + SUM
  6. 下位机发送offset数据给上位机的格式为:0X88 0XAC 0X1C 0XAC + 传感器零偏数据ACC XYZ GYRO XYZ +无用数据+SUM,共六个int16型数据。
  7. 下位机发送PID数据给上位机的格式为:0X88 0XAC 0X1C 0XAD + PID数据 + 无用数据 + SUM
    PID数据为rol_p,rol_i,rol_d,pit_p…i…d,yaw_p,i,d,共9个uint16型数据。
  8. 上位机发送PID数据给下位机的格式为:0X8A 0X8B 0X1C 0XAE +PID数据+ 无用数据 + SUM
    PID数据格式和下位机发送给上位机的格式一样。
  9. 点击飞控解锁按钮,上位机会发送0X8A 0X8B 0X1C 0XA1+无用数据+SUM给下位机,如果下位机已经解锁,点击此按钮会发送0X8A 0X8B 0X1C 0XA0+无用数据+SUM给下位机,锁定飞控。

在上面的相关参考文章中,前者总结的5个通讯办法如下:

  • 1个自定义数据帧+4个官方数据帧
    自定义数据帧:发送MPU6050的原始数据 和 官方数据帧。
  • 官方数据帧:
    1. 飞控显示帧,实现在上位机上观看到四轴的3D动画和波形
    1. 遥控器数据发送帧:将遥控器的各个数据发送到上位机包括PWM占空比
    1. PID数据发送帧:将STM32中设定的PID参数发送到上位机
    1. 零偏数据发送帧:将STM32中测定的零偏值发送给上位机

⛳上位机配置界面设置介绍(重点内容)

  • 🌿设置串口端口号和波特率(工程默认配置的是115200)具体参数如下:
    在这里插入图片描述

  • 高级收码配置项:
    在这里插入图片描述

  • 🌿波形显示,勾选对应的串口端口号,开启高级收码,飞控波形按钮都要打开。
    在这里插入图片描述

  • 🌿飞控状态,根据个人需求勾选

在这里插入图片描述

  • 🌿飞行控制,不用管,代码工程中没有涉及到此功能,只是观测效果。
    在这里插入图片描述

🔨状态开启和切换

🔰下面一排是功能开启,绿色状态的为开启状态,暗绿的是没有开启。如果要看效果,一定要开启高级收码

  • 波形状态切换到飞控状态,可以直接点击下面的键鼠控制按键即可完成切换,但是要切换到波形状态需要通过点击左侧边上的飞控状态,才可切换回去。
    在这里插入图片描述

📝主程序代码部分

/* USER CODE BEGIN Header *///相关接线
//stm32			MPU6050
//PB6(SCL)  ----  SCL
//PB7(SDA)  ----  SDA
// VCC 		----  VCC
// GND  	----  GND/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "i2c.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
#include "stdio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes *//* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
#define u8  uint8_t
#define u16 uint16_t
#define u32 uint32_t
/* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV *//* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */void usart1_send_char(u8 c)
{HAL_UART_Transmit(&huart1 , &c, 1, 0xFFFF);
}
/**  *  功能:发送数据给匿名上位机(V2.6)*  入口参数:fun,功能字,0xA0~0xAF*			   data,数据缓存区,最多28个字节*			   len,data数据长度*  返回值:无*  注:数据格式:0x88+FUN+LEN+DATA+SUM*/
void usart1_niming_report(u8 fun,u8 *data,u8 len)
{u8 send_buf[32]={0x00};u8 i;if(len>28) return;//超过28个字节,无效send_buf[len+3]=0;//校验位置零send_buf[0]=0x88;//帧头0x88send_buf[1]=fun;//命令帧FUNsend_buf[2]=len;//数据长度帧LENfor(i=0;iu8 buf[12];buf[0]=(aacx>>8)&0xFF;buf[1]=aacx&0xFF;buf[2]=(aacy>>8)&0xFF;buf[3]=aacy&0xFF;buf[4]=(aacz>>8)&0xFF;buf[5]=aacz&0xFF;buf[6]=(gyrox>>8)&0xFF;buf[7]=gyrox&0xFF;buf[8]=(gyroy>>8)&0xFF;buf[9]=gyroy&0xFF;buf[10]=(gyroz>>8)&0xFF;buf[11]=gyroz&0xFF;usart1_niming_report(0xA1,buf,12);
}/**  飞控显示帧*  功能:上报解算后的姿态数据给上位机*  入口参数:aacx,aacy,aacz:xyz三个方向的加速度值*			   gyrox,gyroy,gyroz:xyz三个方向的陀螺仪值		*			   yaw,偏航角,单位为0.1度 0 -> 3600  对应 0 -> 360.0度*			   roll,横滚角,单位0.01度。 -18000 -> 18000 对应 -180.00  ->  180.00度*			   pitch,俯仰角,单位 0.01度。-9000 - 9000 对应 -90.00 -> 90.00 度*  返回值:无*  注:数据格式:0x88+0xAF+0x1C+ ACC DATA + GYRO DATA + MAG DATA + ANGLE DATA(roll/pitch/yaw) +0x00+0x00+0x00+0x00+SUM*		 ANGLE的roll和pitch数据为实际值乘以100以后得到的整数值,yaw为乘以10以后得到的整数值*/
void usart1_report_imu(short aacx,short aacy,short aacz,short gyrox,short gyroy,short gyroz,short roll,short pitch,short yaw)
{u8 buf[28]={0x00};buf[0]=(aacx>>8)&0xFF;buf[1]=aacx&0xFF;buf[2]=(aacy>>8)&0xFF;buf[3]=aacy&0xFF;buf[4]=(aacz>>8)&0xFF;buf[5]=aacz&0xFF;buf[6]=(gyrox>>8)&0xFF;buf[7]=gyrox&0xFF;buf[8]=(gyroy>>8)&0xFF;buf[9]=gyroy&0xFF;buf[10]=(gyroz>>8)&0xFF;buf[11]=gyroz&0xFF;//12-17为磁力计,MPU6050没有磁力计,发送0x00buf[18]=(roll>>8)&0xFF;buf[19]=roll&0xFF;buf[20]=(pitch>>8)&0xFF;buf[21]=pitch&0xFF;buf[22]=(yaw>>8)&0xFF;buf[23]=yaw&0xFF;//24-27为数据格式中的0x00usart1_niming_report(0xAF,buf,28);
}/**  *  功能:发送PID数据给上位机*  入口参数:rol_p,rol_i,rol_d,pit_p,pit_i,pit_d,yaw_p,yaw_i,yaw_d*  返回值:无*	 格式为:0X88 0XAC 0X1C 0XAD + PID数据 + 无用数据 + SUM*/
void usart1_report_pid(u16 rol_p,u16 rol_i,u16 rol_d,u16 pit_p,u16 pit_i,u16 pit_d,u16 yaw_p,u16 yaw_i,u16 yaw_d)
{u8 buf[28]={0x00};buf[0]=0xAD;buf[1]=(rol_p>>8)&0xFF;buf[2]=rol_p&0xFF;buf[3]=(rol_i>>8)&0xFF;buf[4]=rol_i&0xFF;buf[5]=(rol_d>>8)&0xFF;buf[6]=rol_d&0xFF;buf[7]=(pit_p>>8)&0xFF;buf[8]=pit_p&0xFF;buf[9]=(pit_i>>8)&0xFF;buf[10]=pit_i&0xFF;buf[11]=(pit_d>>8)&0xFF;buf[12]=pit_d&0xFF;buf[13]=(yaw_p>>8)&0xFF;buf[14]=yaw_p&0xFF;buf[15]=(yaw_i>>8)&0xFF;buf[16]=yaw_i&0xFF;buf[17]=(yaw_d>>8)&0xFF;buf[18]=yaw_d&0xFF;usart1_niming_report(0xAC,buf,28);}/**  *  功能:遥控,电机pwm,电压显示*  入口参数:throt,yaw,roll,pitch,aux1,aux2,aux3,aux4,aux5,pwm1,pwm2,pwm3,pwm4,vol(电压)*  返回值:无*  帧格式:0x88+0xAE+0x12+THROT YAW ROLL PITCH AUX1 2 3 4 5 PWM:1 2 3 4 VOLTAGE+SUM遥控数据最小在1000左右,最大在2000左右。数据都为uint16格式,其中pwm范围1-100,voltage为实际值*100。*/
void usart1_report_rc(short thort,short yaw,short roll,short pitch,short aux1,short aux2,short aux3,short aux4,short aux5,short pwm1,short pwm2,short pwm3,short pwm4,short vol)
{u8 buf[28]={0x00};//THROT YAW ROLL PITCH	buf[0]=(thort>>8)&0xFF;//buf[1]=thort&0xFF;//buf[2]=(yaw>>8)&0xFF;//buf[3]=yaw&0xFF;//buf[4]=(roll>>8)&0xFF;//buf[5]=roll&0xFF;	//buf[6]=(pitch>>8)&0xFF;//buf[7]=pitch&0xFF;////AUX1 2 3 4 5buf[8]=(aux1>>8)&0xFF;buf[9]=aux1&0xFF;buf[10]=(aux2>>8)&0xFF;buf[11]=aux2&0xFF;buf[12]=(aux3>>8)&0xFF;buf[13]=aux3&0xFF;buf[14]=(aux4>>8)&0xFF;buf[15]=aux4&0xFF;buf[16]=(aux5>>8)&0xFF;buf[17]=aux5&0xFF;	//PWM:1 2 3 4 buf[18]=(pwm1>>8)&0xFF;buf[19]=pwm1&0xFF;buf[20]=(pwm2>>8)&0xFF;buf[21]=pwm2&0xFF;buf[22]=(pwm3>>8)&0xFF;buf[23]=pwm3&0xFF;buf[24]=(pwm4>>8)&0xFF;buf[25]=pwm4&0xFF;//VOLTAGEbuf[26]=(vol>>8)&0xFF;buf[27]=vol&0xFF;usart1_niming_report(0xAE,buf,28);
}/**  *  功能:发送offset给上位机*  入口参数:acc_x,acc_y,acc_z,gyro_x,gyro_y,gyro_z*  返回值:无*  格式为:0X88 0XAC 0X1C 0XAC + 传感器零偏数据ACC XYZ GYRO XYZ+无用数据+SUM*/
void usart1_report_offset(short acc_x,short acc_y,short acc_z,short gyro_x,short gyro_y,short gyro_z)
{u8 buf[28]={0x00};buf[0]=0xAC;buf[1]=(acc_x>>8)&0xFF;buf[2]=acc_x&0xFF;buf[3]=(acc_y>>8)&0xFF;buf[4]=acc_y&0xFF;buf[5]=(acc_z>>8)&0xFF;buf[6]=acc_z&0xFF;	buf[7]=(gyro_x>>8)&0xFF;buf[8]=gyro_x&0xFF;buf[9]=(gyro_y>>8)&0xFF;buf[10]=gyro_y&0xFF;buf[11]=(gyro_z>>8)&0xFF;buf[12]=gyro_z&0xFF;usart1_niming_report(0xAC,buf,28);
}/* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 *//* USER CODE END 0 *//*** @brief  The application entry point.* @retval int*/
int main(void)
{/* USER CODE BEGIN 1 */short aacx,aacy,aacz,gyrox,gyroy,gyroz,yaw,roll,pitch;/* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_I2C1_Init();MX_TIM1_Init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 */mpu_dmp_init();/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */dmp_getdata();
//		MPU6050_Read_Temp();pitch= (short)My_Mpu6050.pitch;yaw =(short)My_Mpu6050.yaw;roll =(short)My_Mpu6050.roll;aacx = My_Mpu6050.accel[0];aacy = My_Mpu6050.accel[1];aacz = My_Mpu6050.accel[2]; gyrox = My_Mpu6050.accel[0];gyroy = My_Mpu6050.accel[1];gyroz = My_Mpu6050.accel[2];mpu6050_send_data(aacx,aacy,aacz,gyrox,gyroy,gyroz);usart1_report_imu(aacx,aacy,aacz,gyrox,gyroy,gyroz,(int)(roll*100),(int)(pitch*100),(int)(yaw*10));usart1_report_rc(1500,(int)yaw,(int)roll,(int)pitch,1200,1200,1200,1200,1200,90,40,50,100,300);      usart1_report_pid(123,123,123,456,456,456,789,789,789);	usart1_report_offset(aacx,aacy,aacz,gyrox,gyroy,gyroz);//		printf("pitch:%.2f\r\n",My_Mpu6050.pitch);
//		printf("roll:%.2f\r\n",My_Mpu6050.roll);
//		printf("yaw:%.2f\r\n",My_Mpu6050.yaw);
//		printf("temperature:%.2f\r\n",My_Mpu6050.temperature);HAL_Delay(10);}/* USER CODE END 3 */
}/*** @brief System Clock Configuration* @retval None*/
void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/** Initializes the RCC Oscillators according to the specified parameters* in the RCC_OscInitTypeDef structure.*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;RCC_OscInitStruct.HSIState = RCC_HSI_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK){Error_Handler();}
}/* USER CODE BEGIN 4 */
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}/* USER CODE END 4 *//*** @brief  This function is executed in case of error occurrence.* @retval None*/
void Error_Handler(void)
{/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state */__disable_irq();while (1){}/* USER CODE END Error_Handler_Debug */
}#ifdef  USE_FULL_ASSERT
/*** @brief  Reports the name of the source file and the source line number*         where the assert_param error has occurred.* @param  file: pointer to the source file name* @param  line: assert_param error line source number* @retval None*/
void assert_failed(uint8_t *file, uint32_t line)
{/* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT *//************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

📚工程源码和上位机软件


链接: https://pan.baidu.com/s/1Z5biR0tEAJ-n3JjaWatoGw
提取码: jcha

相关内容

热门资讯

苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
阿西吧是什么意思 阿西吧相当于... 即使你没有受到过任何外语培训,你也懂四国语言。汉语:你好英语:Shit韩语:阿西吧(아,씨발! )日...