A GDI+ Based Character LCD Control
| This is a renew. |
A GDI+ Based Character LCD Control
by Conmajia
Character liquid crystal display (LCD) modules are widely used in electronic devices, instruments and handiworks. They are simple, flexible, clear to view, and low power. Fig.1 shows an example of character LCD used in an amateur project.

Fig.1 LCD in An Amateur Instrument
Very cool, isn't it? What if I told you that you could implement this hardware part as a software UI control and used it in your applications? To accomplish this, you have to get to know some of the hardware details.
Inside an LCD module, there are matrixed liquid crystal dots. Built-in controllers scan rows (COMn) and columns (SEGn) to activate dots to constitute characters and symbols. The process is shown in fig.2.

Fig.2 LCD Display Principle
One thing above all you should know is the register set that controls all display content of the control: display data RAM (DDRAM), character generator RAM/ROM (CGRAM/ROM).
The DDRAM is an 80-byte buffer which can hold up to 40×2 of display data. That is the largest size of a single LCD controller (HD44xxx series) supports. You change characters on the screen by changing bytes in the DDRAM. CGRAM/ROM are used to generate custom characters or symbols, or just simply load pre-defined character/symbols in the ROM. With the character generator, you can do lots tricks such as display animations, icons or Chinese characters.
With all the hardware knowledges you just learned, you can now have your "soft" LCDs. Fig.3 demonstrates one of my implementations.

