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:

Source Code

Demo

References

  1. How to Use Character LCD Module, chan@elm-chan.org

↑Go top

A GDI+ Based Character LCD Control的更多相关文章

  1. 阅读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 ...

  2. 📟 Character Liquid Crystal Display Control (English)

    A replica CLCD module control. Initiated on May 5, 2012 Updated on Feb 21, 2017 Copyright 2012-2017 ...

  3. Mecanim Control

    http://www.ufe3d.com/doku.php/mecanimcontrol Mecanim Control Your ultimate solution for Mecanim base ...

  4. linux驱动之LCD

    LCD程序步骤:1. 分配一个fb_info 2. 设置 3. 硬件相关的操作4. 注册 register_framebuffer 5.入口函数 6.出口函数 #include <linux/s ...

  5. 驱动05.lcd设备驱动程序

    参考s3c2410fb.c总结出框架 1.代码分析 1.1 入口函数 int __devinit s3c2410fb_init(void) { return platform_driver_regis ...

  6. LCD 显示异常定位分析方法

    第一种情况: 进入kernel或android 后,如果LCM图像示异常,可以通过如下步骤来判断问题出现在哪个层面. step1:通过DMMS截图,来判断上面刷到LCM的数据是否有问题. 若DMMS获 ...

  7. lcd驱动框架

    目录 lcd驱动框架 框图 程序分析 入口 打开open 读read 初始化registered_fb 注册 小结 程序设计 测试 方式一操作fb0 方式二操作tty 方式三操作终端 完整程序 tit ...

  8. Linux学习: LCD驱动

    一.LCD驱动框架: 1.分配一个fb_info结构体:s3c_lcd = framebuffer_alloc(0,NULL); 2.设置fb_info(s3c_lcd): ID.固定参数.可变参数. ...

  9. 关于Unity树形插件Tree View Control的相关搜集

    博客http://blog.csdn.net/qq_15267341/article/details/51997926      的这个   Script Based Runtime Tree-Vie ...

随机推荐

  1. java基础:学生管理系统

    package com.lovo.manager; import java.util.Scanner; /** * 学生管理 * * @author 向往的生活 * */public class St ...

  2. 算法模板——sap网络最大流 1(非递归+邻接矩阵)

    实现功能:首行输入N,M,S,T,代表这张图N个点,M条边,源点为S,汇点为T:接下来T行输入个边的出发点.终点和权值:输出最大流 原理:sap网络流算法(详见百度百科,个人觉得这个模板已经不错了,虽 ...

  3. 浅谈jquery插件开发模式

    首先根据<jQuery高级编程>的描述来看,jQuery插件开发方式主要有三种: 通过$.extend()来扩展jQuery 通过$.fn 向jQuery添加新的方法 通过$.widget ...

  4. C# 使用 USB转串 接收数据 问题

    C# 使用 USB转串 接收数据的 问题 硬件设备是MicroUSB接口,通过USB转串驱动接入PC机.自己用winForm写了一个读取串口数据的小程序,总是接收不到数据. 用传sscom32串口工具 ...

  5. dreamweaver破解版下载地址

    dreamweaver CC 2015可以在可视化环境中设计的你网页,非常方便高效完成网页设计.Adobe Dreamweaver CC 2015支持CSS编辑器.和jQuery库代码自动完成功能等等 ...

  6. C#随机取得可用端口号

    TCP与UDP段结构中端口地址都是16比特,可以有在0---65535范围内的端口号.对于这65536个端口号有以下的使用规定: (1)端口号小于256的定义为常用端口,服务器一般都是通过常用端口号来 ...

  7. Spring 框架原理

    [spring框架原理] Spring框架原理 [博主]高瑞林 [博客地址]http://www.cnblogs.com/grl214 写给读者的话 ------亲爱的读者感谢您对小编的支持,当我正值 ...

  8. 关于RestfulAPI与SpringMVC之间的传值

    ##默认读者已经搭建好的SpringMVC的环境,并且对SpringMVC有着一定的了解,并且已经对RestfulAPI有了一定的了解 1,首先将WEB-INF下的web.xml里面的url-part ...

  9. Linux环境下的IDE,极大提升编程效率

    "一个真正的程序员是不用IDE(译者注:集成开发环境)的,他们都是用带着某某插件的文本编辑器来写代码."我们总能在某些地方听到此类观点.然 而,尽管越来越多的人同意这样的观点,但是 ...

  10. 老李推荐:第14章3节《MonkeyRunner源码剖析》 HierarchyViewer实现原理-HierarchyViewer实例化

    老李推荐:第14章3节<MonkeyRunner源码剖析> HierarchyViewer实现原理-HierarchyViewer实例化 poptest是国内唯一一家培养测试开发工程师的培 ...