教你在12864上打点(基于ST7920控制器).doc_第1页
教你在12864上打点(基于ST7920控制器).doc_第2页
教你在12864上打点(基于ST7920控制器).doc_第3页
教你在12864上打点(基于ST7920控制器).doc_第4页
教你在12864上打点(基于ST7920控制器).doc_第5页
已阅读5页,还剩5页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

基于ST7920控制的12864液晶用于字符显示很方便的,但网友说用它显示图形并不合适,原因就是它绘图时先要关闭显示,绘完后又要打开,速度会较慢。我没有用过别的液晶,手中只有这一款,摆弄了几天,掌握了一点东西,写出来共享。 首先,我们知道,图形都是由像素点组成的,绘图的基础其实就是画点。只要我们能点亮液晶的任意一个像素点,那么绘图就不是什么难事了。万丈高楼平地起嘛,先要做的,当然是要打好基础。 ST7920提供了用于绘图的GDRAM(graph display RAM)。共 6432 个字节的空间(由扩充指令设定绘图 RAM 地址),最多可以控制 25664点阵的二维绘图缓冲空间。在它的Datasheet给出了GDRAM的坐标地址对照表: (原文件名:图片1.png) 引用图片用坐标表示,就是这样: (原文件名:图片2.png) 引用图片它的横坐标每一个地址都是16 位的。共16个地址,256位。很明显,它能控制256*64像素的液晶屏,而我们的只是128*64像素液晶屏,显然只用到它的一部分。我刚开始以为它对应屏幕的绘图RAM是这样分布的(如红色部分): (原文件名:图片3.png) 引用图片结果栽了大根头,后来终于弄明白,原来它对应屏幕的GDRAM是这样分布的:2010-03-25,11:31:56资料邮件回复引用回复 编辑删除【1楼】 汗,发了一半不小心提交了,继续 (原文件名:图片4.png) 引用图片只要我们清楚了它的GDRAM和屏幕上像素点的映射(对应)关系,点亮对应的像素点就容易多了。要点亮某一个像素点,就是将这个像素点在GDRAM中对应的位置1,这个相信没人会不知道吧?我们先讨论一下思路,再一步步写代码。我觉得,思路要比代码重要的多,只要你的思路通了,正确了,那么写出代码肯定会很容易。首先,给你x,y的坐标,要你点亮一个点,要怎么做呢?从上面的图我们知道,它是分为两个半屏的,首先,我们要确定这个点是在上半屏还是下半屏,然后确定它是在那一行(纵坐标Y),再确定它是在哪一个字节的哪一个位(也就是确定它在那一列,即横坐标X)。这些都确定后我们就定位到某一个具体的位上了,只就将这个位置1,就OK了。下面我们边写代码边讨论。因为这里仅仅是讨论如何在12864上打点的,而不是给12864写一个驱动,所以对于基本的数据读写函数,我们不做讨论,这里假设已经有了如下基本函数:void lcd_write_cmd(unsigned char); /lcd 命令写void lcd_write_data(unsigned char); /lcd 数据写unsigend char lcd_read_data(void); /lcd 数据读好了,就这些了。为了方便,我们定义如下宏:#define BASIC_SET 0x00 /基本指令集,后面的数字查数据手册,下同。#define EXTEND_SET 0x00 /扩展指令集#define DRAW_ON 0x00 /绘图显示开#define DRAW_OFF 0x00 /绘图显示关我们现在开始写点亮某一个点的函数:void lcd_set_dot(unsigned char x, unsigned char y) unsigned char x_byet, x_bit; /在横坐标的哪一个字节,哪一个位 unsigned char y_byte, y_bit; x_byte = x / 16; /算出它在哪一个字节(地址) /注意一个地址是16位的 x_bit = x % 16; /算出它在哪一个位 y_byte = y /32; /y是没在哪个字节这个说法 /这里只是确定它在上半屏还是下半屏 /0:上半屏 1:下半屏 y_bit = y % 32; /y_bit确定它是在第几行 lcd_write_cmd(EXTEND_SET); /扩展指令集 lcd_write_cmd(DRAW_OFF); /绘图显示关闭 lcd_write_cmd(0x80 + y_bit); /先写垂直地址 /具体参照数据手册 lcd_write_cmd(0x80 + x_byte + 8 * y_byte); /水平坐标 /下半屏的水平坐标起始地址为0x88 /(+8*y_byte)就是用来确定在上半屏还是下半屏 if (x_bit 8) /如果x_bit位数小于8 lcd_write_data(0x01 (7 - x_bit); /写高字节。因为坐标是从左向右的 /而GDRAM高位在左,底位在右 lcd_write_data(0x00); /低字节全部填0 else lcd_write_data(0x00); /高字节全部填0 lcd_write_data(0x01 (15 - x_bit); lcd_write_cmd(DRAW_ON); /打开绘图显示 lcd_write_cmd(BASIC_SET); /回到基本指令集,毕竟ST7920是以字符为主的 return ;基本画点函数算是完成了,但是我们如果使用这个函数,就会发现问题。你且用它沿横坐标画几个连续的点试试,肯定不是你想要的结果。出现问题的原因是因为我们画点时对其余的位全部填0处理了,造成对原来的信息的破坏。所以我们要读出要写的那个地址原来的数据,再进行加工,写回去就可以解决问题了。改进后的代码:void lcd_set_dot(unsigned char x, unsigned char y) unsigned char x_byet, x_bit; /在横坐标的哪一个字节,哪一个位 unsigned char y_byte, y_bit; unsigned char tmph, tmpl; /定义两个临时变量,用于存放读出来的数据 x &= 0x7F; y &= 0x3F; x_byte = x / 16; /算出它在哪一个字节(地址) /注意一个地址是16位的 x_bit = x&0x0F; /算出它在哪一个位 y_byte = y /32; /y是没在哪个字节这个说法 /这里只是确定它在上半屏还是下半屏 /0:上半屏 1:下半屏 y_bit = y&0x3F; /y_bit确定它是在第几行 lcd_write_cmd(EXTEND_SET); /扩展指令集 lcd_write_cmd(DRAW_OFF); /绘图显示关闭 lcd_write_cmd(0x80 + y_bit); /先写垂直地址(最高位必须为1) /具体参照数据手册 lcd_write_cmd(0x80 + x_byte + 8 * y_byte); /水平坐标 /下半屏的水平坐标起始地址为0x88 /(+8*y_byte)就是用来确定 /在上半屏还是下半屏lcd_read_data(); /先空读一次tmph = lcd_read_data(); /读高位tmpl = lcd_read_data();lcd_write_cmd(0x80 + y_bit); /读操作会改变AC,所以重新设置一次lcd_write_cmd(0x80 + x_byte + 8 * y_byte); if (x_bit 8) /如果x_bit位数小于8 lcd_write_data(tmph | (0x01 (7 - x_bit); /写高字节。因为坐标是从左向右的 /而GDRAM高位在左,底位在右 lcd_write_data(tmpl); /原数据送回 else lcd_write_data(tmph); /原数据送回 lcd_write_data(tmpl | (0x01 = 32 | (y 32 & y + height = 32) /要绘制的图案全部在上半屏或下半屏 for (i = 0; i height; i+) for (j = 0; j width / 16; j+) lcd_write_cmd(0x80 + y_bit + i); lcd_write_cmd(0x80 + x + j + y_byte * 8); /通过y_byte * 8 来选定上半屏或下半屏 lcd_write_data(*bmp+); lcd_write_data(*bmp+); else if (y 32) /要绘制的图案一半在上半屏,一半在下半屏 for (i = 0; i 32 - y; i+) /上半屏部分 for (j = 0; j width / 16; j+) lcd_write_cmd(0x80 + y_bit + i); lcd_write_cmd(0x80 + x + j); lcd_write_data(*bmp+); lcd_write_data(*bmp+); for (i = 0; i y + height - 32; i+) /下半屏部分 for (j = 0; j = 1; /x右移一位, 相当于 x / 2 /根据y的值算出对应的地址 if (y = 0) addr = 0x80 + x; else if (y = 1) addr = 0x90 + x; else if (y = 2) addr = 0x88 + x; else if (y = 3) addr = 0x98 + x; if (xx) /如果x % 2不为零, 说明数据在某一地址的低八位上 lcd_write_cmd(addr); /先写地址 lcd_read_data(); /空读一次 tmp = lcd_read_data(); /读出高八位数据 lcd_write_cmd(addr); /设置地址 lcd_write_data(tmp); /写原来高八位的数据 lcd_write_data(varh); /写变量的高位 lcd_write_data(var); /写变量的低位 else /数据在某地址上, 高八位一个数字, 低八位一个数字, 直接写入 lcd_write_cmd(addr); lcd_putc(varh); lcd_putc(var); return ; 我试着贴了一下软件生成的Html代码,给果出来效果不理想,还是贴文本吧。兼顾内存,效率等等因素,比较容易实现的是,任意坐标,任意高度,长度为8 的倍数。 譬如在坐标 17,17 处输出一幅 24*37的图片 /位图信息定义 typedef struct tagBitmap uint8 m_u8Width ; /宽度(必须为8的整数倍,取图片数据时注意!) uint8 m_u8Height ; /高度 prog_uchar* m_pBitmapCode ; BITMAP,*PBITMAP ; /显示位图 void ST7920ShowBitmap(uint8 u8X, uint8 u8Y,PBITMAP pBitmap) uint8 i,j; for(i = 0 ; i m_u8Height

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论