1. gzyueqian
      13352868059
      首頁 > 新聞中心 > > 正文

      uC/GUI NIOS II移植及應用筆記 下

      更新時間: 2008-03-19 16:53:00來源: 粵嵌教育瀏覽量:1397

      uC/GUI NIOS II移植之Text顯示

      今天研究了uC/GUI的文字顯示系統。
      這個系統的功能相當強大,提供了一下幾個函數。
      GUI_DispChar() 顯示一個字符
      GUI_DispCharAt() 在某個位置顯示一個字符
      GUI_DispChars() 顯示n個設定的字符
      GUI_DispString() 顯示一個字符串
      GUI_DispStringAt() 在某個位置顯示一個字符串

      還有好大一堆函數,不過這幾個是基本的。
      先看一段有關這些代碼的事例程序:
      void MainTask(void) {
      unsigned int i;
      GUI_Init();
      初始化,設置的默認字體是6*8的一種字體,具體叫什么忘了
      GUI_SetColor(GUI_YELLOW); 設置顯示顏色為YELLOW,這里指的是字符的顏色
      GUI_DispChars('*', 108); 從當前坐標起顯示108個*,就是截圖里面的上面的那排*
      for(i = 0; i < 480; i+=8) {
      GUI_DispCharAt('*', 1, i);
      } 在列顯示一列*
      GUI_DispChars('*', 108); 在下面一行顯示一排*
      for(i = 0; i <= 480; i+=8) {
      GUI_DispCharAt('*', 634, i);
      } 在右邊的一列顯示一列*


      GUI_SetColor(GUI_GREEN); 設置顯示的顏色為GREEN
      GUI_SetFont(&GUI_Font8x10_ASCII); 設置字體為GUI_Font8*10_ASCII
      GUI_DispCharAt('A', 100, 100); 在坐標100,100處顯示一個A
      GUI_DispString("! Hello World! "); 顯示Hello World!大家注意這是緊跟著A顯示出來的,即它是在當前光標處顯示字符的
      GUI_SetFont(&GUI_Font32_ASCII); 設置字體
      GUI_SetColor(GUI_YELLOW); 設置顯示顏色為YELLOW,下面代碼顯示的字符都是黃色的
      GUI_DispChars('*', 15); 顯示15個*
      GUI_SetBkColor(GUI_BLUE); 設置背景顏色為BLUE,大家注意這個背景顏色,是襯在字下面的,而不是整個的背景
      GUI_DispCharAt('B', 600, 400);
      GUI_SetFont(&GUI_Font32B_ASCII);
      GUI_SetColor(GUI_RED);
      GUI_DispStringAt("Hello World!", 1, 200);
      在1,100這個地方顯示字符串,注意覆蓋掉了原先顯示出來的*
      GUI_Delay(1000);
      }
      效果圖

      這樣基本的字符顯示函數就完了。大家都會使用了。
      在前提到這個GUI支持UNICODE。
      既然支持UNICODE那就應該能顯示中文才對啊!
      當然能顯示中文,但關鍵問題是字體!
      這里就講一講有關字體的提取。
      首先要用到一個字體轉換工具,因為我們得到的uC/GUI代碼基本上都是D版的,里面所附的字體轉換工具都是DOME版,根本轉換不出來正常的字體.c文件。在這里要用到另外一個程序。
      聲明:該程序轉載自www.ucgui.com,所有權歸原作者ucgui所有,這里只是轉載。僅上船該程序的可執行文件
      http://www.ednchina.com/Upload/Blog/cecb4a69-b388-4a9f-916d-2b216f8edcc9.rar
      聲明:在這里特便感謝原作者做出的貢獻!
      首先運行程序,看到如圖的程序界面,相當的簡單。

      然后點擊選擇字體。按扭出現新的對話框,我選擇的字體如圖所示。

      確定后回到主界面,點擊
      看到這個對話框文件就轉換好了!

      直接加載進模擬器工程就可以享受中文字體帶來喜悅了!
      在這里上傳兩個轉換好的字體宋體(5號字)和Times new roman(5號字)兩個字體,供大家參考,其中Times字體去掉了除ascii碼之外所有的其他字模。
      http://www.ednchina.com/Upload/Blog/622a4994-39aa-4380-a8cc-4cef5e57b7df.rar
      說一下這里的5號字對應的就是16*16的漢字字體。

      宋體那個文件體積巨大3Mb多,如果是大字體的話就有十幾MB了!
      我們現在運行下面的程序,體驗一下中文的喜悅!
      #include "GUI.h"
      extern GUI_FLASH const GUI_FONT GUI_FontHZ_FangSong_GB2312_14;
      extern GUI_FLASH const GUI_FONT GUI_FontHZ_Times_New_Roman_14;
      extern GUI_FLASH const GUI_FONT GUI_Font8x10_ASCII;
      extern GUI_FLASH const GUI_FONT GUI_Font32_ASCII;
      extern GUI_FLASH const GUI_FONT GUI_Font32B_ASCII; /*這幾行一定要有,聲明從外部引用這個數據結構,建議大家將所有的字體的定義弄成一個頭文件,這樣子比較方便!*/
      void MainTask(void) {
      unsigned int i;
      GUI_Init();
      GUI_SetColor(GUI_YELLOW);
      GUI_DispChars('*', 108);
      for(i = 0; i < 480; i+=8) {
      GUI_DispCharAt('*', 1, i);
      }
      GUI_DispChars('*', 108);
      for(i = 0; i <= 480; i+=8) {
      GUI_DispCharAt('*', 634, i);
      }
      GUI_SetColor(GUI_GREEN);
      GUI_SetFont(&GUI_FontHZ_Times_New_Roman_14);
      GUI_DispCharAt('A', 100, 100);
      GUI_DispString("! Hello World! "); /*仔細看這里的字體已經是Times new roman了和上面的是不一樣的*/
      GUI_SetFont(&GUI_Font32_ASCII);
      GUI_SetColor(GUI_YELLOW);
      GUI_DispChars('*', 15);
      GUI_SetBkColor(GUI_BLUE);
      GUI_DispCharAt('B', 600, 400);
      GUI_SetFont(&GUI_FontHZ_FangSong_GB2312_14);
      GUI_SetColor(GUI_RED);
      GUI_DispStringAt("大家好這里是中文顯示演示程序!", 1, 200); /*將上面程序中的Hello World替換成了中文!*/
      GUI_Delay(10000);
      }

      還有一個郁悶的問題,文件太大了有的編譯器有限制!例如VC.NET的編譯器。好在NIOS II編譯器沒有這個限制。 看看圖:

      實際測試不影響使用,我們測試了4000多個漢字沒有發現什么問題。
      uC/GUI NIOS II移植之2D圖形庫

      今天繼續昨天的話題。
      來看2D圖形庫。這里面uC/GUI提供了強大的功能。先看看有什么函數。

      里面有不少東西,這是截的圖懶的一個一個把他們敲上來了。

      先看個函數,GUI_SetDrawMode();設置GUI的繪圖模式。靠上去好像很高深。這個函數就有一個參數mode。
      mode又兩個選項GUI_DRAWMODE_NORMAL和GUI_DRAWMODE_XOR。
      先看一個例子大家就明白這個MODE是什么意思了。
      void MainTask(void) {
      unsigned int i;
      GUI_Init();
      GUI_SetFont(&GUI_FontHZ_Times_New_Roman_14);
      GUI_SetDrawMode(GUI_DRAWMODE_NORMAL);設置為GUI_DRAWMODE_NORMAL
      GUI_SetBkColor(GUI_YELLOW);
      GUI_Clear(); //這句話比較有意思,執行了之后他會將整個窗口填充為Bk設置的顏色,要不只有在在繪制的圖形的下面才有Bk色。
      GUI_SetColor(GUI_RED);
      GUI_FillCircle(300, 200, 130); //畫個園,紅色的,顯眼一點。
      GUI_SetColor(GUI_GREEN); //設置繪圖顏色為GREEN
      GUI_FillCircle(140, 200, 130); //以NORMAL方式畫第二個圓
      GUI_SetDrawMode(GUI_DRAWMODE_XOR); //設置繪圖方式為XOR
      GUI_FillCircle(460, 200, 130); //以XOR方式繪制第三個圓,這里大家仔細看看同樣繪制了一GREEN顏色的圓,為什么不是GREEN的?XOR惹的禍。這個函數在黑白顯示里面尤為重要!
      GUI_SetColor(GUI_BLUE);
      GUI_DispStringAt("First Circle", 300, 340);
      GUI_DispStringAt("Seconde Circle", 140, 340);
      GUI_DispStringAt("Third Circle", 460, 340); //這些是為了觀察方便添上去的
      GUI_SetColor(GUI_BLACK);
      GUI_SetDrawMode(GUI_DRAWMODE_NORMAL);
      GUI_FillCircle(300, 200, 3);
      GUI_FillCircle(140, 200, 3);
      GUI_FillCircle(460, 200, 3);
      GUI_DrawCircle(300, 200, 131); //畫圓,但是畫出來的只有輪廓,上面調用的函數GUI_FillCircle()是將這員填充顏色的。uC/GUI里面所有的在封閉圖形比如說圓和長方形的繪圖函數Fill和Draw都有類似的關系
      GUI_Delay(5000);
      }
      效果圖

      接下來就應該顯示位圖了及BMP文件。但是大多數的嵌入式系統不支持文件系統那該怎么辦?
      uC/GUI提供了一個解決方案,把位圖轉化為.C文件。
      這個工具就叫uC-GUI-BitmapConvert.exe
      執行這個工具,打開一個我事先準備好的位圖文件。
      然后如圖選擇轉換該文件。

      其實在這里選擇把位圖轉換成多少色的都沒有關系,gui會自動適佩目標系統的顏色。
      之所以這么選擇是為了節省存儲空間,畢竟嵌入式系統容量有限。
      轉換好了以后立即就能看到效果。

      在界面的上方顯示的是這個位圖的大小這里可看到是419*490。
      下面顯示的就是調色板,即這個位圖所有能顯示出來的顏色。
      線面就是預覽了。難看的不行了。
      然后選擇另存為,就出現了.c文件這個選項。

      這是轉換好的位圖.c文件和位圖原文件。
      http://www.ednchina.com/Upload/Blog/abb12d5c-6ee8-4898-b9e0-1a7fc1c424c8.rar
      uC/GUI還支持位圖文件的壓縮。在保存的時候選擇就可以了。

      比較一下文件可以看到兩個文件的大小相差了一倍。
      為壓縮的600多k,壓縮的才300。按照他文檔的說明,可以提供2的壓縮率。
      來看看他們都有什么不同。
      這是為壓縮的:
      #include "stdlib.h"
      #include "GUI.H"

      /* Palette
      The following are the entries of the palette table.
      Every entry is a 32-bit value (of which 24 bits are actually used)
      the lower 8 bits represent the Red component,
      the middle 8 bits represent the Green component,
      the highest 8 bits (of the 24 bits used) represent the Blue component
      as follows: 0xBBGGRR
      */

      const GUI_COLOR Colors3[] = {
      0x000000,0x0000FF,0x00FF00,0x00FFFF
      ,0xFF0000,0xFF00FF,0xFFFF00,0xFFFFFF
      }; /*這個位圖的調色板可以看出來里面有8種顏色*/

      const GUI_LOGPALETTE Pal3 = {
      8, /* number of entries */
      0, /* No transparency */
      &Colors3[0]
      };

      const unsigned char ac3[] = {
      0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
      /*這里面存放的就是bitmap的數據太多了就被我精簡了,只顯示一行。有興趣的去下載附件看看。*/
      };

      const GUI_BITMAP bm3 = {
      419, /* XSize */
      490, /* YSize */
      210, /* BytesPerLine */
      4, /* BitsPerPixel */
      ac3, /* Pointer to picture data (indices) */
      &Pal3 /* Pointer to palette */
      };

      下面是壓縮的:
      #include "stdlib.h"
      #include "GUI.H"

      /* Palette
      The following are the entries of the palette table.
      Every entry is a 32-bit value (of which 24 bits are actually used)
      the lower 8 bits represent the Red component,
      the middle 8 bits represent the Green component,
      the highest 8 bits (of the 24 bits used) represent the Blue component
      as follows: 0xBBGGRR
      */
      const GUI_COLOR Colors3_compressed_with_palette[] = {
      0x000000,0x0000FF,0x00FF00,0x00FFFF
      ,0xFF0000,0xFF00FF,0xFFFF00,0xFFFFFF
      };

      const GUI_LOGPALETTE Pal3_compressed_with_palette = {
      8, /* number of entries */
      0, /* No transparency */
      &Colors3_compressed_with_palette[0]
      };

      const unsigned char ac3_compressed_with_palette[] = {
      /* RLE: 418 Pixels @ 000,000*/ 254, 0x07, 164, 0x07,
      /* RLE: 001 Pixels @ 418,000*/ 1, 0x00,
      /* RLE: 418 Pixels @ 000,001*/ 254, 0x07, 164, 0x07,
      /*同上砍掉了很多東西,有興趣的看附件*/};
      const GUI_BITMAP bm3_compressed_with_palette = {
      419, /* XSize */
      490, /* YSize */
      210, /* BytesPerLine */
      GUI_COMPRESS_RLE4, /* BitsPerPixel */
      ac3_compressed_with_palette, /* Pointer to picture data (indices) */
      &Pal3_compressed_with_palette /* Pointer to palette */
      ,GUI_DRAW_RLE4
      };
      看看有什么區別,根據我的理解,壓縮就是把有信息的象素點標出來。黑色的就不標記。

      不過在顯示效果上沒有任何區別!但是顯示壓縮的位圖明顯能感覺到速度較慢。
      這是測試用的代碼:
      extern const GUI_BITMAP bm3;
      extern const GUI_LOGPALETTE Pal3;
      extern const unsigned char ac3[];
      extern const GUI_BITMAP bm3_compressed_with_palette;
      //這是一些要用到的外部變量聲明

      GUI_SetDrawMode(GUI_DRAWMODE_NORMAL);
      GUI_SetBkColor(GUI_BLACK);
      GUI_SetColor(GUI_WHITE);
      GUI_Clear(); /*清理桌面,變成黑的*/

      GUI_DrawBitmap(&bm3, 10,10); /*在左上角為起始點的10,10座標為圓點顯示位圖*/
      GUI_Delay(5000);
      GUI_Clear();
      GUI_Delay(1000);
      GUI_DrawBitmap(&bm3_compressed_with_palette, 50, 10); /*在左上角為起始點的50,10座標為圓點顯示位圖,效果上沒有區別,但是速度明顯的慢*/
      GUI_Delay(5000);
      直接添加到上段代碼的后面就行了。

      超出顯示范圍的內容就被自動砍掉了。這是個顯示的截圖,第二個由于效果上沒卻別,就不浪費論壇空間了。

      再來看看GUI_DrawBitmapExp();這個函數,這個函數有多達十個參數。
      void GUI_DrawBitmapExp(int x0, int y0, //顯示位圖的起始座標(指的是在LCD上的位置)
      int XSize, int YSize, //這個兩參數的含義是在待顯示的位圖中選取一個XSize*YSize大小的范圍來顯示,從0,0座標開始。取值范圍1~~255
      int XMul, int YMul, //比例因數,即放大比率!議會就能看到這個參數的效果
      int BitsPerPixel, &n bsp; //位圖的每個象素的位數,可以在bm3這個結構體中找到
      int BytesPerLine, //待顯示位圖每行的字節數,可以在bm3這個結構體中找到
      const U8* pData, //指向位圖,實際存儲數據變量的指針。
      const GUI_LOGPALETTE* pPal); //指向GUI_LOGPALETTE數據結構的指針 GUI_Clear();
      GUI_Delay(1000);
      GUI_DrawBitmapExp(10, 10, 255, 255, 1, 1, bm3.BitsPerPixel, bm3.BytesPerLine, &ac3, &Pal3); //看看這段代碼的含義,特別注意pData的取值是指向ac3的指針
      這句的效果

      GUI_Delay(5000);
      GUI_DrawBitmapExp(10, 10, 255, 255, 2, 2, bm3.BitsPerPixel, bm3.BytesPerLine, &ac3, &Pal3);
      這句的效果,圖片被放大了!

      GUI_Delay(5000);

      GUI_Clear();
      GUI_DrawBitmapMag(&bm3 ,10, 10, 2, 2);
      GUI_Delay(5000);
      也是放大顯示一個圖像!效果和上面的是一樣的。
      沒有什么區別。

      下來在演示一個polygons的例子。
      static const GUI_POINT _aPointArrow[] = {
      { 0, 0},
      {-40, -30},
      {-10, -20},
      {-10, -70},
      { 10, -70},
      { 10, -20},
      { 40, -30},
      }; //定義一個多變性所有的頂點
      GUI_Clear();
      GUI_SetColor(GUI_BLUE);
      GUI_FillPolygon (&_aPointArrow[0], 7, 260, 180); //填充顏色
      GUI_DrawPolygon(&_aPointStar, 7, 460, 200); 僅有邊框
      //7表著個要Fill的多變性有幾個頂點
      GUI_Delay(5000);

      效果如圖:

      今天用到的main函數。
      http://www.ednchina.com/Upload/Blog/87886f3f-b745-492d-a944-4df06746c217.rar
      今天就到此為止!明天繼續!有興趣的朋友還請關注。
      uC/GUI NIOS II移植之Window Manager(窗口管理器)

      昨天太晚了沒有時間更新了。今天繼續。
      今天來看看Window manager,窗口管理器。
      先來看一個小例子。

      #define MSG_CHANGE_TEXT WM_USER+0

      #ifndef NULL
      #define NULL 0
      #endif

      typedef struct {
      int x;
      int y;
      int xHere, yHere;
      const GUI_BITMAP* pBitmap;
      } tDrawContext;

      extern GUI_FLASH const GUI_FONT GUI_FontHZ_FangSong_GB2312_14;
      extern GUI_FLASH const GUI_FONT GUI_FontHZ_Times_New_Roman_14;
      extern GUI_FLASH const GUI_FONT GUI_Font8x10_ASCII;
      extern GUI_FLASH const GUI_FONT GUI_Font32_ASCII;
      extern GUI_FLASH const GUI_FONT GUI_Font32B_ASCII;
      extern const GUI_BITMAP bm3;
      extern const GUI_LOGPALETTE Pal3;
      extern const unsigned char ac3[];
      extern const GUI_BITMAP bm3_compressed_with_palette;
      extern const GUI_BITMAP bmmap; /*以上全部是外部變量聲明,有位圖,有字體*/

      static WM_CALLBACK* _cbBkWindowOld; /*聲明背景窗口的回調函數(Call back function),后面會具體說明這個Call back是干什么的*/
      static char _acInfoText[40]; /*要在背景窗口中顯示的文字*/

      static WM_HWIN _hWindow2; /*窗口2*/

      static void _cbWindow2(WM_MESSAGE* pMsg) { /*窗口2的call back*/
      int x, y;
      switch (pMsg->MsgId) { /*pMsg這個參數用來告訴這個回調函數發生了什么事件的!這里列出了系統已經定義好的所有的事件*/
      case WM_CREATE:
      /*to do add code here*/
      break;

      case WM_DELETE:
      /*to do add code here*/
      break;

      case WM_HIDE:
      /*to do add code here*/
      break;

      case WM_MOVE:
      /*to do add code here*/
      break;

      case WM_NOTIFY_PARENT:
      /*to do add code here*/
      break;

      case WM_PAINT: /*這個Paint事件,準確地翻譯我不知道,但他的功能主要就是自動重繪窗口,這十分重要,有了自動重繪你只要在這個CB里面告訴GUI你想繪什么東西就行了,GUI會自動在適當的時機重繪*/
      GUI_SetBkColor(GUI_RED);
      GUI_Clear();
      GUI_SetColor(GUI_WHITE);
      GUI_SetFont(&GUI_Font24_ASCII);
      x = WM_GetWindowSizeX(pMsg->hWin);
      y = WM_GetWindowSizeY(pMsg->hWin);
      GUI_DispStringHCenterAt("Test Window No.2", x / 2, 1); /*在這里面你可以調用上面貼子中所有出現過的內容,但不是在整個屏幕上繪圖了,而是在這個窗口中繪圖*/
      break;

      case WM_SHOW:
      /*to do add code here*/
      break;

      case WM_SIZE:
      /*to do add code here*/
      break;

      case WM_TOUCH:
      /*to do add code here*/
      break;

      default:
      WM_DefaultProc(pMsg); /*在回調函數中還有很多其他系統定義的事件,例如WM_SIZE你可以在發生了該事件后改變窗口的內容。有了這個回調函數就可以實現很多的功能*/
      }
      }

      static void _ChangeInfoText(char* pStr) { /*將要在背景窗口中顯示的文字放到一個全局變量里面去,再由Bk窗口的回調函數自動刷新*/
      WM_MESSAGE Message;
      Message.MsgId = MSG_CHANGE_TEXT;
      Message.Data.p = pStr;
      WM_SendMessage(WM_HBKWIN, &Message); /*發送一個消息告訴Bk的cb發生了文字改變的事件*/
      WM_InvalidateWindow(WM_HBKWIN);
      }

      static void _cbBkWindow(WM_MESSAGE* pMsg) { /*Bk窗口的CB函數,在這里可以更清楚地看到cb是怎么工作的*/
      switch (pMsg->MsgId) {
      case MSG_CHANGE_TEXT: /*發生了MSG change設個事件,將待顯示的文本拷貝的變量中去*/
      strcpy(_acInfoText, pMsg->Data.p); /*這里有點小小的編程技巧,在這里沒有使用break,而是直接執行下面的case里面的內容這樣就直接刷新的Bk窗口*/
      case WM_PAINT:
      GUI_SetBkColor(GUI_CYAN);
      GUI_Clear();
      GUI_SetColor(GUI_RED);
      GUI_SetFont(&GUI_Font24_ASCII);
      GUI_DispStringHCenterAt("WindowManager - Sample", 160, 5);
      GUI_SetFont(&GUI_FontHZ_FangSong_GB2312_14);
      GUI_DispStringAt(_acInfoText, 5, 40); /*在這里就可以看到桌面是怎么來的了,這里的圖片和lcd的大小不一樣,如果一樣就是桌面了*/
      GUI_DrawBitmap(&bm3, 50, 60);
      break; /*這里就看到了Bk窗口里面發生的一切*/
      default:
      WM_DefaultProc(pMsg);
      }
      }
      /*
      *******************************************************************
      *
      * main()
      *
      *******************************************************************
      */

      void MainTask(void) {
      unsigned int i;
      WM_HWIN hClient;
      GUI_Init();

      _cbBkWindowOld = WM_SetCallback(WM_HBKWIN, _cbBkWindow);
      GUI_Delay(1000);
      _ChangeInfoText("uC/GUI演示程序!");

      _hWindow2 = WM_CreateWindow(330, 130, 300, 300, WM_CF_SHOW | WM_CF_FGND, _cbWindow2, 0);
      GUI_Delay(2000);
      }

      這段代碼就比較復雜了,可以看出來想把GUI用好不是一件容易的事情!

      那如果不使用call back機制呢。一樣可以實現相同的功能。但是屏幕的刷新可就是你的責任了。
      用戶就需要調用相關的函數來實現屏幕內容的刷新。
      可能有很多人還不理解這個cb機制。我也說不太清。

      在前幾天的所有例子中都是用戶控制刷屏的。就直在調用GUI_Delay()的時候內容才會改變!
      單步運行就知道了。

      下面看看隊窗口的操作
      WM_ResizeWindow(_hWindow2, -100, -100);
      WM_MoveTo(_hWindow2, 50, 100);
      執行這兩句,窗口就變了樣了。

      當然了你還可以一次讓它移動1個像素,這樣看上去就是平滑移動的!

      窗口管理還有很多的內容,以后慢慢再貼出來。

      這些東西決的原創,歡迎大家提意見,隨意轉載,但請注明出處和作者。



      免費預約試聽課

      亚洲另类欧美综合久久图片区_亚洲中文字幕日产无码2020_欧美日本一区二区三区桃色视频_亚洲AⅤ天堂一区二区三区

      
      

      1. 亚洲国产欧美在线人网站 | 最新手机AV在线不卡 | 日本午夜福利片在线观看 | 欧美国产激情一区二区 | 亚洲中文色另类欧美小说 | 亚洲国产欧美精品一区二区 |