Fig.3 Demo of My LCD Control
The LCD control is a standard WinForm control derived from the UserControl class.
public class DotMatrixLcd : UserControl
A 2-D array works as the DDRAM to store all characters to be displayed.
DotMatrixCharacter[][] characters;
The DotMatrixCharacter represents a single character in the DDRAM. I made it a Control derived class to easy my work. You are welcome to optimize this if you found it to heavy to use.
public class DotMatrixCharacter : Control
To generate raw character data, a CG class is defined as below.
public sealed class CharacterGenerator
{
/// Get character data from DDRAM by address.
public static byte[] GetDdram(byte address)
{
return charset[address];
}
/// Get character data from DDRAM to match the given character.
public static byte[] GetDdram(char character)
{
return charset[(byte)character];
}
// 8 cgram chars
static byte[][] cgram = new byte[8][];
// for dummy
static byte[] emptyChar ={ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
/// Store character data in CGRAM registers by index.
public static void SetCgram(byte[] data, int index)
{
if (data == null || data.Length != 8)
return;
if (index < 0 || index > 7)
return;
cgram[index] = data;
}
/// Get CGRAM character data by index.
public static byte[] GetCgram(int index)
{
if (index < 0 || index > 7)
return emptyChar;
return cgram[index];
}
// 256x8 bytes (1024 bytes) characters
static readonly byte[][] charset =
{
// 0000 0000
new byte[]{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
// 0000 0001
new byte[]{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
// ...
Now all the data is ready. Now the next todo is on the canvas. To paint a character, a renderer is built in the DotMatrixCharacter control.
void drawBlocks(Graphics g)
{
byte[] charData;
// check source of char to display for CGRAM support
switch (charSource)
{
case DisplaySource.CGRAM:
if (cgramData == null || cgramData.Length != DOT_ROWS)
// invalid data, draw empty
// all 0x00
charData = new byte[DOT_ROWS];
else
charData = cgramData;
break;
case DisplaySource.DDRAM:
default:
charData = CharacterGenerator.GetDdram(ddramAddress);
break;
}
// ready to draw
byte mask;
for (int i = 0; i < DOT_ROWS; i++)
{
// if use mask = 0x01 (right to left)
// the output will be vertical mirrored
mask = 0x01 << (DOT_COLS - 1);
for (int j = 0; j < DOT_COLS; j++)
{
if ((mask & charData[i]) == 0)
{
// 0 - empty
if (circleBlock)
g.FillEllipse(
inactiveBrush,
j * (blockSize.Width + spacing),
i * (blockSize.Height + spacing),
blockSize.Width,
blockSize.Height
);
else
g.FillRectangle(
inactiveBrush,
j * (blockSize.Width + spacing),
i * (blockSize.Height + spacing),
blockSize.Width,
blockSize.Height
);
}
else
{
// 1 - fill
if (circleBlock)
g.FillEllipse(
activeBrush,
j * (blockSize.Width + spacing),
i * (blockSize.Height + spacing),
blockSize.Width,
blockSize.Height
);
else
g.FillRectangle(
activeBrush,
j * (blockSize.Width + spacing),
i * (blockSize.Height + spacing),
blockSize.Width,
blockSize.Height
);
}
// next bit
//mask <<= 1;
// msb to lsb
mask >>= 1;
}
}
}
With the built-in renderer, the final LCD module control can obtain the extensibility to switch between different display contents like character displays, graphic dot matrix display, etc.
Source Code & Demo Executive
Download 'em here:
References
- How to Use Character LCD Module, chan@elm-chan.org
A GDI+ Based Character LCD Control的更多相关文章
- 阅读Deep Packet Inspection based Application-Aware Traffic Control for Software Defined Networks
Deep Packet Inspection based Application-Aware Traffic Control for Software Defined Networks Globlec ...
- 📟 Character Liquid Crystal Display Control (English)
A replica CLCD module control. Initiated on May 5, 2012 Updated on Feb 21, 2017 Copyright 2012-2017 ...
- Mecanim Control
http://www.ufe3d.com/doku.php/mecanimcontrol Mecanim Control Your ultimate solution for Mecanim base ...
- linux驱动之LCD
LCD程序步骤:1. 分配一个fb_info 2. 设置 3. 硬件相关的操作4. 注册 register_framebuffer 5.入口函数 6.出口函数 #include <linux/s ...
- 驱动05.lcd设备驱动程序
参考s3c2410fb.c总结出框架 1.代码分析 1.1 入口函数 int __devinit s3c2410fb_init(void) { return platform_driver_regis ...
- LCD 显示异常定位分析方法
第一种情况: 进入kernel或android 后,如果LCM图像示异常,可以通过如下步骤来判断问题出现在哪个层面. step1:通过DMMS截图,来判断上面刷到LCM的数据是否有问题. 若DMMS获 ...
- lcd驱动框架
目录 lcd驱动框架 框图 程序分析 入口 打开open 读read 初始化registered_fb 注册 小结 程序设计 测试 方式一操作fb0 方式二操作tty 方式三操作终端 完整程序 tit ...
- Linux学习: LCD驱动
一.LCD驱动框架: 1.分配一个fb_info结构体:s3c_lcd = framebuffer_alloc(0,NULL); 2.设置fb_info(s3c_lcd): ID.固定参数.可变参数. ...
- 关于Unity树形插件Tree View Control的相关搜集
博客http://blog.csdn.net/qq_15267341/article/details/51997926 的这个 Script Based Runtime Tree-Vie ...
随机推荐
- mysql中的一些操作语句,留存
CREATE TABLE `poision` ( `username` varchar(20) NOT NULL , `nowtime` varchar(50) NOT NULL , `poision ...
- 百度地图JavascriptApi Marker平滑移动及车头指向行径方向
相信只要是使用百度地图做实时定位服务的朋友都会遇到这个问题,在对坐标位置进行覆盖物展示的时候,会出现由于获取坐标数据时间或者两个坐标点相距过远,导致在视觉上看Marker移动就像"僵尸跳&q ...
- 关于使用lazytag的线段树两种查询方式的比较研究
说到线段树,想来大家并不陌生——最基本的思路就是将其规划成块,然后只要每次修改时维护一下即可. 但是尤其是涉及到区间修改时,lazytag的使用往往能够对于程序的质量起到决定性作用(Ex:一般JSOI ...
- 使用Eclipse/MyEclipse开发Java程序
集成开发环境(IDE)是一类软件 将程序开发环境和程序调试环境集合在一起,提高开发效率 下载eclipse安装包网址:http://www.eclipse.org/downloads/ **MyEcl ...
- php基础语法(20161021)
上午: 数据库总结: 1.创建数据库 create database 数据库名称 删除数据库 drop database 数据库名称 2.创建表 create table 表名 ( 列名 类型(长度) ...
- Maven使用说明
maven的作用. Maven 是一个项目管理和构建自动化工具.可以方便我们导入jar包. maven的安装. 要想安装maven,首先你需要安装jdk,并且配置jdk环境变量.右键点击计算机,选择属 ...
- spdlog源码阅读 (1): sinks
0. spdlog简单介绍 spdlog 是一个快速的 C++ 日志库,只包含头文件,兼容 C++11.项目地址 特性: 非常快 只包含头文件 无需依赖第三方库 支持跨平台 - Linux / Win ...
- ListView的性能优化
@Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder viewHol ...
- MyBatis快速入门(一)
一.MyBatis背景介绍 MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索.MyBatis使用简单的 ...
- JS-DOM . 01 简单了解DOM
DOM概述 html加载完毕,渲染引擎会在内存中把html文档生成一个DOM树,getElementById是获取内DOM上的元素,然后操作的时候修改的是该元素的属性 体验事件/事件三要素1.事件源( ...