LCD也可以模拟?这款模拟器别错过了!
大家好,我是張巧龍,在嵌入式開發(fā)中,有時候有些調(diào)試環(huán)境、流程比較復(fù)雜/繁雜。比如有些bug需要跑很長的一段流程才可以復(fù)現(xiàn),這時候如果按照正常的流程來調(diào)試,單單是復(fù)現(xiàn)問題估計都需要花不少時間。
這時候應(yīng)該要多思考需要怎么去模擬一個相同的環(huán)境,可以更方便地進(jìn)行調(diào)試,一個好的仿真環(huán)境可以大大地提高工作效率。比如數(shù)據(jù)的模擬、流程的模擬、通信收發(fā)的模擬等方面,或是用一些網(wǎng)上現(xiàn)成的模擬器。
本次就來給大家分享一個實用的LCD模擬器:VirtLCD。這個模擬器在我們的工作中有用到,覺得挺實用,分享給大家。
這個模擬器的代碼是開源的,大家感興趣的話可以自己去下載來研究。
地址:
?https://gitee.com/kerndev/VirtualLCD
?下面進(jìn)行實踐演示
先看一個圖:
使用VirtLCD時,我們同樣需要一個demo(VirtSTM32)工程編寫我們的界面設(shè)計代碼,調(diào)試好之后可以很快地移到STM32工程上。
我們在使用STM32做LCD顯示時,常常會封裝一些基礎(chǔ)的繪制函數(shù),如畫點、畫線等函數(shù)。同樣的,使用VirtSTM32與VirtLCD做調(diào)試時,也要封裝類似函數(shù),作者也給我們提供了一些參考,如:
//畫點 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控制臺程序)進(jìn)行驗證,然后把這些函數(shù)加到我們的VirtSTM32工程里。
同時,VirtSTM32需要依賴于VirtLCD.lib,導(dǎo)入即可,這個庫可以在VirtLCD SDK包里找到(文末統(tǒng)一發(fā)給大家)。
有了這三個基礎(chǔ)函數(shù),我們可以就可以做很多的事情了,顯示字符串、顯示圖片等函數(shù)都是以畫點函數(shù)為基礎(chǔ)的,這些函數(shù)可以在各種開發(fā)板的lcd相關(guān)例程里找到,拿過來修改一下就可以。接下來我們顯示一些字符串到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; }運行結(jié)果:
這就是模擬STM32裸機(jī)顯示字符串到VirtLCD中,調(diào)試好之后我們可以很快地移到真正的STM32工程中。
這里只是進(jìn)行簡單的演示,當(dāng)然,感興趣的話,還可以移植LVGL、emwin等GUI進(jìn)去。
附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坐標(biāo)的幀緩存指針 #define?GET_OFFSET(x,?y)????????((?LCD_WIDTH?*?(?LCD_HEIGHT?-?(y)?-?1)?)?+?(x)?) #define?GET_FRAMEBUFFER(x,?y)???(?m_pFrameBuffer?+?GET_OFFSET(x,?y))//響應(yīng)鼠標(biāo)事件 static?void?on_mouse_input(int?event,?int?x,?int?y) {}//響應(yīng)鍵盤事件 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:起始坐標(biāo) //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);??//得到字體一個字符對應(yīng)點陣集所占的字節(jié)數(shù)?num=num-'?';//得到偏移后的值(ASCII字庫是從空格開始取模,所以-'?'就是對應(yīng)字符的字庫)for(t=0;t<csize;t++){???if(size==12)temp=ascii_1206[num][t];????//調(diào)用1206字體else?if(size==16)temp=ascii_1608[num][t];?//調(diào)用1608字體else?if(size==24)temp=ascii_2412[num][t];?//調(diào)用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;??//超區(qū)域了if((y-y0)==size){y=y0;x++;if(x>=LCD_WIDTH)return;?//超區(qū)域了break;}}????}???????????????? }??//顯示字符串 //x,y:起點坐標(biāo) //width,height:區(qū)域大小?? //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我已經(jīng)打包好了,大家可以點擊下方卡片關(guān)注,后臺回復(fù)關(guān)鍵詞:LCD?,即可獲取。
總結(jié)
以上是生活随笔為你收集整理的LCD也可以模拟?这款模拟器别错过了!的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 上汽集团宁德-墨西哥国际自营航线首发启航
- 下一篇: 抽奖 | 送树莓派PICO开发板、机械键