点阵屏上绘图——基于LCD12864控制详解
怎样在点阵屏上绘图——基于LCD12864三

怎样在点阵屏上绘图——基于LCD12864【三】专业 2008-09-27 16:42 阅读122 评论0字号:大中小3.4 我行我素前面我们说过一个函数:void DispBITMap(const char *String,char StringLength,char X,char Y,char DispModel);借助这个函数,我们很容易把一个定义好的图片(字模)显示出来。
但是,这显然太中规中矩了一点。
简单的应用,如果我们想做一个图片在屏幕上来回弹的经典屏保效果就很恼火(恼火是四川话麻烦的意思)。
显然,在屏幕的任意位置显示图片就成了急需解决的问题。
一种基本思想就是,我们在系统的某一个地方再开辟一个显示缓冲区,通过一点点计算,把图片影响到的地方都改写好,然后直接把这块缓冲区影射到原先的显示缓冲中,或者干脆直接显示出来。
怎么,还是不懂?好吧,这样给你打一个比方:12864的现存结构是以纵向的8个点为一个字节,如果我们想在以8为倍数的行开始(单位是像素)显示一个8*n的字模,那么只需要简单得调用本节开始时后提到的函数把字模送过去就可以了;But,如果我们想在别的位置(显然只有行是问题,对于12864来说,列是很容易设置的),显示这个字符呢?你可以自己先思考下下。
对于一个只有1K大小连基本显示缓冲区都开不起的M8来说,你别指望他还能再凭空找出一块地方给你做什么预处理缓冲,问题是,有必要么?实际上,我们每次进行图片变换牵涉到的显存是有限的。
比方说,我们要处理一个8*n的字符,那么每次需要参与处理的字节最多只有(8/8)+1个;我们需要处理一个16*n的字符,那么每次需要参与处理的字节最多只有(16/8)+1个。
如果需要图片在任意位置显示,那么需要参与计算的字节只有(Y/8)+1个。
那么我很容易把缓冲用的显示存储单元数量减少到一个可以接受的范围,比方说12864的8个。
计算的原理很简单,我们可以很容易写出他的通用函数(以下函数只是伪代码):# define DISP_Model_Draw 0x01 //覆盖# define DISP_Model_AND 0x00 //印花# define DISP_Model_Not 0x02 //反相void showPicture(const char *String,char Length,char Height,char X,char Y,DispModel){char TempRAM[2] = {0,0}; //声明一个显示缓冲,因为是一个一个的处理,所以最多只需要2个字节,但是对于画线函数,就不是这样了char a = 0,b = 0,n = 0;char Temp = 0;if (Y - (Y >> 3 <<3)){//普通情况……代码忽略return ;}//需要处理的情况for (a = 0;a<Height;a++){for (b = 0;b<Length;b++){Temp = (Y+a) - ((Y+a) >> 3 <<3); //求余数TempRAM[0] = getRAM(X,(Y+a)>>3); //这一行明显示伪代码哈TempRAM[1] = getRAM(X,((Y+a)>>3)+1);switch (DispModel){case DISP_Model_Draw:for (n = 0;n<8-Temp;n++){if (String[n]<<(7-n)>>7){TempRAM[0] |= (1<<(n+Temp)); }else{TempRAM[0] &= ~(1<<(n+Temp)); }}for (n = 0;n<Temp;n++){if (String[n] << (7 - n - Temp)>>7){TempRAM[1] |= (1<<n);}else{TempRAM[1] &= ~(1<<n);}}n++;break;……以下略}把TempRAM[0]和TempRAM[1]写入到现存中}}}这一章,我囫囵吞枣的给大家撤了很多原理的东西,章节前后时间跨度之大也是前面诸多章节无法比拟的。
如何在LCD12864上任意画点

