摘要:基于的移植教程可以看這里二介紹是一種用于嵌入式應用的圖形支持軟件。適用于使用任何控制和的任何尺寸的物理和虛擬顯示。一個層,稱作驅動程序,包含了對的全部訪問。并在主函數里加入下面的代碼,測試移植是否成功。
keil:? ? 5.25
MCU:? STM32F103ZET6
UCGUI版本:? 3.90(純源碼版本)
3.9.0是源碼版本,可以看到全部源碼,也方便學習;后續的版本都是提供lib庫文件,不再提供源碼了。
基于STM32的STemwin移植教程可以看這里:?https://blog.csdn.net/xiaolong1126626497/article/details/117933355https://blog.csdn.net/xiaolong1126626497/article/details/117933355
? ? ? μC/GUI 是一種用于嵌入式應用的圖形支持軟件。它被設計用于為任何使用一個圖形 LCD的應用提供一個有效的不依賴于處理器和 LCD 控制器的圖形用戶接口。它能工作于單任務或多任務的系統環境下。 μC/GUI 適用于使用任何 LCD 控制和 CPU 的任何尺寸的物理和虛擬顯示。它的設計是模塊化的,由在不同的模塊中的不同的層組成。一個層,稱作 LCD 驅動程序,包含了對 LCD 的全部訪問。 μC/GUI 適用于所有的 CPU,因為它 100%由的 ANSI 的 C 語言編寫的。
? ? μC/GUI 很適合大多數的使用黑色/白色和彩色 LCD 的應用程序。 它有一個很好的顏色管理器,允許它處理灰階。 ?μC/GUI 也提供一個可擴展的 2D 圖形庫和一個視窗管理器,在使用一個最小的 RAM 時能支持顯示窗口。
? ? UCGUI官網地址:Micrium Software and Documentation - Silicon Labs
?
?
①.GUI/LCDDriver 文件夾中存放的是一些 LCD 驅動代碼,如果你使用的 LCD 在
這里可以找到代碼,可以直接通過 Config 中的 LCDConfig.h :
#define LCD_CONTROLLER -1 // -1:表示沒有選擇的 LCD 驅動,而是使用里邊的樣本程序進行修改。
uCGUI 中具體支持哪些 LCD 可以查詢《uCGUI 用戶手冊》的第 22 章 LCD 驅動程序。里邊詳細的說明了,支持些什么控制器的 LCD。
②.在工程中只需加載需要的 LCD 驅動代碼文件即可。如果設置為-1,則選擇加載 LCDDummy.C 或 LCDTemplate.C 文件(不同的版本,此代碼的文件名可能會不同)。
文件夾的主要內容如下:
?Config??-----------????配置文件?
GUI????-----------????源代碼?
GUI_X??----------????操作系統接口函數定義文件???
GUI?源代碼文件:?
1)?AntiAlias:??抗鋸齒顯示效果支持。?
2)?ConvertColor:?彩色顯示的色彩轉換支持。?
3)?ConvertMono:?(b/w)和灰度顯示的色彩轉換支持。
?4)?Core:?核心文件,提供了GUI基本的功能。?
5)?Font:?字庫。?
6)?JPEG:?圖片操作函數。?
7)?LCDDriver:?LCD驅動支持。?
8)?MemDev:?內存設備支持。主要功能是防止在項目重疊時觸摸屏的閃爍。
?9)?Widget:?窗體控件庫。
?10)?WM:?窗口管理庫。?
??注意:JPEG、MemDev、Widget、WM是可裁剪項,若要支持Widget(窗體控件),需要
? ?WM(窗口管理器)的支持;使用控件時,需要將相應的頭文件包含進去,比如我們需要使用按鈕BUTTON,那么我們需要先包含BUTTON.h頭文件,否則控件即使支持也不可用。
移植準備工作:
首先在KEIL工程目錄下創建一個UCGUI的文件夾,用來存放移植需要用到的源碼文件。
效果圖:
?
? ? 將GUI_V3.9_官方源碼/uCGUI3.90版源碼/Start路徑下的Config文件夾和GUI文件拷貝到剛才在KEIL工程目錄下創建的UCGUI文件夾里。
? ?效果圖:
? ? ?將GUI_V3.9_官方源碼/uCGUI3.90版源碼/Sample路徑下的GUI_X文件夾拷貝到剛才在KEIL工程目錄下創建的UCGUI文件夾里。(GUI_X文件夾是操作系統的接口)
? ? 效果圖:
?
?
打開KEIL工程,添加UCGUI源代碼。
? ? 根據 UCGUI/GUI 目錄下的文件創建KEIL的工程目錄,名字最好用源碼默認的名字不要修改,以防止后面查找不方便。額外再添加創建一個UCGUI_Config目錄,用來存放UCGUI的配置文件創建好的工程目錄—效果圖:
工程創建OK之后,將對應源文件添加到KEIL工程目錄下,將對應的頭文件加入工程。
效果圖:
添加的源文件和頭文件需要對照GUI文件夾逐個添加,不能漏掉文件。
源文件只添加.c 。其他文件一律不添加。
UCGUI_Config文件夾添加的文件如下所示:
UCGUI/GUI_X/GUI_X.c //OS系統接口UCGUI/Config/GUITouchConf.h //配置觸摸屏UCGUI/Config/ GUIConf.h //配置GUIUCGUI/Config/ LCDConf.h //配置LCD顯示屏參數
?效果圖:
?
修改LCD配置文件,打開LCDConf.h文件,替換下面的代碼:
#ifndef LCDCONF_H#define LCDCONF_H#define LCD_XSIZE (240) /* 水平分辨率X-resolution of LCD, Logical coor. */#define LCD_YSIZE (320) /* 垂直分辨率Y-resolution of LCD, Logical coor. */#define LCD_BITSPERPIXEL (16) /*lcd 顏色深度*/#define LCD_CONTROLLER (-1) /*lcd 控制器的具體型號*/#define LCD_FIXEDPALETTE (565) /*RGB 顏色位數*/#define LCD_SWAP_RB (1) /*紅藍反色交換*/#define LCD_INIT_CONTROLLER() LCD9341_Init (); /*底層初始化函數,自己寫的,而非源碼自帶,這一步非常重要*/#endif /* LCDCONF_H */
?
因為我們有LCD的驅動,不需要UCGUI的LCD驅動配置。
其中:LCD9341_Init (); 函數是我們自己工程的LCD初始化函數。我們的LCD初始化函數名字不能是LCD_Init(),因為UCGUI自帶的LCD初始化函數也是這個名字,我們自己的工程里也不能出現LCD名字的結構體。不然,會出現重定義的錯誤。
?修改UCGUI配置文件,打開GUIConf.h文件,修改成下面的代碼:
#ifndef GUICONF_H#define GUICONF_H#define GUI_OS (0) /* 系統支持 */#define GUI_SUPPORT_TOUCH (0) /* 支持觸摸屏 */#define GUI_SUPPORT_UNICODE (0) /* 支持混合ASCII / UNICODE字符串 */#define GUI_DEFAULT_FONT &GUI_Font6x8//#define GUI_ALLOC_SIZE 12500 /* Size of dynamic memory ... For WM and memory devices*/#define GUI_ALLOC_SIZE 1024*1024 /* Size of dynamic memory ... For WM and memory devices*/#define GUI_WINSUPPORT 0 /* 窗口管理器包可用 */#define GUI_SUPPORT_MEMDEV 0 /* 內存設備可用 */#define GUI_SUPPORT_AA 0 /* 抗鋸齒可用 */#endif /* Avoid multiple inclusion */
?初次移植,將不需要用到的配置全部關閉,等UCGU的基本操作熟悉之后再打開使用。
打開LCDDummy.c文件,添加UCGUI底層的畫點函數和讀點函數。
先在LCDDummy.c里加入LCD頭文件。并且定義使用自己的LCD驅動。
添加畫點函數
該函數在LCDDummy.c文件(大約382行)處。
void LCD_L0_SetPixelIndex(int x, int y, int PixelIndex) { /* Convert logical into physical coordinates (Dep. on LCDConf.h) */ #if LCD_SWAP_XY | LCD_MIRROR_X| LCD_MIRROR_Y int xPhys = LOG2PHYS_X(x, y); int yPhys = LOG2PHYS_Y(x, y); #else #define xPhys x #define yPhys y #endif /* Write into hardware ... Adapt to your system */ { LCD_DrawPoint_color(x,y,PixelIndex); //添加畫點函數 }}
?添加讀點函數
該函數在LCDDummy.c文件(大約407行)處。
unsigned int LCD_L0_GetPixelIndex(int x, int y) { LCD_PIXELINDEX PixelIndex; /* Convert logical into physical coordinates (Dep. on LCDConf.h) */ #if LCD_SWAP_XY | LCD_MIRROR_X| LCD_MIRROR_Y int xPhys = LOG2PHYS_X(x, y); int yPhys = LOG2PHYS_Y(x, y); #else #define xPhys x #define yPhys y #endif /* Read from hardware ... Adapt to your system */ { PixelIndex=LCD_ReadPoint(x,y); //添加讀點函數 } return PixelIndex;}
?
文件修改完畢之后,回到主函數,添加#include "GUI.h"頭文件。
并在主函數里加入下面的代碼,測試GUI移植是否成功。
GUI_Init(); //GUI初始化GUI_SetBkColor(GUI_BLUE); //設置顏色GUI_Clear(); //清屏GUI_GotoXY(60,50); //設置字符顯示的XY坐標GUI_DispString("Hello World!!"); //顯示字符GUI_DrawCircle(100,200,50); //畫圓
?代碼寫完,編譯工程,編譯時間1-10分鐘左右(電腦性能決定)。
??效果圖:
編譯成功之后,將代碼下載到開發板運行。
效果如圖:
如果編譯出現下面的錯誤:
../OBJ/KEY.axf: Error: L6218E: Undefined symbol exit (referred from jerror.o).
根據錯誤提示,打開jerror.c文件,找到error_exit函數,將該函數的最后一行代碼exit(EXIT_FAILURE); 該為return 。改完,再次編譯,錯誤解決。
效果圖:
方法:
一般解決了上述的問題,移植一般都沒有問題。出現了問題,可以查看錯誤信息,判斷是什么錯誤,針對性解決。
? ? 加入觸摸屏功能之前,要保證原本工程已經有正常的觸摸屏驅動代碼,能正確的轉換觸摸屏的X Y坐標值。
#define GUI_SUPPORT_TOUCH (1) /* 支持觸摸屏 */#define GUI_ALLOC_SIZE 5000 //修改內存空間改大一點,防止編譯不過
效果圖:
?
#ifndef GUITOUCH_CONF_H#define GUITOUCH_CONF_H#define GUI_TOUCH_AD_LEFT 0 //屏幕左邊尺寸#define GUI_TOUCH_AD_RIGHT 240 //屏幕右邊尺寸#define GUI_TOUCH_AD_TOP 0 //屏幕頂端尺寸#define GUI_TOUCH_AD_BOTTOM 320 //屏幕底部尺寸#define GUI_TOUCH_SWAP_XY 0 //是否交換坐標#define GUI_TOUCH_MIRROR_X 0 //設置鏡像X#define GUI_TOUCH_MIRROR_Y 0 //設置鏡像Y#endif /* GUITOUCH_CONF_H */
?效果圖:
GUI_X_Touch.c在UCGUI/GUI_X路徑下。
并修改獲取X Y 坐標代碼,加入觸摸屏驅動頭文件。
修改代碼如下:
#include "GUI.h"#include "GUI_X.h"#include "touch.h" //頭文件void GUI_TOUCH_X_ActivateX(void) {}void GUI_TOUCH_X_ActivateY(void) {}int GUI_TOUCH_X_MeasureX(void) { //添加獲取觸摸X坐標代碼 Touch_check(); //掃描觸摸屏 return TOUCH.x; //X坐標}int GUI_TOUCH_X_MeasureY(void) {//添加獲取觸摸Y坐標代碼 Touch_check(); //掃描觸摸屏 return TOUCH.y; //Y坐標}
?效果圖:
上邊步驟完成之后,在主函數添加(自己工程的)觸摸屏的初始化函數,觸摸屏即可正常運行。
如果GUI沒有加入系統,需要定義一個定時器去掃描觸摸屏,在定時器的中斷服務函數里加入GUI_TOUCH_Exec();函數。掃描的頻率為:10毫秒一次
如果GUI加入了系統,可以創建一個多帶帶的任務,在任務里添加GUI_TOUCH_Exec();
本小節的的移植是基于UCOSII系統的移植
移植系統之前的準備工作:
打開GUIConf.h文件,修改當前GUI支持系統
#define GUI_OS??????????????????? (1)? /* 系統支持 */?
效果圖:
添加相關頭文件路徑效果圖:
?
效果圖:
?
注意:加載源碼的時候,不能將ucos_ii.c加入到工程。加入了ucos_ii.c文件會出現重定義。
”ucos_ii.c的代碼作用是加載源文件,因為UCOSII其他源文件我們已手動加入到工程,已不需要ucos_ii.c的代碼”。
初始化滴答時鐘,開啟滴答時鐘中斷,設置滴答時鐘10毫秒中斷一次。
(用任何一個硬件定時器都可以代替)
在滴答時鐘中斷服務函數里加入下面的代碼:
(記得在滴答定時器中斷函數的代碼文件里引用UCOSII的頭文件:#include "includes.h" )
?
/*滴答時鐘中斷服務函數*/void SysTick_Handler(void){ OSIntEnter(); //進入中斷 OSTimeTick(); //調用ucos的時鐘服務程序 OSIntExit(); //觸發任務切換軟中斷}
?效果圖:
在進行上邊的步驟,之后,編譯工程,會出現如下的錯誤:
Build target "UCGUI移植"linking...../OBJ/KEY.axf: Error: L6218E: Undefined symbol GUI_X_GetTaskId (referred from guitask.o).../OBJ/KEY.axf: Error: L6218E: Undefined symbol GUI_X_InitOS (referred from guitask.o).../OBJ/KEY.axf: Error: L6218E: Undefined symbol GUI_X_Lock (referred from guitask.o).../OBJ/KEY.axf: Error: L6218E: Undefined symbol GUI_X_Unlock (referred from guitask.o).Not enough information to list image symbols.Finished: 1 information, 0 warning and 4 error messages."../OBJ/KEY.axf" - 4 Error(s), 0 Warning(s).Target not created
?根據報錯提示信息,打開GUITask.c 文件。GUITask.c有提示需要在GUI_X.c文件實現幾個函數。
根據提示,繼續打開GUI_X.C 。前邊有提到,GUI_X.C文件主要是提供OS系統接口,配置/系統相關的外部環境。
效果圖:
?我們當前移植的OS是UCOSII系統,打開KEIL工程路徑下的GUI_X文件夾:
效果圖:
?該目錄下有6個與系統接口相關的文件,我們移植的是UCOS系統,其中GUI_X_uCOS.c文件是UCOSII系統的接口。我們將GUI_X_uCOS.c文件加入到工程
效果圖:
?將GUI_X.C文件的三個底層函數拷貝一份到GUI_X_uCOS.c文件
void GUI_X_Log (const char *s) { GUI_USE_PARA(s); }void GUI_X_Warn (const char *s) { GUI_USE_PARA(s); }void GUI_X_ErrorOut (const char *s) { GUI_USE_PARA(s); }
?效果圖:
完成上面的步驟之后,將GUI_X.c文件從工程中卸載掉,因為GUI_X_uCOS.c與GUI_X.c文件實現的函數有很多是相同的,不卸載GUI_X.c會出現重定義的錯誤。
接著修改GUI_X_uCOS.c文件,替換UCOS的延時函數。(大約在78行)。
?
void GUI_X_ExecIdle (void) { //OS_X_Delay(1); OSTimeDly(50); //UCOS延時函數}
?效果圖:
?
//開始任務void start_task(void *pdata){ OS_CPU_SR cpu_sr=0; pdata = pdata; OS_ENTER_CRITICAL(); //進入臨界區(無法被中斷打斷) OSTaskCreate(led0_task,(void *)0,(OS_STK*)&LED0_TASK_STK[LED0_STK_SIZE-1],LED0_TASK_PRIO); //創建的任務 OSTaskCreate(led1_task,(void *)0,(OS_STK*)&LED1_TASK_STK[LED1_STK_SIZE-1],LED1_TASK_PRIO); OSTaskSuspend(START_TASK_PRIO); //掛起起始任務. OS_EXIT_CRITICAL(); //退出臨界區(可以被中斷打斷)}//LED0任務void led0_task(void *pdata){ u8 i; u16 cnt=0; /*************************************** 畫一個進度條控件 ****************************************/ hProgBar_1 = PROGBAR_Create(0, 0, 240, 40, WM_CF_SHOW); //設置進度條的大小坐標參數 PROGBAR_SetBarColor(hProgBar_1,0,GUI_GREEN); //參數(句柄,1(0)代表本函數是顯示進度條覆蓋的區域還未覆蓋的區域,進度條覆蓋的顏色) PROGBAR_SetBarColor(hProgBar_1,1,GUI_RED); //參數(句柄,1(0)代表本函數是顯示進度條覆蓋的區域還未覆蓋的區域,進度條未覆蓋的顏色) PROGBAR_SetValue(hProgBar_1,99); //參數(句柄 ,99是進度條顯示的99%) while(1) { i=!i; LED2(i); LED3(i); PROGBAR_SetValue(hProgBar_1,cnt); //顯示進度條1控件 的進度 OSTimeDlyHMSM(0,0,1,0); //將一個任務延時若干時間(設定時、 分、 秒、 毫秒) WM_Exec(); cnt++; if(cnt>=100) { cnt=0; } }}//LED1任務void led1_task(void *pdata){ u8 i; u16 cnt; hProgBar_2 = PROGBAR_Create(0, 80, 240, 40, WM_CF_SHOW); //設置進度條的大小坐標參數 PROGBAR_SetBarColor(hProgBar_2,0,GUI_GREEN); //參數(句柄,1(0)代表本函數是顯示進度條覆蓋的區域還未覆蓋的區域,進度條覆蓋的顏色) PROGBAR_SetBarColor(hProgBar_2,1,GUI_RED); //參數(句柄,1(0)代表本函數是顯示進度條覆蓋的區域還未覆蓋的區域,進度條未覆蓋的顏色) while(1) { //GUIDEMO_main(); //運行DEMO代碼 i=!i; LED1(i); LED4(i); PROGBAR_SetValue(hProgBar_2,cnt); //顯示進度條2控件 的進度 WM_Exec(); //顯示生效 OSTimeDlyHMSM(0,0,0,500); //將一個任務延時若干時間(設定時、 分、 秒、 毫秒) cnt++; if(cnt>=100) { cnt=0; } }}
?效果圖:
?將DEMO文件全部加入工程編譯,最后運行DEMO代碼。
//LED0任務void led0_task(void *pdata){ u8 i; while(1) { i=!i; LED2(i); LED3(i); GUI_TOUCH_Exec(); //監視和刷新觸摸板 OSTimeDlyHMSM(0,0,0,10); //將一個任務延時若干時間(設定時、 分、 秒、 毫秒) }}//LED1任務void led1_task(void *pdata){ u8 i; while(1) { GUIDEMO_main(); //運行DEMO代碼 i=!i; LED1(i); LED4(i); OSTimeDlyHMSM(0,0,0,10); //將一個任務延時若干時間(設定時、 分、 秒、 毫秒) }}
?系統時間計算
如果跑UCOS系統可以設置UCOS工作頻率高一些:? #define OS_TICKS_PER_SEC? 1000?? //一秒的節拍時間。
節拍時間計算方式:滴答時鐘中斷時間 * 節拍次數 =? 1秒
函數原型 | GUI_Init();????????????????????? |
函數功能 | 初始化GUI的內部數據結構和變量,使用GUI任何功能之前必須調用本函數 |
函數參數 | |
返回值 |
函數原型 | GUI_GotoXY(int x, int y)???????????????? |
函數功能 | 設置當前的XY坐標 |
函數參數 | X :橫坐標?? Y:縱坐標 |
返回值 | 成功返回0 |
相關函數 | GUI_GotoX() 設置當前X坐標 GUI_GotoY() 設置當前Y坐標 |
函數原型 | void GUI_SetBkColor(GUI_COLOR color) ??????????? |
函數功能 | 設置LCD背景顏色 |
函數參數 | Color:顏色值 |
返回值 | 無 |
函數原型 | void GUI_SetColor(GUI_COLOR color)???????? |
函數功能 | 設置LCD前景顏色 |
函數參數 | Color:顏色值 |
返回值 | 無 |
所屬文件 | GUI_SetColor.c |
函數原型 | void GUI_DispString(const char GUI_UNI_PTR *s)?????? |
函數功能 | 在當前坐標顯示文本-字符串 |
函數參數 | *s :字符串指針 |
返回值 | 無 |
所屬文件 | GUI_DispString.C |
示例:
GUI_DispString("Hello World!!");?? //顯示字符串 |
函數原型 | void GUI_DispStringAt(const char GUI_UNI_PTR *s, int x, int y)???? |
函數功能 | 在指定坐標顯示文本-字符串 |
函數參數 | *s :字符串指針 X:橫坐標 Y:縱坐標 |
返回值 | 無 |
所屬文件 | GUI_DispStringAt.c |
示例:
GUI_DispStringAt("Hello World!!",0,100);? //顯示字符串 |
函 數 | 說 明 |
GUI_DispChar() | 在當前坐標顯示單個字符 |
GUI_DispCharAt() | 在指定坐標顯示單個字符 |
GUI_DispChars() | 按指定重復次數顯示一個字符 |
GUI_DispChars() | 在當前坐標顯示字符串 |
GUI_DispStringAt() | ??????? 在指定坐標顯示字符串 |
GUI_DispStringAtCEOL() | 在指定坐標顯示字符串,并清除到行末 |
GUI_DispStringInRect() | 在指定矩形區域內顯示字符串 |
GUI_DispStringLen() | 在當前坐標顯示指定字符數量的字符串 |
函數 | 功能 |
GUI_SetTextMode(); | 設置文本繪圖模式 |
函數 | 功能 |
GUI_GetTextAlign() | 返回當前文本對齊模式 |
GUI_SetLBorder() | 設置換行后的左邊界 |
GUI_ SetTextAlign() | 設置文本對齊模式 |
函數 | 功能 |
GUI_GotoX() | 設置當前X坐標 |
GUI_GotoXY() | 設置當前YX坐標 |
GUI_GotoY() | 設置當前Y坐標 |
函數 | 功能 |
GUI_GetDispPosX() | 返回當前X坐標 |
GUI_GetDispPosY() | 返回當前Y坐標 |
函數 | 功能 |
GUI_Clear() | 清除活動視窗(如果背景是活動視窗,則是清除整個屏幕) |
GUI_DispCEOL() | 清除從當前坐標到行末的顯示內容 |
默認情形下,存儲設備是被激活的。為了優化軟件的性能,對存儲設備的支持可以在配
置文件 GUIConf.h 中加入下面一行而關閉:
#define GUI_SUPPORT_MEMDEV? 0
要是使用時,需要將宏開關打開:
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/120933.html
摘要:基于開發的軟件包導師汪禮超學員崔林威摘要騰訊物聯網操作系統是騰訊面向物聯網領域開發的實時操作系統,具有低功耗,低資源占用,模塊化,可裁剪等特性。圖中斷函數處理進行生成工程配置,按如下界面進行配置,最后點擊,并點擊。 ...
摘要:力矩控制模式電機在運行過程的電流,始終等于給定的值。設定電流為零,彈簧不被拉伸。比如機械臂從點運動到點,并限制揮舞過程中的最大速度和最大力矩。 目錄 說明一、電機...
摘要:添加設備名和鑒權信息。記錄如下數據二引腳連接和接電源接地和連接至配置的串口三代碼編寫串口配置單片機需配置兩個串口,串口打印至串口助手,顯示連接狀態。串口用來發送信息至串口配置代碼如下系列配置和系列配置不同點在于口上拉和推挽配置略有不同。 ...
摘要:已初始化的讀寫數據,程序中定義并且初始化的全局變量和靜態變量位于此處。好了,初步移植要點講完了,下一篇文章講內核配置文件函數啟動后如何進入鴻蒙輕量內核。 9月30日,OpenHarmony 3.0 LTS版本發布,新版介紹見OpenHarmony 3.0 發布:OpenHarmony 3.0...
摘要:大信刷抖音時,偶然蹦出了聯盛德物聯開發板這個廣告。板子做的很精致,毫米厚的板子,平滑的板邊緣,亮紫色和鍍金的過孔透露著高檔品質,同時收到售后支持的加好友,在售后支持指導下加入了聯盛德官方的開發群里,開始了開發測試工作。 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ...
閱讀 2327·2021-11-22 14:56
閱讀 1460·2021-09-24 09:47
閱讀 904·2019-08-26 18:37
閱讀 2817·2019-08-26 12:10
閱讀 1521·2019-08-26 11:55
閱讀 3139·2019-08-23 18:07
閱讀 2293·2019-08-23 14:08
閱讀 604·2019-08-23 12:12