字符型液晶屏模拟控件(En)
A replica CLCD module control.
Initiated on May 5, 2012
Updated on Feb 21, 2017
Copyright 2012-2017 Conmajia
Nobi's LCM Display
Simple Demo
Here is a demo screenplay of the LCM control. Just in case you understand what I'm talking 'bout.
Basic Background
Character liquid crystal display module (CLCD, or simply LCD/LCM) module is one of the display devices well used for electronic equipments.
Panel Organization
An LCM panel that displays alpha-numeric characters is controlled by its core controller chip like Hitachi's HD44780 or HD44100. Panels are organized in general as shown below.
Inside The Controller
Two things among all the hardware details that you should pay attention are the DDRAM and the CGRAM/CGROM.
DDRAM
DDRAM (display data RAM) is an 80-byte buffer which can hold up to 40 columns by 2 rows of display data. You change a DDRAM byte, you change that character on the screen.
CGRAM/CGROM
Character generator is formed by 2 parts: the CGRAM and the CGROM. With the character generator you can draw custom characters such as symbols, icons and simple Chinese characters.
Implementation
The LCD control is a standard WinForm control derived from the UserControl
class.
[ToolboxBitmap("Lcd\\lcd_logo.bmp")]
public partial class DotMatrixLcd : UserControl
With a 2-D array stores all characters to display.
DotMatrixCharacter[][] characters;
A DotMatrixCharacter
represents the data of a character to display. I made this class a Control
so that it can do much more than storing data.
public class DotMatrixCharacter : Control
public byte Ddram
public byte[] Cgram
public char Character
Generate Character
A generator class is designed to return raw character data for the control.
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 prepared.
Paint A Character
The characters renderer is inside 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.
Full Project Source & Demo Executive
You can download them here:
Project source code: → Click to download
Demo executive file: → Click to download
References
- How to Use Character LCD Module, elm-chan.org
字符型液晶屏模拟控件(En)的更多相关文章
- CAD全屏显示控件
主要用到函数说明: MxDrawXCustomFunction::Mx_FullScreen 全屏显示控件,详细说明如下: 参数 说明 int iFull = 2 0: 不完屏,1:全屏,2:自动切换 ...
- 基于stm32f4的ucGUI通过外部flash存储汉字库显示任意英文字符和汉字组合(控件可用)
在做一个用到ucGUI的项目的时候要用到不定的汉字和英文字符,但是ucGUI本身又不支持读取芯片外部flash的字库来显示,于是查了下资料,如下: http://www.cnblogs.com/hik ...
- 模拟winform里的控件的事件和委托机制
参考:.NET 中的委托 委托的两大用处 1.委托可以实现方法作为参数进行传递,如 /// <summary> /// the English speaker. /// </summ ...
- C#在截屏时将截屏之前需要隐藏的控件也截入
最近我在项目中遇到一个让我十分头疼的问题,就是我在截屏时也将截屏之前隐藏的控件也截入了. 情况:我在Winform窗体有个截屏功能按钮,实现在调用WPF全屏后截屏,但在截屏WPF界面前将界面里的一个L ...
- Android 中常见控件的介绍和使用
1 TextView文本框 1.1 TextView类的结构 TextView 是用于显示字符串的组件,对于用户来说就是屏幕中一块用于显示文本的区域.TextView类的层次关系如下: java.la ...
- Android 控件属性介绍
1.LinearLayout(线性布局): 可以分为水平线性:android:orientation= " horizontal " 和垂直线性:android:orientati ...
- 银行支票和汇票中使用的专用字体MICR E13B条形码控件字体
MICR E13B条形码控件字体是一种在美国.加拿大.波多黎各.巴拿马.英国和其它少数国家的银行支票和汇票中使用的专用字体,主要用来打印适用于磁性和光学字符识别系统的MICR字符.MICR E13B条 ...
- MFC中树控件CTreeCtrl的用法
树形控件可以用于树形的结构,其中有一个根接点(Root)然后下面有许多子结点,而每个子结点上有允许有一个或多个或没有子结点.MFC中使用CTreeCtrl类来封装树形控件的各种操作.通过调用 BOOL ...
- windows 编程 —— 子窗口 与 子窗口控件
目录: 子窗口与主窗口的交互 子窗口控件 按钮类别 button 滚动条类别 scrollbar 静态类别 static 编辑框类别 edit 清单方块 listbox 子窗口与主窗口的交互 创建窗 ...
随机推荐
- BZOJ_1705_[Usaco2007 Nov]Telephone Wire 架设电话线_DP
BZOJ_1705_[Usaco2007 Nov]Telephone Wire 架设电话线_DP Description 最近,Farmer John的奶牛们越来越不满于牛棚里一塌糊涂的电话服务 于是 ...
- 电梯调度二——曹玉松&&蔡迎盈
电梯初步版本 经过去实际大楼的调查和一周的学习,初步完成了电梯的制作,但是这个版本的电梯功能并不是很全面,而且界面有待于改善,现在做出了测试版本,稍后进一步跟进新的版本,现在的版本初步完成的是电 ...
- JAVA基础第三章-类与对象、抽象类、接口
业内经常说的一句话是不要重复造轮子,但是有时候,只有自己造一个轮子了,才会深刻明白什么样的轮子适合山路,什么样的轮子适合平地! 我将会持续更新java基础知识,欢迎关注. 往期章节: JAVA基础第一 ...
- this指向和apply,call,bind三者的区别
一.前言 this指向,apply,call,bind的区别是一个经典的面试问题,同时在项目中会经常使用到的原生的js方法.同时也是ES5中的众多坑的一个.ES6中可能会极大的避免了this产生的错误 ...
- 《HelloGitHub》第 32 期
公告 新加入了 2 位机器学期的小伙伴负责机器学习专栏.项目的首页增加合作组织一栏,如有开源组织有意合作可以点击联系我. 我们还在路上,不停地前行. <HelloGitHub>第 32 期 ...
- Java集合详解8:Java集合类细节精讲
今天我们来探索一下Java集合类中的一些技术细节.主要是对一些比较容易被遗漏和误解的知识点做一些讲解和补充.可能不全面,还请谅解. 本文参考:http://cmsblogs.com/?cat=5 具体 ...
- 判空、判等、转码的StringUtil
目录 StringUtil类 StringUtil类 import java.io.UnsupportedEncodingException; /** * 字符串工具 */ public class ...
- 常用的Java Keytool Keystore命令
Java keytool是密钥和证书管理工具.它使用户能够管理自己的公钥/私钥对及相关证书,用于(通过数字签名)自我认证(用户向别的用户/服务认证自己)或数据完整性以及认证服务.它还允许用户储存他们的 ...
- laravel中如何利用反射实现依赖注入
依赖注入 在一个类中经常会依赖于其他的对象,先看一下经典的写法 class Foo { public $bar; public function __construct() { $this->b ...
- Git常用简介
Git是什么 git是目前最先进的分布式版本控制系统,它的核心架构如下图所示,分为四个核心区域.git的常用命令主要是关于这四个区域. 本地工作区-work 本地工作区就是我们实际电脑中的文件夹以及文 ...