一、关于12864的画图功能。
我们知道在纸上画出一个点,我们要知道这个点在张纸上面的位置,也就是这个点在这张纸上面的坐标。
而在12864上面画点也是一样,我们要先知道这个点在液晶屏上面的坐标,然后我们该坐标点黑或是点白可以了。
而在这之前,我们要首先理解12864图形显示坐标。
12864的绘图显示坐标如图所示:需要注意的是它的水平位址并不是一个点有一个位址的,它是16个格才有一个位址。
它的垂直位址也分为上下两半部分。
当我们给出位址是X是0,Y是0的时候,其实里面包含了16个点,也就是说我们一次要操作16个点。
所有当我们要点亮一个点的时候,我们不仅要知道的位址,还要知道它在这个位址中是第几个位,也就是第几个点。
#include<reg52.h>#define uint unsigned int#define uchar unsigned charsbit RS=P2^6; //这个是LCD的数据命令选择端sbit RW=P2^5; //这个是LCD的写入或是读出选择端sbit PSB=P3^2; //这个是LCD串行还是并行选择端sbit RST=P3^4; //这个是LCD的复位端口sbit LCDE=P2^7; // 这个是LCD的使能端/*延时子函数*/void delay(uint x){uint y;for(;x>0;x--)for(y=110;y>0;y--);}/*忙碌检查*/void lcd_busy(){RS=0;RW=1;P0=0XFF;LCDE=1;delay(2);while((P0&0x80)==0x80);/*如下图1,当LCD忙碌的时候BF位是为1,而我们只需要想知道这位,所有与上0x80,当它是1的时候得到0X80,当它是0的时候得到0.*/LCDE=0;}/*写入命令*/void write_com(uchar com){lcd_busy();/*每次操作LCD之前都需要检查一次LCD是否忙碌,不过一般LCD工作比单片机快,所有都不用检查。
LCD12864液晶显示器中文说明

一、液晶显示模块概述12864A-1汉字图形点阵液晶显示模块,可显示汉字及图形,内置8192个中文汉字(16X16点阵)、128个字符(8X16点阵)及64X256点阵显示RAM(GDRAM)。
主要技术参数和显示特性:电源:VDD 3.3V~+5V(内置升压电路,无需负压);显示内容:128列× 64行显示颜色:黄绿显示角度:6:00钟直视LCD类型:STN与MCU接口:8位或4位并行/3位串行配置LED背光多种软件功能:光标显示、画面移位、自定义字符、睡眠模式等二、外形尺寸1.外形尺寸图2.主要外形尺寸项目标准尺寸单位模块体积113.0×65.0×12.8mm定位尺寸105.0×55.0mm视域73.4×38.8 mm行列点阵数128×64dots点距离0.52×0.52 mm点大小0.48×0.48 mm二、模块引脚说明128X64 引脚说明引脚号引脚名称方向功能说明1 VSS - 模块的电源地2 VDD - 模块的电源正端3 V0 - LCD驱动电压输入端4 RS(CS) H/L 并行的指令/数据选择信号;串行的片选信号5 R/W(SID) H/L 并行的读写选择信号;串行的数据口6 E(CLK) H/L 并行的使能信号;串行的同步时钟7 DB0 H/L 数据08 DB1 H/L 数据19 DB2 H/L 数据210 DB3 H/L 数据311 DB4 H/L 数据412 DB5 H/L 数据513 DB6 H/L 数据614 DB7 H/L 数据715 PSB H/L 并/串行接口选择:H-并行;L-串行16 NC 空脚17 /RET H/L 复位低电平有效18 NC 空脚19 LED_A - 背光源正极(LED+5V)20 LED_K - 背光源负极(LED-OV)逻辑工作电压(VDD):4.5~5.5V电源地(GND):0V工作温度(Ta):0~60℃(常温) / -20~75℃(宽温)三、接口时序模块有并行和串行两种连接方法(时序如下):8位并行连接时序图MPU写资料到模块MPU从模块读出资料2、串行连接时序图串行数据传送共分三个字节完成:第一字节:串口控制—格式11111ABCA为数据传送方向控制:H表示数据从LCD到MCU,L表示数据从MCU到LCDB为数据类型选择:H表示数据是显示数据,L表示数据是控制指令C固定为0第二字节:(并行)8位数据的高4位—格式DDDD0000第三字节:(并行)8位数据的低4位—格式0000DDDD串行接口时序参数:(测试条件:T=25℃VDD=4.5V)四、用户指令集指令指令码说明执行时间(540KHZ)RSRWDB7DB6DB5DB4DB3DB2DB1DB清除显示0 0 0 0 0 0 0 0 0 1将DDRAM填满“20H”,并且设定DDRAM的地址计数器(AC)到“00H”4.6ms地址归位0 0 0 0 0 0 0 0 1 X设定DDRAM的地址计数器(AC)到“00H”,并且将游标移到开头原点位置;这个指令并不改变DDRAM的内容4.6ms进入点设定0 0 0 0 0 0 0 1 I/D S指定在资料的读取与写入时,设定游标移动方向及指定显示的移位72us显示状态开/关0 0 0 0 0 0 1 D C BD=1:整体显示ONC=1:游标ONB=1:游标位置ON72us游标或显示移位控制0 0 0 0 0 1S/CR/LX X设定游标的移动与显示的移位控制位元;这个指令并不改变DDRAM的内容72us功能设定0 0 0 0 1 DL XREX XDL=1 (必须设为1)RE=1:扩充指令集动作72us备注:1、当模块在接受指令前,微处理顺必须先确认模块内部处于非忙碌状态,即读取BF标志时BF需为0,方可接受新的指令;如果在送出一个指令前并不检查BF标志,那么在前一个指令和这个指令中间必须延迟一段较长的时间,即是等待前一个指令确实执行完成,指令执行的时间请参考指令表中的个别指令说明。
LCD12864详解

