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 ...
随机推荐
- thinkphp apicloud 下拉刷新 。。。由于新人里面导入了vue.js
//刷新 apiready = function(){ var count; var i= 1; var param = {}; toDoRequest(); param.loadingImgae = ...
- 2017-3-9 SQL server 数据库
数据库的定义:数据库(Database)是按照数据结构来组织.存储和管理数据的仓库,简单说数据库是一些存储在硬盘上的数据文件,随着信息技术和市场的发展,数据管理不再仅仅是存储和管理数据,而转变成用户所 ...
- 1637: [Usaco2007 Mar]Balanced Lineup
1637: [Usaco2007 Mar]Balanced Lineup Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 393 Solved: 263[ ...
- 好多鱼 Java
牛客网的题目: 链接:https://www.nowcoder.com/questionTerminal/e3dd485dd23a42899228305658457927牛牛有一个鱼缸.鱼缸里面已经有 ...
- Caused by: java.lang.RuntimeException: java.io.IOException: invalid constant type: 18
工程启动的时候有报下面这个错误的,更新下工程的jar包依赖,然后在工程的pom文件里加上下面的jar包 Caused by: java.lang.RuntimeException: java.io.I ...
- android 透明状态栏方法及其适配键盘上推(二)
在上一篇文章中介绍了一种设置透明状态栏及其适配键盘上推得方法.但是上一篇介绍的方法中有个缺点,就是不能消除掉statusbar的阴影.很多手机如(三星,Nexus都带有阴影).即使我用了: <a ...
- curl javaSSm框架中传入json数组的格式方法
curl与java结合传入get.post,head请求, 比如: curl的地址: curl -l 127.0.0.1:8080/spacobj/core/do?acid=100 -H " ...
- 为什么用IP无法访问网站,域名可以访问?
我们访问网站都是通过域名进行访问的,偶尔会使用网站IP进行访问,如学校通常使用IP登录教务处,但很多的时候我们无法通过ip进行访问其他网站,这就涉及到服务器的问题了. 网站都是依托在服务器上面的,而服 ...
- 实现input输入时智能搜索
// 智能搜索 function oSearchSuggest(searchFuc) { var input = $('#in'); var suggestWrap = $('#gov_search_ ...
- WP8.1小梦词典开发2:百度翻译API使用
原文出自:http://www.bcmeng.com/api2/ 小梦昨天和大家分享了WP8.1金山词霸API使用方法,今天继续分享windows phone 8.1中百度翻译API的使用方法.和昨天 ...