LCD也可以模拟?这款模拟器别错过了!
大家好,我是張巧龍,在嵌入式開發中,有時候有些調試環境、流程比較復雜/繁雜。比如有些bug需要跑很長的一段流程才可以復現,這時候如果按照正常的流程來調試,單單是復現問題估計都需要花不少時間。
這時候應該要多思考需要怎么去模擬一個相同的環境,可以更方便地進行調試,一個好的仿真環境可以大大地提高工作效率。比如數據的模擬、流程的模擬、通信收發的模擬等方面,或是用一些網上現成的模擬器。
本次就來給大家分享一個實用的LCD模擬器:VirtLCD。這個模擬器在我們的工作中有用到,覺得挺實用,分享給大家。
這個模擬器的代碼是開源的,大家感興趣的話可以自己去下載來研究。
地址:
?https://gitee.com/kerndev/VirtualLCD
?下面進行實踐演示
先看一個圖:
使用VirtLCD時,我們同樣需要一個demo(VirtSTM32)工程編寫我們的界面設計代碼,調試好之后可以很快地移到STM32工程上。
我們在使用STM32做LCD顯示時,常常會封裝一些基礎的繪制函數,如畫點、畫線等函數。同樣的,使用VirtSTM32與VirtLCD做調試時,也要封裝類似函數,作者也給我們提供了一些參考,如:
//畫點 void??LCD_DrawPoint(int?x,?int?y,?PIXEL?color) {PIXEL?*mem;mem?=?GET_FRAMEBUFFER(x,?y);*mem?=?color; }//畫水平直線 void??LCD_DrawHLine(int?x1,?int?y1,?int?x2,?PIXEL?color) {PIXEL?*mem;mem?=?GET_FRAMEBUFFER(x1,?y1);for(;?x1?<?x2;?x1++){*mem++?=?color;} }//畫垂直直線 void??LCD_DrawVLine(int?x1,?int?y1,?int?y2,?PIXEL?color) {PIXEL?*mem;mem?=?GET_FRAMEBUFFER(x1,?y1);for(;?y1?<?y2;?y1++){*mem?=?color;mem?-=?LCD_WIDTH;} }下面我們新建一個VirtSTM32工程(VS2019控制臺程序)進行驗證,然后把這些函數加到我們的VirtSTM32工程里。
同時,VirtSTM32需要依賴于VirtLCD.lib,導入即可,這個庫可以在VirtLCD SDK包里找到(文末統一發給大家)。
有了這三個基礎函數,我們可以就可以做很多的事情了,顯示字符串、顯示圖片等函數都是以畫點函數為基礎的,這些函數可以在各種開發板的lcd相關例程里找到,拿過來修改一下就可以。接下來我們顯示一些字符串到Virtlcd上,如:
左右滑動查看全部代碼>>>
int?main(void) {LCD_Init();printf("hello?virtlcd,?i?am?ZhengN");LCD_DrawHLine(10,?10,?350,?WHITE);LCD_ShowString(10,?30,?LCD_WIDTH,?LCD_HEIGHT,?12,?"hello?virtlcd,?i?am?ZhengN");LCD_ShowString(10,?50,?LCD_WIDTH,?LCD_HEIGHT,?16,?"hello?virtlcd,?i?am?ZhengN");LCD_ShowString(10,?70,?LCD_WIDTH,?LCD_HEIGHT,?24,?"hello?virtlcd,?i?am?ZhengN");LCD_DrawHLine(10,?110,?350,?WHITE);while(1);return?0; }運行結果:
這就是模擬STM32裸機顯示字符串到VirtLCD中,調試好之后我們可以很快地移到真正的STM32工程中。
這里只是進行簡單的演示,當然,感興趣的話,還可以移植LVGL、emwin等GUI進去。
附VirtSTM32主要代碼:
#include?"virtlcd.h" #include?"font.h" #include?<stdio.h>#pragma?comment(lib,?"virtlcd.lib")#define?LCD_FILENAME????"virtlcd.exe" #define?LCD_WIDTH???????480 #define?LCD_HEIGHT??????320 #define?LCD_BPP?????????32#define?WHITE???????????0xFFFFFFFF #define?BLACK???????????0x00000000??#define?FRONT_COLOR?WHITE #define?BACK_COLOR?BLACK//定義像素類型 typedef?unsigned?long???PIXEL;//幀緩存指針 static?PIXEL*?m_pFrameBuffer;//計算在X,Y坐標的幀緩存指針 #define?GET_OFFSET(x,?y)????????((?LCD_WIDTH?*?(?LCD_HEIGHT?-?(y)?-?1)?)?+?(x)?) #define?GET_FRAMEBUFFER(x,?y)???(?m_pFrameBuffer?+?GET_OFFSET(x,?y))//響應鼠標事件 static?void?on_mouse_input(int?event,?int?x,?int?y) {}//響應鍵盤事件 static?void?on_keybd_input(int?event,?int?key) {}//初始化LCD int?LCD_Init(void) {int?ret;ret?=?VirtLCD_Init(LCD_FILENAME,?LCD_WIDTH,?LCD_HEIGHT,?LCD_BPP);if?(!ret){return?0;}m_pFrameBuffer?=?VirtLCD_GetFrameBuffer();VirtLCD_SetMouseProc(on_mouse_input);VirtLCD_SetKeybdProc(on_keybd_input);return?1; }//畫點 void??LCD_DrawPoint(int?x,?int?y,?PIXEL?color) {PIXEL*?mem;mem?=?GET_FRAMEBUFFER(x,?y);*mem?=?color; }//畫水平直線 void??LCD_DrawHLine(int?x1,?int?y1,?int?x2,?PIXEL?color) {PIXEL*?mem;mem?=?GET_FRAMEBUFFER(x1,?y1);for?(;?x1?<?x2;?x1++){*mem++?=?color;} }//畫垂直直線 void??LCD_DrawVLine(int?x1,?int?y1,?int?y2,?PIXEL?color) {PIXEL*?mem;mem?=?GET_FRAMEBUFFER(x1,?y1);for?(;?y1?<?y2;?y1++){*mem?=?color;mem?-=?LCD_WIDTH;} }//在指定位置顯示一個字符 //x,y:起始坐標 //num:要顯示的字符:"?"--->"~" //size:字體大小?12/16/24 //mode:疊加方式(1)還是非疊加方式(0) void?LCD_ShowChar(int?x,?int?y,?int?num,?int?size,?int?mode) {???????????int?temp,t1,t;int?y0=y;int?csize=(size/8+((size%8)?1:0))*(size/2);??//得到字體一個字符對應點陣集所占的字節數?num=num-'?';//得到偏移后的值(ASCII字庫是從空格開始取模,所以-'?'就是對應字符的字庫)for(t=0;t<csize;t++){???if(size==12)temp=ascii_1206[num][t];????//調用1206字體else?if(size==16)temp=ascii_1608[num][t];?//調用1608字體else?if(size==24)temp=ascii_2412[num][t];?//調用2412字體else?return;????????//沒有的字庫for(t1=0;t1<8;t1++){???????if(temp&0x80)LCD_DrawPoint(x,y,FRONT_COLOR);else?if(mode==0)LCD_DrawPoint(x,y,BACK_COLOR);temp<<=1;y++;if(y>=LCD_HEIGHT)return;??//超區域了if((y-y0)==size){y=y0;x++;if(x>=LCD_WIDTH)return;?//超區域了break;}}????}???????????????? }??//顯示字符串 //x,y:起點坐標 //width,height:區域大小?? //size:字體大小 //*p:字符串起始地址???? void?LCD_ShowString(int?x,?int?y,?int?width,?int?height,?int?size,?char*?p) {int?x0?=?x;width?+=?x;height?+=?y;while?((*p?<=?'~')?&&?(*p?>=?'?'))//判斷是不是非法字符!{if?(x?>=?width)?{?x?=?x0;?y?+=?size;?}if?(y?>=?height)break;//退出LCD_ShowChar(x,?y,?*p,?size,?0);x?+=?size?/?2;p++;} }int?main(void) {LCD_Init();printf("hello?virtlcd,?i?am?ZhengN");LCD_DrawHLine(10,?10,?350,?WHITE);LCD_ShowString(10,?30,?LCD_WIDTH,?LCD_HEIGHT,?12,?"hello?virtlcd,?i?am?ZhengN");LCD_ShowString(10,?50,?LCD_WIDTH,?LCD_HEIGHT,?16,?"hello?virtlcd,?i?am?ZhengN");LCD_ShowString(10,?70,?LCD_WIDTH,?LCD_HEIGHT,?24,?"hello?virtlcd,?i?am?ZhengN");LCD_DrawHLine(10,?110,?350,?WHITE);while(1);return?0; }以上就是本次的分享。如果文章對你有幫助,麻煩三連支持一下
代碼下載
VirtLCD SDK包及本文的VirtSTM32工程demo我已經打包好了,大家可以點擊下方卡片關注,后臺回復關鍵詞:LCD?,即可獲取。
總結
以上是生活随笔為你收集整理的LCD也可以模拟?这款模拟器别错过了!的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 上汽集团宁德-墨西哥国际自营航线首发启航
- 下一篇: windows flushdns卡住如何