12864液晶一、概述带中文字库的128X64是一种具有4位/8位并行、2线或3线串行多种接口方式,内部含有国标一级、二级简体中文字库的点阵图形液晶显示模块;其显示分辨率为128×64,内置8192个16*16点汉字,和128个16*8点ASCII字符集.利用该模块灵活的接口方式和简单、方便的操作指令,可构成全中文人机交互图形界面。
可以显示8×4行16×16点阵的汉字.也可完成图形显示.低电压低功耗是其又一显著特点。
由该模块构成的液晶显示方案与同类型的图形点阵液晶显示模块相比,不论硬件电路结构或显示程序都要简洁得多,且该模块的价格也略低于相同点阵的图形液晶模块。
基本特性:低电源电压(VDD:+3.0--+5.5V)显示分辨率:128×64点内置汉字字库,提供8192个16×16点阵汉字(简繁体可选)内置 128个16×8点阵字符2MHZ时钟频率显示方式:STN、半透、正显驱动方式:1/32DUTY,1/5BIAS视角方向:6点背光方式:侧部高亮白色LED,功耗仅为普通LED的1/5—1/10通讯方式:串行、并口可选内置DC-DC转换电路,无需外加负压无需片选信号,简化软件设计工作温度: 0℃ - +55℃ ,存储温度: -20℃ - +60℃模块接口说明:*注释1:如在实际应用中仅使用串口通讯模式,可将PSB接固定低电平,也可以将模块上的J8和“GND”用焊锡短接。
*注释2:模块内部接有上电复位电路,因此在不需要经常复位的场合可将该端悬空。
*注释3:如背光和模块共用一个电源,可以将模块上的JA、JK用焊锡短接。
2.2并行接口管脚号管脚名称电平管脚功能描述1 VSS 0V 电源地2 VCC 3.0+5V 电源正3 V0 - 对比度(亮度)调整4RS(CS)H/LRS=“H”,表示DB7——DB0为显示数据RS=“L”,表示DB7——DB0为显示指令数据5R/W(SID) H/L R/W=“H”,E=“H”,数据被读到DB7——DB0R/W=“L”,E=“H→L”, DB7——DB0的数据被写到IR或DR6 E(SCLK) H/L 使能信号7 DB0 H/L 三态数据线8 DB1 H/L 三态数据线9 DB2 H/L 三态数据线10 DB3 H/L 三态数据线11 DB4 H/L 三态数据线12 DB5 H/L 三态数据线13 DB6 H/L 三态数据线14 DB7 H/L 三态数据线15 PSB H/L H:8位或4位并口方式,L:串口方式(见注释1)16 NC - 空脚17 /RESET H/L 复位端,低电平有效(见注释2)18 VOUT - LCD驱动电压输出端19 A VDD 背光源正端(+5V)(见注释3)20 K VSS 背光源负端(见注释3)*注释1:如在实际应用中仅使用并口通讯模式,可将PSB接固定高电平,也可以将模块上的J8和“VCC”用焊锡短接。
学习笔记:LCD12864的画点功能

