大家好,我是张巧龙,在嵌入式开发中,有时候有些调试环境、流程比较复杂/繁杂。比如有些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也可以模拟?这款模拟器别错过了!相关推荐

  1. android模拟器能刷推广吗,模拟玩安卓模拟器已成重度手游主要推广渠道

    根据DataEye发布的行业数据报告显示,在智能手机普及的这几年里,玩家在终端设备上的行为发生了比较大的变化.以前的手机时间是一种碎片化的时间.手机游戏其实是占据碎片化时间的一种游戏.在统计这些数据会 ...

  2. python模拟按键_python 模拟按键放在模拟器Python初学者的17个技巧

    Python初学者的17个技巧,有需要的朋友可以参考下. W WW.002pc .COM认为此文章对<python 模拟按键放在模拟器Python初学者的17个技巧>说的很在理. 交换变量 ...

  3. 使用这5款模拟器访问备选操作系统

    模拟器是我平时闲暇时最喜欢琢磨的与科技相关的东西.也许这只是我自己的爱好,但是能够在你的PC上运行一个备用操作系统这件事确实很酷,尤其是当这个备用操作系统很好玩.本文将谈谈这5款旧的和新的模拟器. 1 ...

  4. LCD显示器的模拟和数字接口

    LCD显示器的模拟和数字接口 1 模拟接口 模拟和数字视频信源已经存在了很长时间,模拟视频常用于台式机,而数字视频则在笔记本电脑中比较流行.当前大量计算机使用的模拟视频输出,因此保证了模拟接口支持 ...

  5. 梦幻模拟战手游怎么在电脑上玩 梦幻模拟战安卓模拟器玩法教程

    梦幻模拟战是上古三大日式RPG的巅峰之一,作为正统游戏续作将传承经典特色,还原游戏经典,在剧情上补充了游戏后续空白,同时进行内容创新.战棋式策略战斗让玩家感受到时代气息,游戏画面升级换代,战斗流程也更 ...

  6. mysql56401_一款你不容错过的Laravel后台管理扩展包 —— Voyager

    一款你不容错过的Laravel后台管理扩展包 -- Voyager 由 学院君 创建于4年前, 最后更新于 4个月前 版本号 #3 43101 views 16 likes 0 collects 1. ...

  7. 运动蓝牙耳机什么好?五款国产不容错过的运动耳机

    运动蓝牙耳机什么好?五款国产不容错过的运动耳机 随着我们健康意识的增强,运动健身也开始纳入生活必需之中,由于运动过程是比较枯燥的,也容易产生疲倦感,因此不少人在运动时会使用蓝牙耳机听听音乐,来消除运动 ...

  8. Android模拟Windows10,windows10模拟器

    <windows10模拟器安卓版>是一款功能强大的模拟器工具,可以直接把你的手机当成一部安装着win10系统的电脑,让大家在这里模拟win10系统支持的软件和各种电脑游戏,再也不用为身边没 ...

  9. GNS模拟linux,GNS3模拟器官方版最新版及安装说明

    GNS3模拟器官方版是一款网络模拟器,功能十分强大,能够模拟不同网络设备的硬件平台,如思科和瞻博的网络设备,包括路由器.交换机.防火墙等.同时,GNS3模拟器官方版还是一个图形化的网络模拟器,允许模拟 ...

最新文章

  1. 直接在PDF文件中改变字体的小技巧
  2. Python的XML解析!
  3. android 资源引用 自定义标题栏
  4. java数组可扩展_[转载]Java数组扩容算法及Java对它的应用
  5. 英宝通4.0公开课---致力于提供最新的Unity3D技术
  6. 使用Julia进行图像处理--图像分割
  7. android之camera
  8. VC++ 添加用户环境变量
  9. testufo测试刷新率测试_【中立观点】黑鲨3测试体验报告
  10. 京东月薪8万快递员:真正牛逼的人,都拥有这个特质
  11. 项目管理之风险管理:如何系统化应对风险?
  12. Maven配置nexus私服地址
  13. java 搭建个人博客_5分钟 教大家搭建免费个人博客
  14. APM32 ST-LINK不能刷入
  15. 安装了VCam后,VideoCapture 出问题,FileStorage fs(X.yml, FileStorage::READ)报错
  16. 物联网平台 ThingsBoard 3.3 发布
  17. Unity3D研究院之Unity中连接本地或局域网MySQL数据库
  18. 超声波塑料焊接电源发生器电控箱设计
  19. 8086微型计算机原理答案,8086微型计算机原理与应用(吴宁)习题答案(第二章)
  20. 程序员必备的600个英语词汇(4)

热门文章

  1. 如何在S/4HANA里创建Custom Business object并实现自定义逻辑
  2. SAP中国研究院再次荣获年度中国最佳雇主,国际友人纷纷发来贺电
  3. Why close date in S2 view is not displayed correctly after clicking it
  4. 阮一峰react demo代码研究的学习笔记 - ReactMount.render
  5. Jerry带您了解Restful ABAP Programming模型系列之三:云端ABAP应用调试
  6. Fiori navigation logic ( Route )
  7. windows系统上openssh client的离线安装
  8. Request load debugging - CRM side
  9. QGS/300 performance issue
  10. Java Spring log源代码学习