学习笔记:LCD12864的画点功能本人学习的LCD12864的驱动控制器是ST7920,本文档主要记述了本人学习LCD12864画点原理的一些心得及细节。
但只限于画点功能,其他功能将在其他文档中记述。
首先,先介绍与画点功能有关的存储器:GDRAM:(Graphic Display RAM):图形显示RAM,这一块区域用于绘图,往里面写啥,屏幕就会显示啥,它与DDRAM的区别在于,往DDRAM中写的数据是字符的编码,字符的显示先是在CGROM中找到字模,然后映射到屏幕上,而往GDRAM中写的数据是图形的点阵信息,每个点用1bit来保存其显示与否。
GDRAM的空间结构图如下图所示。
可以看出,它可以看作是32行*256列的屏幕,只不过分成上下半屏来显示,所以GDRAM 的地址是上下半屏连续循环的,例如点亮上半屏的第0行的第0列像素点,之后点亮第0行第2列、第0行第2列、第0行第4列......一直到第0行第127列,此时上半屏第0行像素已经全部点亮,当点亮第0行第128列时,点亮的像素点会是下半屏的第0行第0列,点亮第0行第129列会是下半屏的第0行第1列像素点亮,但要注意地址只是在当前行循环。
比如上面讲的例子,地址始终是在第0行循环的。
另外重要的是,在对GDRAM进行数据读/写时,当读/写完毕后,在当前的行上地址自动增加一个单位,这一个单位的大小为十六个格子,也就是16bit,一个字。
而读/写数据的最小单位也是一个字。
每一个方格代表一个像素点,在GDRAM空间结构中,以十六个方格为一个数据单位,即字(两个字节)。
在对GDRAM读写操作中,也是以字为单位的。
而又以16列*32行为一个单位,共分为16个单位。
分别为图中的0~15,为了方便叙述下面我将这些单位称之为模块(16列*32行,即32字)。
这些模块在存储中是有地址的,0~15分别对应地址80H~8FH。
上半屏为80H~87H,下半屏为88H~8FH。
LCD12864绘图之KS0108(1)

LCD12864(KS0108)之绘图篇(一)写给无字库液晶(KS0108芯片)使用之初学者也许你见过12864LCD 的各种显示方案,也见过字库型液晶(ST7920)的绘图功能。
但要说到可以直接在PROTEUS 中进行软件仿真的Ampire128x64 的绘图功能,情况就不同了。
因为由KS0108芯片控制的Ampire128x64液晶屏,可以在Proteus 中进行软件仿真,这对于初学单片机的人,无疑是成本低廉,效果直观,而且易于操作,配合Keil 编译器,对程序的编写和修改,非常得心应手. Ampire128x64 是无字库点阵液晶屏, 相关使用说明主要体现了它的显示功能,甚至说它只能用显示编码数据。
如编码的汉字,数字,字母,符号,以及图片......而它的绘图功能却只字不提,乃至很多人认为Ampire128x64液晶屏根本不能直接绘制几何图形。
尽管网络上有一些关于Ampire128x64绘图程序的说法,但实际却是用于ST7920驱动的字库型液晶屏的,而在大海橡树的百度空间里出现过Ampire128x64绘图显示的图片,但程序也是一字不外漏。
本人经过近两月的潜心钻研,终于解开了Ampire128x64绘图的瓶颈,尽管走了不少弯路,却很值得。
使用Ampire128x64绘图,关键是点坐标的确定及画点函数的编写,正如有人说:"给我一个画点函数,我可以描绘整个世界". Ampire128x64绘图的瓶颈, 一在于它的扫描结构和ST7920不同,二在于KS0108无专门的绘图扩充指令. 本文针对初学LCD12864的遇到的问题,予以详细讲解,以期能对他们有所帮助。
内容不多,但仍将其分成几个小节进行讲解,以便让初学者有足够的时间进行学习和消化。
凯里市第一中等职业技术学校 电子应用技术高级教师 杨正富 2014-2-4 晚20:10 先上几张图:C S 11C S 22G ND 3V C C 4V 05R S 6R /W 7E 8D B 09D B 110D B 211D B 312D B 413D B 514D B 615D B 716R S T 17-V o u t 18LCAMPIRE12864C S 11C S 22G ND 3V C C 4V 05R S 6R /W 7E 8D B 09D B 110D B 211D B 312D B 413D B 514D B 615D B 716R S T 17-V o u t 18C S 11C S 22G ND 3V C C 4V 05R S 6R /W 7E 8D B 09D B 110D B 211D B 312D B 413D B 514D B 615D B 716R S T 17-V o u t 18LCAMPIRE12864C S 11C S 22G ND 3V C C 4V 05R S 6R /W 7E 8D B 09D B 110D B 211D B 312D B 413D B 514D B 615D B 716R S T 17-V o u t 18AMPIRE12864。
LCD12864(proteus仿真)——指令详解

由RAM 地址映射表可知LCD 显示屏由两片控制器控制,分别用CS1和CS2控制。每个内部带有 64X64 位(512字节)的RAM 缓冲区,对应关系如图3-2所示。
点 LCD 128*64
: 页 列 IC1 8 *64
: 页 列 IC2 8 *64
图3-2 LCD地址映射图
整个屏幕分左、右两个屏,每个半屏右8页,每页有8行,注意数据是竖行排列,如表3.2。显示1个 汉字要16*16点,全屏有128*64个点,故可显示32个中文汉字。每两页显示一行汉字,可显示4行汉字, 每行8个汉字,共32个汉字。而显示1个字符需要16*8个点(或8*8个点),可显示数据是汉字的两陪(用 8*8个点就是4倍)。
功能:读忙信号标志位(BF)、复位标志位(RST)以及显示状态位(ON/OFF)。
BF=H:内部正在执行操作;
BF=L:空闲状态。
RST=H:正处于复位初始化状态;
RST=L:正常状态。
ON/OFF=H:表示显示关闭;
ON/OFF=L:表示显示开。
(6)写显示数据 CODE:R/W RS DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
L H D7 D6 D5 D4 D3 D2 D1 D0
功能:写数据到 DDRAM,DDRAM 是存储图形显示数据的,写指令执行后 Y 地址计数器自 动加 1。D7-D0 位数据为 1 表示显示(点亮),数据为 0 表示不显示(熄灭)。写数据到 DD RAM 前, 要先执行“设置页地址”及“设置列地址”命令。
(2) 设置显示起始行
CODE:R/W RS DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
L L HH
行地址(0~63)
LCD12864液晶显示器中文说明(DOC)

一、液晶显示模块概述12864A-1汉字图形点阵液晶显示模块,可显示汉字及图形,内置8192个中文汉字(16X16点阵)、128个字符(8X16点阵)及64X256点阵显示RAM(GDRAM)。
主要技术参数和显示特性:电源:VDD 3.3V~+5V(内置升压电路,无需负压);显示内容:128列× 64行显示颜色:黄绿显示角度:6:00钟直视LCD类型:STN与MCU接口:8位或4位并行/3位串行配置LED背光多种软件功能:光标显示、画面移位、自定义字符、睡眠模式等二、外形尺寸1.外形尺寸图2.二、模块引脚说明电源地(GND):0V工作温度(Ta):0~60℃(常温) / -20~75℃(宽温)三、接口时序模块有并行和串行两种连接方法(时序如下):8位并行连接时序图MPU写资料到模块MPU从模块读出资料、串行连接时序图2串行数据传送共分三个字节完成:第一字节:串口控制—格式11111ABCA为数据传送方向控制:H表示数据从LCD到MCU,L表示数据从MCU到LCDB为数据类型选择:H表示数据是显示数据,L表示数据是控制指令C固定为0第二字节:(并行)8位数据的高4位—格式DDDD0000第三字节:(并行)8位数据的低4位—格式0000DDDD串行接口时序参数:(测试条件:T=25℃VDD=4.5V)四、用户指令集1、当模块在接受指令前,微处理顺必须先确认模块内部处于非忙碌状态,即读取BF 标志时BF 需为0,方可接受新的指令;如果在送出一个指令前并不检查BF 标志,那么在前一个指令和这个指令中间必须延迟一段较长的时间,即是等待前一个指令确实执行完成,指令执行的时间请参考指令表中的个别指令说明。
2、“RE ”为基本指令集与扩充指令集的选择控制位元,当变更“RE ”位元后,往后的指令集将维持在最后的状态,除非再次变更“RE ”位元,否则使用相同指令集时,不需每次重设“RE ”位元。
具体指令介绍:1、清除显示 CODE :功能:清除显示屏幕,把DDRAM 位址计数器调整为“00H ” 2、位址归位 CODE :功能:把DDRAM 位址计数器调整为“00H ”,游标回原点,该功能不影响显示DDRAM 3、位址归位 CODE : 功能:把DDRAM 位址计数器调整为“00H ”,游标回原点,该功能不影响显示DDRAM 功能:执行该命令后,所设置的行将显示在屏幕的第一行。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
点阵屏上绘图——基于LCD12864 控制详解2009年04月10日星期五 20:02—前言—前言往往要解释写文章的动机和原因,同时给作者一个正题以外灌水的机会——本文也不例外。
1、为什么我要写这篇文章。
不可否认,我的确受到了Armok的利诱影响,但是最近发生的一些事情却使我觉得写这篇文章是非常有必要的。
在OurAVR上看到很多版本的LCD驱动程序,几乎每一个版本都只是简单的将全部或部分的显示数据Cover到LCD的显存上,完成一个字或者是图片的显示就等着大家喊“牛”了。
其实要走的路还很远。
对一个工程项目来说,增加n多的成本来提供一个点阵屏作为用户接口,不是一两幅欢迎图片和Now Loading...Please Standy By的提示能糊弄的过去的。
用户希望你提供的是友好的图形界面GUI,虽然比不过XP和Apple的华丽,但是由各种基本图形组成的窗口界面还是需要的。
当我们真的想实现一个图形界面的时候,很快就会发现,我们需要的不仅仅是一个被喊了“牛”的初级驱动,我们需要的是一个图形引擎——一个自定义的图形函数包,没有DirectX的华丽,但是能绘制一个任意的直线或是矩形就够了——结果往往发现无所适从。
这个时候,我们遇到的就是一个门槛,真正的嵌入式工程师和一个业余电子爱好者之间的门槛。
2、我如何写这篇文章考虑到本人老王卖瓜的习惯,所以请大家一定无比在吃饭前看本人写的技术文章,同时保持耐心等待续集(绝对有续集)。
本人现单身,个人问题众多,学习任务重,所以可能有时候写文章象羊拉屎,不对大家胃口,请见谅。
硬件平台:AVR Mega8级LCD:不带字库的12864软件平台:ICC规范:符合基本的C编程规范3、何时开始正文广告之后,马上回来……怎样在点阵屏上绘图——基于LCD12864Chapter Zero—预备知识—其实,本文应该算是计算机图形学的一个具体分支,所以,计算机图形学的基本要求就是本文的基本要求,考虑到各位兄弟的胃口,我就多罗嗦下。
1、位操作向LCD12864这种二值屏幕,我们习惯于用1个字节表示连续的8个点,1对应对应位被点亮,0表示不亮,所以对图形的操作最基本的手段就是位操作。
复习下,常用的位操作,假设Dis表示某一个现存地址的内容Dis = Dis~ 黑白颠倒Dis &= ~(1<<n) 第n处被擦去,Dis |= (1<<n) 第n处被画了一个点Dis ^= (1<<n) 如果n处是亮的,就变被擦掉;如果n处是空白的,就被点亮………… 差不多就这些2、作图原理点是一切光栅显示设备的基本要素,所有的操作都是以点为基础的,所以学会如何利用点构成线、圆、填充就是必须掌握的——几何不能太差哦。
还有,结合屏幕的硬件特点,对算法进行优化的一些方法也是需要掌握的。
比方说,如何填充之类的……后面会针对LCD12864作详细介绍的。
3、人机交互学虽然很多人都没有实实在在学过这门功课,但是多多少少对于界面应该怎样有些许了解。
如何利用手中的基本操作函数做出一些特效,如何安排窗体,如何绘制图形界面的一些基本元素如按钮,甚至如何显示汉字,都是人际交互学需要教会你的——总之,如果你没有学过这门课程,你的产品只有你自己用的话——跟着感觉走,没错的。
4、最最重要的物质基础你要掌握一种单片机,掌握一种点阵屏幕。
AVR InsideNot Only For LCD12864怎样在点阵屏上绘图——基于LCD12864Chapter One—从点滴开始—前面已经说过,对于栅格显示设备来说,点是一切图形的基础,说白了,不会在液晶屏幕的任意位置随心所欲的画点就不能说你已经掌握了某种液晶屏幕的使用了。
事实上,根据笔者的经验,尝试画点往往能暴露出很多问题。
就拿LCD12864来说吧,一段时间,笔者总是发现,在片切换的地方有一点点错误……在说明如何画点之前先说明一个概念:显示缓冲区。
所谓显示缓冲区,顾名思义,就是显示数据的一个缓冲地带。
一般情况下,我们绘图也是直接对这块缓冲区域进行操作的。
很多朋友就要提问了:我们为什么不直接对屏幕操作呢?事实上,LCD本身存在一块显示存储器,也可以被认为是一个显示缓存,直接写在这个存储器的数据并非直接显示出来,而多半需要一个显示指令来影射一下。
我们有时候也通过这种类似的技术来实现很大的图片的显示——先画好,再拿给大家看,让人以为你是一下就画好的,当然如果你刻意需要那种图片被“画”出来的效果,则不在讨论之列。
问题就在于,LCD是片外资源,对其存储器的访问可以被认为是对片外存储器的访问,其速度显然没有对片内SRAM的操作速度要快。
如果我们使用那种常用的串行方式来作图(所谓串行方式作图,就是绘图指令的执行和系统的其他操作时串行的,指令不完成,其它操作就不回被执行),那么对于一些实时性要求高的系统来说就会造成重大隐患——甚至是不符合要求的;如果开辟一段片内存储空间和LCD的存储器一一对应,在相同的时间段内,花费相同的资源来保持着两个存储空间的一致性,那么就可以保证实时系统的稳定和可靠,保证画面显示的正常(因为允许跳帧嘛^_^)。
这就是我们为什么需要另外在片内选取一个显示缓冲区的原因。
以后,我们的操作都是针对显示缓冲区的。
显示缓冲区将成为一个概念,无论这个缓冲区位于SRAM内还是LCD内部。
比方说,我们需要一个低成本的游戏机——如做一个贪食蛇游戏机送给老师作为课程设计,或者送给小侄子,那么,M8甚至是M48成为首选,问题是,M8绝对无法开辟出一个8 * 128 = 1K大小的数组,所以,这个时候,认定LCD的片内存储器作为显示缓冲区就是不二的选择——好在贪食蛇速度太快了也没有办法玩哈。
绕了这么多的弯子,究竟如何画点呢?我还想多补充一个原因,关于,为什么需要显示缓冲区,由于点阵屏幕使用的是1个字节来表示8个点的,如果你想使得一个字节中的某一个点被操作而不影响别的点,你起码要知道原来这个位置是什么内容,对于有些使用595级联的LCD设备来说,无法直接从LCD读取现存数据,所以开辟一个缓冲区,从中获得信息加以加工以后再放回去,是这种设备处理显示图形的唯一方法——当然我们没有那么惨,但是从LCD中获取所需点所在字节的内容还是必须的,不然你画一个点就会破坏一条线上所有的数据。
好的,那么我们实际上已经明确了如何去画一个点。
首先,根据用户给出的坐标计算出所要画的点所在现存内的地址偏移量;然后,我们读出该地址内的数据;再次,根据用户所需画点的类型(擦除、画点、反相点)来进行相应的操作获得一个新的数据;最后,将该数据写回原来的地址。
不是很难吧?---------------------------------------------LCD12864补充知识1、关于坐标系。
很多人,包括笔者,一开始都看不懂LCD12864的内存影射方式,感觉X、Y似乎不是那么回事。
后来才发现,只要把屏幕竖着放一切就好懂了。
X 还是横轴,Y还是竖轴……但是这显然不符合我们的习惯,我们习惯于长的那个边作为横轴,所以需要一点点坐标之间的转换。
假设输入的是正常习惯的坐标 X,Y DX DY就是LCD上的坐标,那么转换关系是char DX = (Y >>3); //计算出属于哪个字节char BX = Y - (DX <<3); //属于该字节的哪个位char DY = X;2、读取12864的数据的时候,一定要注意,E信号要在一个下降延之后持续拉高,然后才能正常独处数据;假设直接拉高,的确也能读出数据,但是,等着抓头皮,发帖子“[跪求]大侠帮忙关于12864——请使用明确的大标题……”^_^---------------------------------------------废话少说(说的不少了),看源代码:# define LCD12864_Graphic_Draw 0x01# define LCD12864_Graphic_Clear 0x00# define LCD12864_Graphic_Not 0x02……void LCD12864Draw(char X,char Y,char Type){char DX = (Y >>3); //计算出属于哪个字节char BX = Y - (DX <<3); //计算出属于字节哪一位char TempData = 0;LCD12864_ChooseBoth;setX(DX);if (X > 63){LCD12864_ChooseCS2;X -= 64;}else{LCD12864_ChooseCS1;}setY(X);TempData = getLCD12864Data();switch (Type){case LCD12864_Graphic_Clear:TempData &= ~(1<<BX);break;case LCD12864_Graphic_Not:TempData ^= (1 << BX);break;default:TempData |= (1 << BX);}setY(X);sendDataToLCD(TempData);}怎样在点阵屏上绘图——基于LCD12864特别说明一下,关于贪食蛇范例的问题,这篇文章里面只会简单得提及一下。
作为嵌入式系统开发的一个范例,我会另外开一个帖子详细说明开发过程。
这个范例将作为介绍嵌入式系统开发方法的一个很好的例子,用于解释一个系统和一段表示您调通了某一个功能的代码之间有什么区别,同时也将介绍嵌入式开发系统的几种模式(超级循环、调度器),顺便侃一侃时间驱动的系统RTOS (Real Time Operation System实时操作系统)和RTS(Real Time System)实时系统。
怎样在点阵屏上绘图——基于LCD12864[本章导读]直线由点构成,更精确的说,直线是由靠近这条线的像素构成。
这就引出一个问题,究近那些点算是靠近一条直线;哪些点不算是靠近一条直线,这必须使用一种算法作为依据。
实际上,图形学算法和纯几何算法还是有很大差别的,问题就出在一个离散化上面,说白了,你画出的直线很可能是一组波动厉害的锯齿象素群而不是一条看起来有规则变化的直线。
当然,太过于理论的东西对我们是没有多少实际价值的。
下面,我就介绍两种常见的画线思路,一种就是最容易被想到的直线方程计算的方法,另外一种则是被称为布兰森汉姆(Bresenham)的计算机图形学主流算法。
在介绍完这两种算法以后,我们会针对LCD12864的硬件结构为例子,介绍,具体算法的实现和优化。
怎样在点阵屏上绘图——基于LCD12864首先,我们从最基本的数学算法说起。