12864显示图形

合集下载

12864液晶图像显示图文教程——最全版

12864液晶图像显示图文教程——最全版

由图可以看到水平坐标一个单位是两字节(即 16 位 D15~D0),X 地址会自动加 1,是直接加一个单位 (即两字节 16 位),比如 0001(也即 0X80+000X80+01),从第一行第一列跳到第一行第二列。 代码: void display_image(uchar *p) { uchar i,j; write_cmd(0x34);//扩充指令集动作 write_cmd(0x34);//关绘图显示功能 /*上半屏显示设置*/ for(i=0;i<32;i++)//上半屏 { write_cmd(0x80+i);//垂直地址 write_cmd(0x80); //水平地址 for(j=0;j<16;j++) { write_data(*p);//连续写入 16 个字节 p++; } } /*下半屏半屏显示设置*/ for(i=0;i<32;i++)//下半屏 { write_cmd(0x80+i);//垂直地址 write_cmd(0x88);//水平地址 for(j=0;j<16;j++)//连续写入 16 个字节 { write_data(*p); p++; } } write_cmd(0x36);//开绘图显示 write_cmd(0x30);//回到基本指令集 } 源程序: #include <reg52.h> #include "12864.h" X 坐标(水平)方向以 2 字节 Byte 为单位,Y 坐标(垂直) 方向以 1 位 Bit 为单位,先连续写入垂直与水平坐标,再写入 两字节数据到 GDRAM。 这里是这样进行的:i=0 时,j=0,1 时,写入两字节到垂直 (0X80+00)水平(0X80+00)这格(D15~D0)里;然后 X 坐标地址自增 1, 地址变为垂直 (0X80+00) , 水平 (0X80+01) 这格,在 j=2,3 时写入两字节,………一直到垂直(0X80+00) 水平(0X80+07)这格,在 j=14,15 时写入两字节,此时循环 for(j=0;j<16;j++)结束跳出,刚好第一行 128 位写完数据;然后 i++,开始写第二行……

12864中文图形点阵液晶显示模块使用说明书

12864中文图形点阵液晶显示模块使用说明书

72us
读出 RAM
的值
1 1 D7
D6
D5
D4
D3
D2
D1
D0
从 内 部 RAM 读 取 数 据 (DDRAM/CGRAM/GDRAM)
72us
指令表 2:(RE=1:扩充指令集)
指令
指令码
RS RW DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
说明
执行 时间 (540K HZ)
功能:设定 CGRAM 地址到地址计数器(AC),需确定扩充指令中 SR=0(卷动地址或 RAM 地址选择)
地址
设定 CGRAM 地址到地址计数器(AC)
1 AC5 AC4 AC3 AC2 AC1 AC0 需确定扩充指令中 SR=0(卷动地址或 72us RAM 地址选择)
设定 DDRAM 0 0 1 AC6 AC5 AC4 AC3 AC2 AC1 AC0 设定 DDRAM 地址到地址计数器(AC) 72us
I/O
DB5
I/O
DB6
I/O
DB7
I/O
PSB
I
NC
-
/RST
I
VEE
-
LED+
-
LED-
-
说明
电源地
逻辑电源正(+5V)
LCD 对比度调节电压
并行模式时选择数据或指令
H: 数据 L: 指令
串行模式时选择模块与否
H: 选择 L: 不选择
并行模式时控制读写
H: 读
L: 写
串行模式时输入数据
并行模式时使能端
L
L
L
H
DL
X
RE
X

12864图片显示

12864图片显示

/************************************/ /* */ /* 12864图像显示程序*/ /* */ /************************************/#include<reg52.h>#include"qq.h"#define uchar unsigned char#define uint unsigned intsbit lcdrs=P2^4;sbit lcdrw=P2^5;sbit lcden=P2^6;/******************************函数名:delayus()功能:延时k微秒参数:k返回值:无*******************************/void delayus(uint k){while(k--);}/******************************函数名:delayms()功能:延时i微秒参数:i返回值:无*******************************//*void delayms(uint i){uchar j;for(i;i>0;i--)for(j=125;j>0;j--);}*//******************************函数名:lcd_wrcom()功能:12864写命令参数:lcd_com返回值:无*******************************/void lcd_wrcom(char lcd_com){uchar temp;lcdrs=0;lcdrw=1;do //12864判忙{lcden=1;temp=P0;delayus(6);lcden=0;}while(temp & 0x80);//不忙则退出循环lcdrw=0;P0=lcd_com; //写命令lcden=1;delayus(6);lcden=0;}/******************************函数名:lcd_wrdata()功能:12864写数据参数:lcd_dat返回值:无*******************************/void lcd_wrdata(char lcd_dat){uchar temp;lcdrs=0;lcdrw=1;do //12864判忙{lcden=1;temp=P0;delayus(6);lcden=0;}while(temp & 0x80); //第八位为判忙标志位lcdrs=1;P0=lcd_dat; //写数据lcden=1;delayus(6);lcden=0;}/******************************函数名:init_12864()功能:12864初始化参数:无返回值:无*******************************/void init_12864(){delayus(100); //延时100微秒lcd_wrcom(0x30);//功能设定delayus(5000);lcd_wrcom(0x02);//地址归位delayus(100);lcd_wrcom(0x0e);//显示状态delayus(100);lcd_wrcom(0x1c);//游标和显示的移位delayus(100);lcd_wrcom(0x01);//清屏delayus(5000); //延时5毫秒}/******************************函数名:clearGDRAM()功能:清除GDRAM参数:无返回值:无*******************************/void clearGDRAM(){uchar i,j,k;lcd_wrcom(0x34); //打开扩展指令集i = 0x80; //液晶纵向首地址0x80for(j = 0;j < 32;j++) //0x80,0x90两个汉字行共32个纵点(小方格){lcd_wrcom(i++); //纵向地址增1lcd_wrcom(0x80);for(k = 0;k < 32;k++)//横向80-8f(16个汉字)或90-9f每行32个字节lcd_wrdata(0x00);//每个字节都清零}}//也可以80,90各汉字行分开清零原理一样/* i = 0x80; //80行清零for(j = 0;j < 16;j++) //每行16个纵电(即16行小方格){lcd_wrcom(i++);lcd_wrcom(0x80);for(k = 0;k < 32;k++)//横向80-8f(16个汉字即16列){lcd_wrdata(0x00);}}i = 0x90; //90行清零90-9Ffor(j = 0;j < 16;j++){lcd_wrcom(i++);lcd_wrcom(0x80);for(k = 0;k < 32;k++){lcd_wrdata(0x00);}}*/lcd_wrcom(0x30); //返回基本指令集}/*******************************************函数名称:Draw_TX功能:显示一个16*16大小的图形参数:Yaddr--Y地址Xaddr--X地址dp--指向图形数据存放地址的指针返回值:无********************************************/void Draw_TX(uchar Yaddr,uchar Xaddr,const uchar *p){uchar j;uchar k=0;lcd_wrcom(0x34); //使用扩展指令集,关闭绘图显示for(j=0;j<16;j++){lcd_wrcom(Yaddr++); //Y地址16个纵点lcd_wrcom(Xaddr); //X地址横向地址可自增lcd_wrdata(p[k++]); //写入一个字(2字节)lcd_wrdata(p[k++]);}lcd_wrcom(0x36); //打开绘图显示lcd_wrcom(0x30); //回到基本指令集模式}/******************************函数名:draw_128*64()功能:显示128*64全屏图画参数:数组指针*point返回值:无*******************************/void draw_12864(uchar code *point){uchar i,j,k;lcd_wrcom(0x34); //打开扩展指令集i = 0x80; //分4屏写for(j = 0;j < 16;j++) //第一屏80-87(8个汉字宽度) {lcd_wrcom(i++); //纵向16个纵点lcd_wrcom(0x80); //横向地址可自增for(k = 0;k < 16;k++) //横向16个字节lcd_wrdata(*point++);}i = 0x90; //第二屏90-97for(j = 0;j < 16;j++){lcd_wrcom(i++);lcd_wrcom(0x80);for(k = 0;k < 16;k++)lcd_wrdata(*point++);}i = 0x80; //第三屏88-8ffor(j = 0;j < 16;j++){lcd_wrcom(i++);lcd_wrcom(0x88);for(k = 0;k < 16;k++)lcd_wrdata(*point++);}i = 0x90; //第四屏98-9ffor(j = 0;j < 16;j++){lcd_wrcom(i++);lcd_wrcom(0x88);for(k = 0;k < 16;k++)lcd_wrdata(*point++);}/* uchar i,j,k; //上下分两屏写(典型用法) lcd_wrcom(0x34); //打开扩展指令集i = 0x80; //80-87and90-97for(j = 0;j < 32;j++){lcd_wrcom(i++);lcd_wrcom(0x80);for(k = 0;k < 16;k++){lcd_wrdata(*point++);}}i = 0x80; //88-8f and 98-9ffor(j = 0;j < 32;j++){lcd_wrcom(i++);lcd_wrcom(0x88);for(k = 0;k < 16;k++){lcd_wrdata(*point++);}}*/lcd_wrcom(0x36); //打开绘图显示lcd_wrcom(0x30); //回到基本指令集}/******************************函数名:main()功能:调用显示图片参数:无返回值:无*******************************/void main(){/*uchar laba[]= //喇叭图代码{0x00,0x00,0x00,0xC0,0x01,0x48,0x02,0x44,0x04,0x52,0xF8,0x49,0x88,0x49,0x88,0x49, 0x88,0x49,0x88,0x49,0xF8,0x49,0x04,0x52,0x02,0x44,0x01,0x48,0x00,0xC0,0x00,0x00 };*/clearGDRAM(); //清除GDRAMlcd_wrcom(0x01); //清除DDRAMinit_12864(); //液晶初始化draw_12864(qq1); //qq图128*64// Draw_TX(0x86,0x96,laba);//喇叭图16*16while(1);}/****************************************************************************** *************感言:①、12864实际上只有80-8f和90-9f两行工艺上把(80-87、90-97)和(88-8f、98-9f)之间切下来做成两部分接在下半屏即有4行(80-87、90-97、88-8f、98-9f),所以清屏和写数据的时候要特别注意!②、画图的时候横向是算字节的,而纵向则算像素(小方格)。

12864显示文字+图像

12864显示文字+图像

引用12864液晶原理分析3他山之石2010-07-21 20:52:05 阅读7 评论0 字号:大中小小峰的12864液晶原理分析3一、ST7920控制IC的LCD12864实现反白显示从使用手册上可知,扩展指令里的0x03+行号即可实现反白对应行。

但是ST7920 控制器的128×64 点阵液晶其实原理上等同256×32 点阵,第三行对应的DDRAM 地址紧接第一行;第四行对应的DDRAM 地址紧接第二行。

所以128×64 点阵的液晶执行反白功能时实用意义不大,因为用户对第一行执行反白显示操作时,第三行必然也反白显示;第二行反白,第四行也必然反白。

其实还是有办法做到单行反白的,解决方法就是混用图形显示和字符显示。

其理论支持在于:在ST7920中,字符显示的DDRAM和图形的GDRAM是相互独立的,而最后显示到液晶上的结果,是两个RAM中数据的异或。

具体来说:假如某个点上,绘图RAM的没有绘图(数据为0),而字符RAM上有点阵(数据为1),那么异或的结果就是1,也就是说正常显示字符;当字符上RAM没有点阵的时候,异或的结果是0,自然也就不显示了。

假如该点上绘图RAM绘图了(数据为1),当字符RAM上有点阵(数据为1时),异或的结果为0,效果就是反白显示;如果字符RAM没有点阵(数据为0时),异或结果为1,效果就是显示绘图的背景。

所以,如果要在某个地方反白显示,那么就在该点绘图并且写字,如果要取消反白,就重新用全0擦掉那个地方的绘图!这样一来可以实现任何地方、任意大小的反白显示,反而比原指令中的单行反白的功能更好更强大。

二、对于整屏既有图象又有文本,则可以用两种方式实现:1、首先文本DDRAM写入要写的字符,其余全部空格(即0X00),然后再在没有字符的地方(即非点亮的晶格中,0X00)绘入图象。

DDRAM与GDRAM异或后就可以整屏实现图象与文本。

参见程序实例1。

12864显示图形和文字

12864显示图形和文字
/****** 返回值 : 无 ******/
/*******************************************************/
void lcd_out(unsigned char send_byte)
/*******************************************************/
void lcd_control()
{
WR_control(0x30);
WR_control(0x0C);
}
/*******************************************************/
/****** 参 数: 无 ******/
/****** 返回值 : 无 ******/
/*******************************************************/
{
bcd &= 0x0F;
if(bcd > 9)
bcd +=('7'); // 将A~F转换为ASCII
else
bcd += '0'; // 将0~9转换为ASCII 0~9
return(bcd);
{
unsigned char i,s;
for (i=0;i<8;i++)
{
if((send_byte&0x80)==0)
{
LCD_DATAL;
}
else
{
LCD_DATAH;
} //送数据

LCD12864显示图形程序

LCD12864显示图形程序

COM
EQU 20H ;指令数据寄存器
DAT
EQU 21H ;显示数据寄存器
;********************************变量定义结束**********************************
;*********************************程序开始************************************
指令和数据;BF=0时,模块为准备状态,随时可接受外部指令和数据。利用状态 读指令,可以将BF读到DB7总线,从而检验LCD的工作状态 4. 显示控制触发器DFF
此触发器是用于模块屏幕显示开和关的控制。DFF=1为开显示,DISPLAY OFF DDRAM的内容就显示在屏幕上;DFF=0为关显示。DISPLAY OFF DDRAM的状态是指 令显示ON/OFF和RST信号控制的。 5. XY地址计数器
2.2 程序功能
LCD 会每隔 1 秒显示一个画面,共 3 个画面,一直循环下去。 第 1 秒:
第 2 秒: 第 3 秒:
8
嵌入式应用软件园,版权所有,请勿转载/销售。
第 3 章程序代码
3.1 文本版代码
我们的辛勤付出,需要您的肯定,请访问: 嵌入式应用软件园。
;******************************************************************************
第 3 章程序代码 .....................................................................................9 3.1 文本版代码 ................................................................................ 9 3.2 图片版代码 .............................................................................. 21

液晶12864显示图片

液晶12864显示图片

液晶12864显示图片液晶12864简介12864是128*64点阵液晶模块的点阵数简称。

基本参数1、低电源电压(VDD:+3.0~+5.5V)。

2、显示分辨率:128×64 点。

3、内置汉字字库,提供8192 个16×16 点阵汉字。

4、内置128 个16×8 点阵字符。

5、2MHZ 时钟频率。

6、显示方式:STN、半透、正显。

7、驱动方式:1/32DUTY,1/5BIAS。

8、视角方向:6 点。

9、背光方式:侧部高亮白色LED。

10、通讯方式:串行、并口可选。

11、内置DC-DC 转换电路,无需外加负压。

12、无需片选信号,简化软件设计。

13、工作温度: 0℃~+55℃ ,存储温度: -20℃~+60℃。

液晶12864接口液晶12864显示图片程序源代码/*******************12864显示图片******************** 处理器:51单片机* 开发环境:keil* 功能:12864显示图片****************************************************/#include <reg51.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned int/*12864端口定义 */#define LCD_data P0 //数据口sbit LCD_RS = P1^0; //寄存器选择输入sbit LCD_RW = P1^1; //液晶读/写控制sbit LCD_EN = P2^5; //液晶使能控制sbit LCD_PSB = P1^2; //串/并方式控制unsigned char code zhu[]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFE,0x7D,0x7F,0xFF,0xFF,0xFF,0xFD,0xEF,0xFF,0xF0,0x04,0x3F,0xFF, 0xFF,0xFF,0xFF,0xFD,0xBD,0x7F,0xFF,0xFF,0xFF,0xE6,0xE7,0xFF,0xF4,0x00,0x7F,0xFF, 0xFF,0xFF,0xFF,0xFD,0x3D,0x7F,0xFF,0xFF,0xFF,0xDE,0x00,0xFF,0xF0,0x00,0x7F,0xFF, 0xFF,0xFF,0xFF,0xC4,0x3E,0x7F,0xFF,0xFF,0xFF,0xA8,0x00,0x1F,0xF0,0x00,0x7F,0xFF, 0xFF,0xFF,0xFF,0xBA,0x46,0x7F,0x7F,0xFF,0xFF,0x70,0x00,0x0E,0xF0,0x00,0xFF,0xFF, 0xFF,0xFF,0xFF,0x7D,0xBB,0x5F,0x7F,0xFF,0xFE,0xE1,0x70,0x01,0xF0,0x00,0xFF,0xFF, 0xFF,0xFF,0xFF,0x7D,0xA3,0xEF,0x9F,0xFF,0xFF,0x06,0xF8,0x03,0xF0,0x00,0xFF,0xFF, 0xFF,0xFF,0xF0,0x7C,0x07,0xB6,0x07,0xFF,0xFF,0xCC,0xF9,0x81,0xF0,0x01,0xFF,0xFF, 0xFF,0xFF,0xEF,0x75,0xDF,0xB8,0x01,0xFF,0xFF,0x98,0xF9,0x80,0xF1,0xF1,0xEF,0xFF, 0xFF,0xFF,0xEF,0x6D,0xEF,0x58,0xE0,0xFF,0xFF,0x90,0x70,0x00,0xF3,0xFB,0xFF,0xFF, 0xFF,0xFF,0xEF,0xBB,0xEE,0xD9,0xF0,0xFF,0xFF,0xB0,0x0C,0x00,0x73,0x1B,0xAF,0xFF, 0xFF,0xFF,0xF7,0x87,0xAE,0xC2,0xF0,0x7F,0xFF,0xE0,0x0C,0x62,0x36,0xFD,0xFF,0xFF, 0xFF,0xFF,0xF0,0x33,0xDD,0xD2,0x60,0x7F,0xFF,0xE0,0x31,0x61,0x76,0xFD,0xEF,0xFF, 0xFF,0xFF,0xEF,0xA0,0x3B,0xF4,0x18,0x3F,0xFF,0xE0,0x30,0x09,0x6C,0x3D,0xFF,0xFF, 0xFF,0xFF,0xDF,0x83,0xB6,0xA5,0x98,0x3F,0xFF,0xE0,0x00,0x01,0x7B,0xDD,0xAF,0xFF, 0xFF,0xFF,0xDE,0x83,0xCF,0xED,0x80,0x3F,0xFF,0xE0,0x00,0x01,0xFA,0xDD,0xFF,0xFF, 0xFF,0xFF,0xDD,0x7B,0xDE,0xF4,0x00,0x3F,0xFF,0xE0,0x00,0x09,0xFB,0xDD,0xEF,0xFF, 0xFF,0xFF,0xEE,0x5B,0xDF,0xF4,0x00,0x3F,0xFF,0xF0,0x00,0x29,0xF9,0xBB,0xFF,0xFF, 0xFF,0xFF,0xF1,0x79,0xBE,0xB4,0x00,0x3F,0xFF,0xF0,0x00,0x33,0xFF,0xFA,0xAF,0xFF, 0xFF,0xFF,0xEF,0x68,0x03,0xF8,0x00,0x3F,0xFF,0xF8,0x0F,0xE3,0xFF,0xF7,0xFF,0xFF, 0xFF,0xFF,0xDF,0x70,0x16,0xEA,0x01,0x3F,0xFF,0xF8,0x1F,0xC7,0xEF,0xF6,0xEF,0xFF, 0xFF,0xFF,0x07,0x80,0x0F,0xFA,0x1D,0x7F,0xE0,0x3C,0x7F,0x87,0xEF,0xEF,0xFF,0xFF, 0xFF,0xFF,0x0B,0xA0,0x2A,0xB6,0x1E,0x70,0x1F,0xBF,0x3E,0x0F,0xD3,0x9A,0xAF,0xFF, 0xFF,0xFF,0x85,0xA0,0x5F,0xF7,0x3C,0xF7,0xE0,0x3C,0x00,0x3F,0xDC,0x7F,0xFF,0xFF, 0xFF,0xFF,0x41,0x11,0x2E,0xF6,0x81,0xF8,0x00,0x3F,0x00,0xFF,0xAF,0x8E,0xEF,0xFF, 0xFF,0xFF,0x94,0xA0,0xFF,0xF7,0xFF,0xF8,0x00,0x3F,0xFF,0x1F,0xBF,0x77,0xFF,0xFF, 0xFF,0xFF,0xE2,0x3F,0xAA,0xB7,0x8B,0xFC,0x00,0x3F,0xDF,0xDF,0x6A,0xFA,0xAF,0xFF, 0xFF,0xFF,0x88,0x01,0xFF,0xFB,0x75,0xFC,0x00,0x3F,0xDF,0xBE,0xFE,0xFB,0xFF,0xFF, 0xFF,0xFF,0x40,0x00,0x3E,0xEB,0xB7,0xFE,0x00,0x3F,0xE0,0x7C,0x78,0xFB,0xF7,0xFF, 0xFF,0xFF,0x00,0x00,0x0F,0xFD,0xC7,0xFE,0x01,0xBF,0xFF,0xFA,0xA7,0x70,0x6F,0xFF, 0xFF,0xFF,0x0F,0xBF,0x0A,0xAA,0xFF,0xFE,0x0F,0xBF,0xFF,0xE7,0xCF,0x8F,0xAF,0xFF, 0xFF,0xFF,0x47,0x5E,0x2F,0xFF,0x7F,0xFF,0x1F,0xBF,0xFF,0xDF,0xEF,0x8F,0xAF,0xFF, 0xFF,0xFF,0x38,0x21,0xDE,0xEE,0x9F,0xFF,0xBF,0x7F,0xFF,0x3F,0xEF,0x0F,0xB7,0xFF, 0xFF,0xFF,0x07,0xD6,0x2F,0xFF,0xE7,0xFF,0xC0,0xFF,0xFC,0xFF,0xF0,0xEF,0xBF,0xFF, 0xFF,0xFF,0x41,0x8C,0xCA,0xBA,0xB9,0xFF,0xFF,0xFF,0xE3,0xFF,0xFD,0xF0,0x6F,0xFF, 0xFF,0xFF,0x93,0xCC,0xDF,0xFF,0xFE,0x3F,0xFF,0xFE,0x00,0x7F,0xFD,0xF7,0x7F,0xFF, 0xFF,0xFF,0x40,0x03,0x2E,0xEE,0xEF,0xC2,0x03,0xC0,0xFF,0x9F,0xFD,0xF7,0xAF,0xFF, 0xFF,0xFF,0xC0,0x03,0x3F,0xFF,0xFF,0xF9,0xFC,0x37,0xFF,0xE3,0xFE,0xE7,0xDF,0xFF, 0xFF,0xFF,0xD1,0xCC,0xFB,0xBB,0xBB,0xE7,0xFF,0x8F,0xFF,0xFC,0x3E,0x17,0xDF,0xFF,0xFF,0xFF,0xC0,0x8C,0xFF,0xFF,0xFF,0x9F,0xFF,0xDF,0xFF,0xFF,0xC6,0xF7,0xEF,0xFF,0xFF,0xFF,0xC0,0x90,0x2F,0xEF,0xEE,0x7F,0xFF,0xBF,0xFF,0xFF,0xF9,0xFB,0xF7,0xFF,0xFF,0xFF,0xC0,0xA0,0x3F,0xFF,0xF9,0xDF,0xFF,0xBF,0xFF,0xDF,0xFE,0xFB,0xFF,0xFF,0xFF,0xFF,0x10,0xC0,0x08,0x00,0x00,0x0F,0xFF,0xBF,0xFF,0x80,0x00,0x00,0x07,0xFF,0xFF,0xFF,0xE8,0x80,0x7F,0xFF,0xFF,0xF3,0xFF,0xBF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE1,0xC0,0x7F,0xFF,0xFF,0xFC,0x7E,0x5F,0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF0,0x00,0xFF,0xFF,0xFF,0xFF,0x81,0xE0,0x07,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};#define delayNOP0(); {_nop_();_nop_();};#define delayNOP1(); {_nop_();_nop_();_nop_();_nop_();};void delay(int In,int Out) {int i,j;for(i=0;i<In;i++){for(j=0;j<Out;j++){;}}}/*******************************************************************//*检查LCD忙状态 *//*lcd_busy为1时,忙,等待。

12864显示图形中上半屏和下半屏

12864显示图形中上半屏和下半屏

最近买了一块12864液晶显示屏,淘宝给我的资料不算多,我就从网上下载了部分资料,通过研究别人的例程我发现了一些问题,并得出了自己的见解。

写程序一定要严谨,同时又要求精练,如果程序中多了些没用的语句不仅让学习的人看的一头雾水,而且又占用多余的空间,我想通过自己的实践来鄙视那些程序不严谨就挂到网上的人,给初学者很多困惑。

我就通过12864的绘图功能来说下,不对之处望求指正(附上绘图说明)12864(ST7920驱动芯片)把屏幕分成上下两部分(如上图中把垂直坐标分成了两部分的00~1F)。

水平坐标00到0F处于同一面,而不是上下屏的关系,[上半屏“07”后通过我标注的箭头连接是到下一个红色00行]。

在向GDRAM中写入要显示的图片时,我们先指定从X:00、Y:00处(也就是第①处)开始写入数据,我们先在第①处写图形数据(按照图片所标注,第15位在最左边,第0位在最右边,即在写入的时候LCD会先写高位字节,接着再写低位字节),接着LCD会自动把坐标定位到同一行第②处的开头,此时我们可以接着告诉LCD在这里写入图形数据,依此类推,当我们写满16次后,第00行(包括上半屏和下半屏的)就全写满了。

那么我们接下去写入数据会出现什么情况呢?接着LCD又自动从第00行的第①处重新开始写了。

这是因为ST7920控制芯片设计出来就这样,在写入的时候它只会在水平方向(X轴上)地址自增,并且在增加到0F地址之后就会变成00地址从头开始写。

从这里我们可以明白,每次写满一行(共16部分)后就必须在程序里人为地把垂直方向(Y轴)的地址加1,不然就会造成只是在同一行重复写入的现象。

垂直(列)地址由AC6~AC0指定,共32行,列地址由AC3AC2AC1AC0指定,共16列(00-0F),绘图程序如下:通过以上所讲我想大家也明白了很多了吧,我看网上有很多教程说是要把屏幕分开两半来写程序,其实我觉得下半屏程序根本没必要再写出来,因为见上面的分析过程,其实“上半部分屏”程序已经完全把整个屏幕覆盖了,而下半部分屏相当于在原来的基础上又重新覆盖了一部分。

12864液晶显示图片原理(完整版)

12864液晶显示图片原理(完整版)

51单片机综合学习12864液晶原理分析1辛勤学习了好几天,终于对12864液晶有了些初步了解~没有视频教程学起来真有些累,基本上内部程序写入顺序都是根据程序自我变动,然后逆向反推出原理……芯片:YM12864R P-1 控制芯片:ST7920A 带中文字库初步小结:1、控制芯片不同,寄存器定义会不同2、显示方式有并行和串行,程序不同3、含字库芯片显示字符时不必对字符取模了4、对芯片的结构地址一定要理解清楚5、显示汉字时液晶芯片写入数据的顺序(即显示的顺序)要清楚6、显示图片时液晶芯片写入数据的顺序(即显示的顺序)要清楚7、显示汉字时的二级单元(一级为八位数据写入单元)要清楚8、显示图片时的二级单元(一级为八位数据写入单元)要清楚 12864点阵液晶显示模块(LCM)就是由128*64个液晶显示点组成的一个128列*64行的阵列。

每个显示点对应一位二进制数,1表示亮,0表示灭。

存储这些点阵信息的RAM 称为显示数据存储器。

要显示某个图形或汉字就是将相应的点阵信息写入到相应的存储单元中。

图形或汉字的点阵信息由自己设计,问题的关键就是显示点在液晶屏上的位置(行和列)与其在存储器中的地址之间的关系。

由于多数液晶显示模块的驱动电路是由一片行驱动器和两片列驱动器构成,所以12864液晶屏实际上是由左右两块独立的64*64液晶屏拼接而成,每半屏有一个512*8 bits显示数据RAM。

左右半屏驱动电路及存储器分别由片选信号CS1和CS2选择。

显示点在64*64液晶屏上的位置由行号(line,0~63)与列号(column,0~63)确定。

512*8 bits RAM中某个存储单元的地址由页地址(Xpage,0~7)和列地址(Yaddress,0~63)确定。

每个存储单元存储8个液晶点的显示信息。

为了使液晶点位置信息与存储地址的对应关系更直观关,将64*64液晶屏从上至下8等分为8个显示块,每块包括8行*64列个点阵。

[原创]12864 LCD图形显示程序例子

[原创]12864 LCD图形显示程序例子

这是一个在LCD128*64上显示图形的一个程序,一直以来都总是不知道怎么搞,现在终于都通了,想当初在网上总找,要不是程序不全,就是无法运行,或者是C51汇编语言,让人不爽,这样的痛苦不可以再让别人难受了。

在LCD上显示一幅图,是“我的电脑,我的文档”。

IC用PIC16F877A,晶振4MHZ,采用并行8线,LCD:TS12864-3,接法在程序中有定义,只要将此程序COPY到你的PICC里编译下载后,在目标板上即可以看到图画了!不知道可不可以加酷?#include "pic.h"#define RS RC0#define RW RC1#define E RC2#define PSB RC3#define RST RC4//PORTD=DATA;unsigned char COUNT3,COUNT2,COUNT1,COUNT,LCD_X,LCD_Y,LCD_DATA1,LCD_D ATA2,LCD_DATA,F3,R1,F0;const unsigned char TU_TAB1[]={// 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 10xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0 x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0 x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0 x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0 x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0 x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xFF,0xF0,0x00,0 x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x18,0x00,0 x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xBF,0xFF,0xDC,0x00, 0x01,0x80,0x00,0x1F,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0xBF,0xFF,0xBC,0x00,0 x01,0x80,0x00,0x30,0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x01,0x7F,0xFF,0xB8,0x00,0 x01,0x80,0x00,0x30,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x01,0x7F,0xFF,0x78,0x00,0 x01,0x80,0x00,0x19,0xFF,0xFE,0xC0,0x00,0x00,0x00,0x00,0x02,0xFF,0xFF,0x70,0x00,0 x01,0x80,0x00,0x18,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x02,0xFF,0xFE,0xF0,0x00,0 x01,0x80,0x00,0x0C,0x01,0xFF,0x60,0x00,0x00,0x00,0x00,0x05,0xFF,0xFE,0xE0,0x00, 0x01,0x80,0x00,0x0C,0x7F,0xD0,0x20,0x00,0x00,0x00,0x00,0x05,0xFF,0xFD,0xE0,0x00,0x 01,0x80,0x00,0x06,0x00,0x0F,0xB0,0x00,0x00,0x00,0x00,0x0B,0xFF,0xFD,0xC0,0x00,0x 01,0x80,0x00,0x06,0x03,0xFC,0x10,0x00,0x00,0x00,0x00,0x0B,0xFF,0xFB,0xC0,0x00,0x 01,0x80,0x00,0x03,0x1F,0x00,0x18,0x00,0x00,0x00,0x00,0x17,0xFF,0xFB,0x80,0x00,0x0 1,0x80,0x00,0x03,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x17,0xFF,0xF7,0x80,0x00,0x0 1,0x80,0x00,0x01,0x80,0x00,0x0C,0x00,0x00,0x00,0x00,0x17,0xFF,0xF7,0x00,0x00,0x 01,0x80,0x00,0x01,0x80,0x00,0x04,0x00,0x00,0x00,0x00,0x09,0xFF,0xEF,0x00,0x00,0x0 1,0x80,0x00,0x00,0xC0,0x00,0xF6,0x00,0x00,0x00,0x00,0x06,0x7F,0xEE,0x00,0x00,0x 01,0x80,0x00,0x00,0xC0,0x03,0xC2,0x00,0x00,0x00,0x00,0x01,0x9F,0xDE,0x00,0x00,0x 01,0x80,0x00,0x00,0x60,0x00,0x3B,0x00,0x00,0x00,0x00,0x00,0x67,0xDF,0x00,0x00,0x 01,0x80,0x00,0x00,0x60,0x00,0xE3,0x00,0x00,0x00,0x00,0x00,0x19,0xBF,0x00,0x00,0x 01,0x80,0x00,0x00,0x30,0x03,0x8E,0x00,0x00,0x00,0x00,0x00,0x06,0x3F,0x00,0x00,0x0 1,0x80,0x00,0x00,0x30,0x06,0x3C,0x00,0x00,0x00,0x00,0x00,0x01,0xFF,0x00,0x00,0x 01,0x80,0x00,0x00,0x18,0x00,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x0 1,0x80,0x00,0x00,0x18,0x03,0xC0,0x00,0x00,0x00,0x00,0x00,0x0F,0x7F,0x80,0x00,0x0 1,0x80,0x00,0x00,0x0C,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x1F,0xC0,0x00,0 x01,0x80,0x00,0x00,0x0C,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x07,0xE0,0x00,0x 01,0x80,0x00,0x00,0x06,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x1F,0xE0,0x00,0x 01,0x80,0x00,0x00,0x07,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x3F,0xC0,0x00,0x 01,1,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xFC,0x00,0x00,0x 01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xF0,0x00,0x00,0x0 1,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xC0,0x00,0x00,0x 01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0 1,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0 1,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0 1,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0 1,0x80,0x05,0x40,0x88,0x04,0x01,0x08,0x00,0x00,0x0A,0x81,0x10,0x04,0x00,0x20,0x0 1,0x80,0x79,0x21,0x08,0x02,0x21,0x49,0x00,0x00,0xF2,0x42,0x10,0x04,0x47,0x10,0x0 1,0x80,0x09,0x07,0xDF,0x7F,0xF7,0xAA,0x00,0x00,0x12,0x0F,0xBE,0x7F,0xE5,0xFE,0 x01,0x80,0x7F,0xF4,0x51,0x08,0x81,0x2C,0x00,0x00,0xFF,0xE8,0xA2,0x44,0x47,0x00,0x 01,0x80,0x09,0x04,0x61,0x08,0x81,0x7F,0x00,0x00,0x12,0x08,0xC2,0x7F,0xC5,0x4A,0x 01,0x80,0x0B,0x24,0x51,0x08,0x83,0x81,0x00,0x00,0x16,0x48,0xA2,0x44,0x45,0x6A,0x 01,0x80,0x1D,0x47,0xC9,0x05,0x05,0x01,0x00,0x00,0x3A,0x8F,0x92,0x44,0x47,0x52,0x 01,0x80,0x68,0x84,0x49,0x05,0x05,0x7F,0x00,0x00,0xD1,0x08,0x92,0x7F,0xC5,0x6A,0x 01,0x80,0x09,0x94,0x41,0x02,0x01,0x01,0x00,0x00,0x13,0x28,0x82,0x44,0x05,0x4A,0 x01,0x80,0x0E,0x57,0xC1,0x0D,0x81,0x01,0x00,0x00,0x1C,0xAF,0x82,0x04,0x29,0x42,0x 01,0x80,0x38,0x34,0x4E,0x70,0x71,0x7F,0x00,0x00,0x70,0x68,0x9C,0x03,0xEB,0x7E, 0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0 x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0 x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0 x01,x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0 x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0 x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0 x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0 x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0 x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0 x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0 xFF};//*************delay_ms********************************void delay_10us(unsigned char x){while(x--);}void delay_ms(unsigned char cnt){unsigned char i;do {i = 4;do {delay_10us(39);} while(--i);} while(--cnt);}//***********检查是否LCD忙碌的子程序**********************void check_busy(void){TRISD=0xff;//在此处设为输入。

12864图形显示函数要点

12864图形显示函数要点

/****************************************************************************** ******************************************************************************* *********///程序说明:本程序为12864(st7920)驱动程序,只实现了最简单的显示功能//端口设置:RS、RW、EN分别为P0口的0、1、2,数据口为P2口//用取模软件取的图形或汉字必须是逐行取的,因为本函数是在液晶上逐行打点的/****************************************************************************** ******************************************************************************* ********/#include<reg51.h>#include<intrins.h> //内含-NOP-函数#include<stdlib.h> //内含rand()函数#define uchar unsigned char#define uint unsigned int//**********宏定义所需指令#define BASIC_SET 0x30#define EXTEND_SET 0x34#define DRAW_ON 0x36#define DRAW_OFF 0x34//*************端口定义sbit LCD_RS = P0^0;sbit LCD_RW = P0^1;sbit LCD_EN = P0^2;//************变量定义//uchar dis1[10];//读出缓存unsigned char tu[];//****************短延时void delay(uint k){uint i;uchar j;for(i = 0; i < k ;i ++)for(j = 0; j < 10 ;j ++);}//***********ms级延时函数/*void delay_1ms(uint x){uint i,j;for(j = 0;j < x; j++)for(i = 0;i < 110; i++);} *///***********12864写指令函数void write_com(uchar cmd){LCD_RS = 0;LCD_RW = 0;delay(5);LCD_EN = 1;P2 = cmd;delay(5);LCD_EN = 0;}//********12864写数据函数void write_dat(uchar dat){LCD_RS = 1;LCD_RW = 0;delay(5);LCD_EN = 1;P2 = dat;delay(5);LCD_EN = 0;}//****************从LCD中读数据uchar read_dat(void){uchar temp;P2 = 0XFF; //释放数据线LCD_RS = 1; //数据LCD_RW = 1; // 读模式LCD_EN = 1; //E为高电平进行读数据或指令delay(1);temp = P2;LCD_EN = 0;return temp;}//********************************************************//设置光标(地址)函数//参数说明:x---为行号,y为列号//********************************************************void set_cursor(unsigned char x, unsigned char y){unsigned char i;switch(x) //确定行号{case 0x00: i=0x80; break; //第一行case 0x01: i=0x90; break; //第二行case 0x02: i=0x88; break; //第三行case 0x03: i=0x98; break; //第四行default : break;}i = y+i; //确定列号write_com(i);}//********************************************************//显示字符函数//********************************************************/*void display_char(unsigned char Alphabet){write_dat(Alphabet); //写入需要显示字符的显示码} *///********************************************************//指定位置显示字符串函数//参数说明:x为行号,y为列号//********************************************************/*void display_string(unsigned char x,unsigned char y,unsigned char *Alphabet) {unsigned char i=0;set_cursor(x,y); //设置显示的起始地址while(Alphabet[i]!='\0'){write_dat(Alphabet[i]); //写入需要显示字符的显示码i++;}} *///***************************************************************************以下为GDRAM绘图部分************************************************************************////*********************绘图显示的清屏函数(因清屏指令在画图时不能用)------------------------------------------------------------------------------注意!!!!!!!void gui_clear(){uchar i , j , k;write_com(EXTEND_SET);//扩展指令集,8位数据传输write_com(DRAW_OFF);//绘图显示关闭for(i = 0; i < 2; i ++)//分上下两屏写{for(j = 0; j < 32; j ++){write_com(0x80 + j);//写y坐标delay(1);if(i == 0) //写x坐标{write_com(0x80);delay(1);}else //写下半屏{write_com(0x88);delay(1);}for(k = 0; k < 16; k ++)//写一整行数据{// write_dat(0x00);//写高字节// write_dat(0x00);//写低字节delay(10);}}}write_com(DRAW_ON);//打开绘图显示write_com(BASIC_SET);//打开基本指令集}//************************************************************************////*********************清内部RAM************************//void clrgdram(){unsigned char x,y ;for(y=0;y<64;y++)for(x=0;x<16;x++){write_com(0x34);write_com(y+0x80);//行地址write_com(x+0x80);//列地址write_com(0x30);write_dat(0x00);write_dat(0x00);}}//***************************************************************************** ********************//***************有反白显示功能的打点函数**********************************************************//参数:color=1,该点填充1;color=0,该点填充白色0;//***************************************************************************** ********************void GUI_Point(unsigned char x,unsigned char y,unsigned char color){unsigned char x_Dyte,x_byte; //定义列地址的字节位,及在字节中的哪1位unsigned char y_Dyte,y_byte; //定义为上下两个屏(取值为0,1),行地址(取值为0~31)unsigned char GDRAM_hbit,GDRAM_lbit;write_com(0x36); //扩展指令命令//***X,Y坐标互换,即普通的X,Y坐标**x_Dyte=x/16; //计算在16个字节中的哪一个x_byte=x&0x0f; //计算在该字节中的哪一位y_Dyte=y/32; //0为上半屏,1为下半屏y_byte=y&0x1f; //计算在0~31当中的哪一行write_com(0x80+y_byte); //设定行地址(y坐标),即是垂直地址write_com(0x80+x_Dyte+8*y_Dyte); //设定列地址(x坐标),并通过8*y_Dyte选定上下屏,即是水平地址read_dat(); //预读取数据GDRAM_hbit= read_dat(); //读取当前显示高8位数据GDRAM_lbit= read_dat(); //读取当前显示低8位数据delay(1);write_com(0x80+y_byte); //设定行地址(y坐标)write_com(0x80+x_Dyte+8*y_Dyte); //设定列地址(x坐标),并通过8*y_Dyte选定上下屏delay(1);if(x_byte<8) //判断其在高8位,还是在低8位{if(color==1){write_dat(GDRAM_hbit|(0x01<<(7-x_byte))); //置位GDRAM区高8位数据中相应的点}elsewrite_dat(GDRAM_hbit&(~(0x01<<(7-x_byte)))); //清除GDRAM区高8位数据中相应的点write_dat(GDRAM_lbit); //显示GDRAM区低8位数据}else{write_dat(GDRAM_hbit);if(color==1)write_dat(GDRAM_lbit|(0x01<<(15-x_byte))); //置位GDRAM区高8位数据中相应的点elsewrite_dat(GDRAM_lbit&(~(0x01<<(15-x_byte))));//清除GDRAM区高8位数据中相应的点}write_com(0x30); //恢复到基本指令集}//***********(给定坐标并打点的)任意位置打点函数/*void lcd_set_dot(uchar x,uchar y){uchar x_byte,x_bit;//确定在坐标的那一字节哪一位uchar y_ping , y_bit;//确定在坐标的哪一屏哪一行uchar tmph , tmpl;//定义两个临时变量,用于存放读出来的数据write_com(EXTEND_SET);//扩展指令集write_com(DRAW_OFF);//绘图显示关闭x_byte = x / 16;//算出在哪一字节,注意一个地址是16位的x_bit = x % 16;//& 0x0f;//算出在哪一位y_ping = y / 32;//确定在上半屏还是下半屏,0代表上半屏,1代表下半屏y_bit = y % 32;//& 0x1f;//确定在第几行write_com(0X80 + y_bit);//先写垂直地址(最高位必须)write_com(0x80 + x_byte + 8 * y_ping);//水平坐标,下半屏坐标起始地址为0x88,(+8*y_ping)就是用来确定上半屏还是下半屏read_dat();//预读取数据tmph = read_dat();//读取当前显示高8位数据tmpl = read_dat();//读取当前显示低8位数据delay(1);write_com(0x80 + y_bit);//读操作会改变AC,所以重新设置一下write_com(0x80 + x_byte + 8 * y_ping);delay(1);if(x_bit < 8){write_dat(tmph | (0x01 << (7 - x_bit)));//写高字节,因为坐标是从左向右的,GDRAM 高位在左,低位在右write_dat(tmpl);//原低位数据送回}else{write_dat(tmph);//原高位数据送回write_dat(tmpl | (0x01 << (15 - x_bit)));}write_com(DRAW_ON); //打开绘图显示write_com(BASIC_SET);//回到基本指令集} *///************画水平线函数**********************************////x0、x1为起始点和终点的水平坐标,y为垂直坐标***************////**********************************************************///*void gui_hline(uchar x0, uchar x1, uchar y){uchar bak;//用于对两个数互换的中间变量,使x1为大值if(x0 > x1){bak = x1;x1 = x0;x0 = bak;}do{lcd_set_dot(x0 , y);//从左到右逐点显示x0 ++;}while(x1 >= x0);} *///***********画竖直线函数***********************************// //x为起始点和终点的水平坐标,y0、y1为垂直坐标***************// //**********************************************************// /*void gui_rline(uchar x, uchar y0, uchar y1){uchar bak;//用于对两个数互换的中间变量,使y1为大值if(y0 > y1){bak = y1;y1 = y0;y0 = bak;}do{lcd_set_dot(x , y0);//从上到下逐点显示y0 ++;}while(y1 >= y0);} *///*********任意两点间画直线*********************************// //x0、y0为起始点坐标,x1、y1为终点坐标**********************// //**********************************************************// /*void gui_line(uchar x0 , uchar y0 , uchar x1 , uchar y1){char dx;//直线x轴差值char dy;//直线y轴差值char dx_sym;//x轴增长方向,为-1时减值方向,为1时增值方向char dy_sym;//y轴增长方向,为-1时减值方向,为1时增值方向char dx_x2;//dx*2值变量,用于加快运算速度char dy_x2;//dy*2值变量,用于加快运算速度char di; //决策变量if(x0 == x1)//判断是否为垂直线{gui_rline(x0 , y0 , y1);//画垂直线return;}if(y0 == y1)//判断是否为水平线{gui_hline(x0 , x1 , y0);//画水平线return;}dx = x1 - x0;//求取两点之间的差值dy = y1 - y0;//判断增长方向,或是否为水平线、垂直线、点if(dx > 0)//判断x轴方向dx_sym = 1;else{if(dx < 0)dx_sym = -1;else{gui_rline(x0 , y0 , y1);return;}}if(dy > 0)//判断y轴方向dy_sym = 1;else{if(dy < 0)dy_sym = -1;else{gui_hline(x0 , x1 , y0);return;}}//*将dx、dy取绝对值**********dx = dx_sym * dx;dy = dy_sym * dy;//****计算2倍的dx、dy值******dx_x2 = dx * 1;//我改为了一倍,这样才跟真实的两点对应dy_x2 = dy * 1;//***使用bresenham法进行画直线***if(dx >= dy)//对于dx>=dy,使用x轴为基准{di = dy_x2 - dx;while(x0 != x1){lcd_set_dot(x0,y0);x0 +=dx_sym;if(di < 0)di += dy_x2;//计算出下一步的决策值else{di += dy_x2 - dx_x2;y0 += dy_sym;}}lcd_set_dot(x0, y0);//显示最后一点}else //对于dx<dy使用y轴为基准{di = dx_x2 - dy;while(y0 != y1){lcd_set_dot(x0, y0);y0 += dy_sym;if(di < 0)di += dx_x2;else{di += dx_x2 - dy_x2;x0 += dx_sym;}}lcd_set_dot(x0, y0);//显示最后一点}} *///***************************************************************************// //*******************画指定宽度的任意两点之间的直线**************************// //参数说明:x0、y0为起始点坐标,x1、y1为终点坐标,with为线宽*****************// //***************************************************************************// /*void gui_linewith(uchar x0 , uchar y0 , uchar x1 , uchar y1 , uchar with){char dx; // 直线x轴差值变量char dy; // 直线y轴差值变量char dx_sym; // x轴增长方向,为-1时减值方向,为1时增值方向char dy_sym; // y轴增长方向,为-1时减值方向,为1时增值方向char dx_x2; // dx*2值变量,用于加快运算速度char dy_x2; // dy*2值变量,用于加快运算速度char di; // 决策变量char wx, wy; // 线宽变量char draw_a, draw_b;// 参数过滤if(with==0) return;if(with>50) with = 50;dx = x1-x0; // 求取两点之间的差值dy = y1-y0;wx = with/2;wy = with-wx-1;//判断增长方向,或是否为水平线、垂直线、点if(dx>0) // 判断x轴方向{dx_sym = 1; // dx>0,设置dx_sym=1 }else{if(dx<0){dx_sym = -1; // dx<0,设置dx_sym=-1}else{//dx==0,画垂直线,或一点wx = x0-wx;if(wx<0) wx = 0;wy = x0+wy;while(1){x0 = wx;gui_rline(x0, y0, y1);if(wx>=wy) break;wx++;}return;}}if(dy>0) // 判断y轴方向{dy_sym = 1; // dy>0,设置dy_sym=1 }else{if(dy<0){dy_sym = -1; // dy<0,设置dy_sym=-1 }else{//dy==0,画水平线,或一点wx = y0-wx;if(wx<0) wx = 0;wy = y0+wy;while(1){y0 = wx;gui_hline(x0, x1, y1);if(wx>=wy) break;wx++;}return;}}// 将dx、dy取绝对值dx = dx_sym * dx;dy = dy_sym * dy;//计算2倍的dx及dy值dx_x2 = dx*2;dy_x2 = dy*2;//使用Bresenham法进行画直线if(dx>=dy) // 对于dx>=dy,则使用x轴为基准{di = dy_x2 - dx;while(x0!=x1){//x轴向增长,则宽度在y方向,即画垂直线draw_a = y0-wx;if(draw_a<0) draw_a = 0;draw_b = y0+wy;gui_rline(x0, draw_a, draw_b);x0 += dx_sym;if(di<0){di += dy_x2; // 计算出下一步的决策值}else{di += dy_x2 - dx_x2;y0 += dy_sym;}}draw_a = y0-wx;if(draw_a<0) draw_a = 0;draw_b = y0+wy;gui_rline(x0, draw_a, draw_b);}else // 对于dx<dy,则使用y轴为基准{di = dx_x2 - dy;while(y0!=y1){//y轴向增长,则宽度在x方向,即画水平线draw_a = x0-wx;if(draw_a<0) draw_a = 0;draw_b = x0+wy;gui_hline(draw_a, y0, draw_b);y0 += dy_sym;if(di<0){di += dx_x2;}else{di += dx_x2 - dy_x2;x0 += dx_sym;}}draw_a = x0-wx;if(draw_a<0) draw_a = 0;draw_b = x0+wy;gui_hline(draw_a, y0, draw_b);}} *///***********画矩形函数*************************************// //x0、y0为矩形左上角坐标值,x1、y1为矩形右下角坐标值********// //**********************************************************// /*void gui_rectangle(uchar x0 , uchar y0 , uchar x1 , uchar y1){gui_hline(x0 , x1 , y0);gui_rline(x0 , y0 , y1);gui_rline(x1 , y0 , y1);gui_hline(x0 , x1 , y1);}*///****************画填充矩形函数****************************// //x0、y0为矩形左上角坐标值,x1、y1为矩形右下角坐标值********// //**********************************************************// /*void gui_rectangle_fill(uchar x0 , uchar y0 , uchar x1 , uchar y1){uchar i;//转换数据的中间变量,使x1、y1大if(x0 > x1){i = x0;x0 = x1;x1 = i;}if(y0 > y1){i = y0;y0 = y1;y1 = i;}//***判断是否是直线***//* if(y0 == y1)//画水平线{gui_hline(x0 , x1 , y0);return;}if(x0 == x1)//画竖直线{gui_rline(x0 , y0 , y1);return;}while(y0 <= y1)//画填充矩形{gui_hline(x0 , x1 , y0);y0 ++;}} *///*******************画正方形函数*************************// //x0、y0为正方形左上角坐标,with正方形边长****************// //********************************************************// /*void gui_square(uchar x0 , uchar y0 , uchar with){if(with == 0)return;if((x0 + with) > 127)//横轴超出液晶边界return;if((y0 + with) > 63)return;gui_rectangle(x0 , y0 , x0 + with , y0 + with);} *///****************画填充正方形函数*************************// //x0、y0为正方形左上角坐标,with正方形边长*****************// //*********************************************************// /*void gui_square_fill(uchar x0 , uchar y0 , uchar with){if(with == 0)return;if((x0 + with) > 127)//横轴超出液晶边界return;if((y0 + with) > 63)return;gui_rectangle_fill(x0 , y0 , x0 + with , y0 + with);} *///****************画圆函数*********************************// //x0、y0为圆心坐标,r为圆的半径****************************// //*********************************************************// /*void gui_circle(uchar x0 , uchar y0 , uchar r){char a , b;char di;if(r > 31 || r == 0)//圆大于液晶屏或者没半径则返回return;a = 0;b = r;di = 3 - 2 * r;//判断下个点位置的标志while(a <= b){lcd_set_dot( x0 - b , y0 - a);//3lcd_set_dot( x0 + b , y0 - a); //0lcd_set_dot( x0 - a , y0 + b); //1lcd_set_dot( x0 - b , y0 - a); //7lcd_set_dot( x0 - a , y0 - b); //2lcd_set_dot( x0 + b , y0 + a); //4lcd_set_dot( x0 + a , y0 - b); //5lcd_set_dot( x0 + a , y0 + b); //6lcd_set_dot( x0 - b , y0 + a);a ++;//***使用bresenham算法画圆********if(di < 0)else{di += 10 + 4 * (a - b);b --;}lcd_set_dot( x0 + a , y0 + b);}} *///***************************************************************************// //***************************画正椭圆函数************************************// //说明:给定椭圆的四个点的参数,最左、最右点的x轴坐标值为x0、x1,最上、最下点// 的y轴坐标为y0、y1.//说明:----------------------------显示效果不好//***************************************************************************// /*void gui_ellipse(char x0, char x1, char y0, char y1){char draw_x0, draw_y0; // 刽图点坐标变量char draw_x1, draw_y1;char draw_x2, draw_y2;char draw_x3, draw_y3;char xx, yy; // 画图控制变量char center_x, center_y; // 椭圆中心点坐标变量char radius_x, radius_y; // 椭圆的半径,x轴半径和y轴半径int radius_xx, radius_yy; // 半径乘平方值int radius_xx2, radius_yy2; // 半径乘平方值的两倍char di; // 定义决策变量///* 参数过滤if( (x0==x1) || (y0==y1) ) return;///* 计算出椭圆中心点坐标center_x = (x0 + x1) >> 1;center_y = (y0 + y1) >> 1;///* 计算出椭圆的半径,x轴半径和y轴半径if(x0 > x1){ radius_x = (x0 - x1) >> 1;}else}if(y0 > y1){ radius_y = (y0 - y1) >> 1;}else{ radius_y = (y1 - y0) >> 1;}///* 计算半径平方值radius_xx = radius_x * radius_x;radius_yy = radius_y * radius_y;///* 计算半径平方值乘2值radius_xx2 = radius_xx<<1;radius_yy2 = radius_yy<<1;///* 初始化画图变量xx = 0;yy = radius_y;di = radius_yy2 + radius_xx - radius_xx2*radius_y ; // 初始化决策变量///* 计算出椭圆y轴上的两个端点坐标,作为作图起点draw_x0 = draw_x1 = draw_x2 = draw_x3 = center_x;draw_y0 = draw_y1 = center_y + radius_y;draw_y2 = draw_y3 = center_y - radius_y;lcd_set_dot(draw_x0, draw_y0); // 画y轴上的两个端点lcd_set_dot(draw_x2, draw_y2);while( (radius_yy*xx) < (radius_xx*yy) ){ if(di<0){ di+= radius_yy2*(2*xx+3);}else{ di += radius_yy2*(2*xx+3) + 4*radius_xx - 4*radius_xx*yy;yy--;draw_y0--;draw_y1--;draw_y2++;draw_y3++;}xx ++; // x轴加1draw_x0++;draw_x1--;draw_x2++;draw_x3--;lcd_set_dot(draw_x0, draw_y0);lcd_set_dot(draw_x1, draw_y1);lcd_set_dot(draw_x2, draw_y2);lcd_set_dot(draw_x3, draw_y3);}di = radius_xx2*(yy-1)*(yy-1) + radius_yy2*xx*xx + radius_yy + radius_yy2*xx - radius_xx2*radius_yy;while(yy>=0){ if(di<0){ di+= radius_xx2*3 + 4*radius_yy*xx + 4*radius_yy - 2*radius_xx2*yy;xx ++; // x轴加1draw_x0++;draw_x1--;draw_x2++;draw_x3--;}else{ di += radius_xx2*3 - 2*radius_xx2*yy;}yy--;draw_y0--;draw_y1--;draw_y2++;draw_y3++;lcd_set_dot(draw_x0, draw_y0);lcd_set_dot(draw_x1, draw_y1);lcd_set_dot(draw_x2, draw_y2);lcd_set_dot(draw_x3, draw_y3);}} *///*******************************************************************//*******画满屏图片-----本程序为逐行写,因此图片数据也应该是逐行取的//参数:dat为填充的数据------用本程序时需要满屏图的数组//*******************************************************************/*void gui_draw_full_picture (unsigned char *dat){unsigned char i;unsigned char j;unsigned char k;unsigned char bGDRAMAddrX = 0x80; //GDRAM水平地址unsigned char bGDRAMAddrY = 0x80; //GDRAM垂直地址for(i = 0; i < 2; i++){for(j = 0; j < 32; j++){for(k = 0; k < 8; k++){write_com(0x34); //设置为8位MPU接口,扩充指令集,关闭绘图显示write_com(bGDRAMAddrY+j); //垂直地址Ywrite_com(bGDRAMAddrX+k); //水平地址Xwrite_dat(*dat++); //写数据高字节write_dat(*dat++); //写数据低字节}}bGDRAMAddrX = 0x88; //写下半屏幕}write_com(0x36); //打开绘图模式write_com(0x30); //恢复基本指令集,关闭绘图模式} */unsigned char code DCB2HEX_TAB[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};//****************************输出一行数据函数,此行可任意长,不必非得是8的倍数**和下个函数合用画任意大小(矩形)的图形或汉字//参数:flag反显标志,1为反显,x、y为指定显示位置的起始点,*dat要输出的点阵数组,no显示此行所需的点个数,即图形一行的点数void gui_loadline(unsigned char x,unsigned char y,unsigned char *dat,unsigned char no,unsigned char flag){unsigned char bit_dat;unsigned char i;//参数过滤,若指定显示位置超出液晶屏则返回if(x>127) return;if(y>63) return;for(i=0; i<no; i++)//超出本行所规定的点数则本行显示完成{// 判断是否要读取点阵数据,每字节的开始读取一次点阵数组即i为8的倍数时if( (i%8)==0 ) bit_dat = *dat++;// 对相应的点打1或打0,i&0x07意思是对8求余if( (bit_dat&DCB2HEX_TAB[i&0x07])==0 )//取出i对应的位,并判断是否为0{if(flag==0) //判断是否反显,该位取出的数据为0,反显要打为1,flag==0代表不反显GUI_Point(x,y,0); //正常显示0,GUI_Point(x,y,0)代表在x、y处打0 elseGUI_Point(x,y,1); //将0反显}else{if(flag==0)GUI_Point(x,y,1);elseGUI_Point(x,y,0);}if( (++x)>127) return;//若显示超出了液晶屏则返回}}//***************************************************************************//*****************在自定义大小的区域内画图或画字函数****************************//参数说明:x、y指定显示区域的起始点坐标// dat 要输出显示的图形或汉字点阵数组。

12864LCD显示图形文字程序代码--STC89C52

12864LCD显示图形文字程序代码--STC89C52

/********函数声明*************************************************************/ void WriteDataLCD(unsigned char WDLCD); void WriteCommandLCD(unsigned char WCLCD,BuysC); unsigned char ReadDataLCD(void); unsigned char ReadStatusLCD(void); void LCDInit(void); void LCDClear(void); void LCDFlash(void); void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData); void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData); void DisplayImage (unsigned char code *DData); void Delay5Ms(void); void Delay400Ms(void);
sbit LCD_RS=P1^0;
sbit LCD_RW=P1^1;
sbit LCD_E=P1^2; sbit PSB =P1^6;
//PSB 脚为 12864-12 系列的串、并通讯功能切换,我们使用 8 位义***********************************************************/ #define LCD_Data P0 #define Busy 0x80 //用于检测 LCD 状态字中的 Busy 标识

12864液晶显示图片,画点,画任意直线

12864液晶显示图片,画点,画任意直线

玩转12864液晶(2)--显示图片,画点,画任意直线本帖被红金龙吸味执行加亮操作(2009-07-04)通过上一篇的实验,相信大家都掌握了显示字符的基本用法。

下面我们来看一下12864液晶更高级的用法。

首先是它的绘图功能。

让我们先来显示一整副的图片吧,也就是128x64大小。

在使用绘图功能时,先要打开扩充指令集,然后再打开绘图功能。

接着就是送数据显示了。

这里我们首先要弄明白ST7920的显示坐标关系。

其显示坐标如下。

从图中可以看出,X方向共有8个字(16个字节)Y方向共有0~31 行分为上下两个屏。

弄懂了之后我们就可以依照此坐标来显示一整屏的图片了。

随便用一个图片的提取转换软件,讲一副126X64大小的图片转换成字节数据,总共字节大小为128*64/8 = 1024个字节。

下面我们来看看这个显示整屏图像的函数void v_Lcd12864DrawPicture_f( unsigned char code *pPicture ){unsigned char i, j, k ;for( i = 0 ; i < 2 ; i++ )//分上下两屏写{for( j = 0 ; j < 32 ; j++ ){v_Lcd12864SendCmd_f( 0x80 + j ) ;//写Y坐标if( i == 0 ) //写X坐标{v_Lcd12864SendCmd_f( 0x80 ) ;}else{v_Lcd12864SendCmd_f( 0x88 ) ;}for( k = 0 ; k < 16 ; k++ ) //写一整行数据{v_Lcd12864SendData_f( *pPicture++ ) ;}}}v_Lcd12864SendCmd_f( 0x30 ) ;}看看效果图片如下:显示一个人的图像下面来看看如何在任意一个位置显示或者是擦除一个点对于12864这种二值显示屏来说,其显示状态无外乎显示和不显示一个点这两种状态。

12864画圆程序 12864显示任意图形和字符

12864画圆程序  12864显示任意图形和字符

uchar Read_data()
{
uchar shuju;
P0=0xff;
rs=1;
// D/I=1,代表数据
rw=1;
// R/W=1.读取
delayms(10);
en=1;
delayms(100); shuju=P0; //读取当前显示的数据
en=0;
return(shuju);
}
/******************************************* 函数名称:Draw_TX 功 能:显示一个 16*16 大小的图形 参 数:Yaddr--Y 地址
uchar i,j,k;
Write_com(0x34);
//打开扩展指令集
i=0x80;
for(j=0;j<32;j++)
{
Write_com(i++);
Write_com(0x80);
for(k=0;k<16;k++)
{
Write_data(0x00);
}
}
i=0x80;
for(j=0;j<32;j++)
{
Write_com(i++);
Write_com(0x88);
for(k=0;k<16;k++)
{
Write_data(0x00);
}
} Write_com(0x30);
//回到基本指令集
}
/****************************
画点函数:Write_Point() x 表示列,y 表示为行。 ******************************/

12864液晶图像显示图文教程——最全版

12864液晶图像显示图文教程——最全版
2:1 的过程中图片会被拉伸变形,不过缩小到 128*64 像素后也不 是太明显。 也可以使用 windows 操作系统自带的绘图工具修改图片大小,并保存为.bmp 格式文件,再利用自摸 提取软件提取字模。 例子如下:(该图片是利用 Photoshop 软件编辑而成的,像素 128*64,经绘图工具保存为.bmp 格式)
uchar i,j; write_cmd(0x34);//扩充指令集动作 write_cmd(0x34);//关绘图显示功能 for(i=0;i<32;i++)//上半屏 { write_cmd(0x80+i);//垂直地址 write_cmd(0x80); //水平地址,水平地址自动加 1 for(j=0;j<16;j++) { write_data(0x00); } } for(i=0;i<32;i++)//下半屏 { write_cmd(0x88+i);//垂直地址 write_cmd(0x88);//水平地址,水平地址自动加 1 for(j=0;j<16;j++) { write_data(0x00); } } write_cmd(0x36);//开绘图显示 write_cmd(0x30);//回到基本指令集 } //函数名称:display_image(uchar *p) //函数功能:显示图片 void display_image(uchar *p) { uchar i,j; write_cmd(0x34);//扩充指令集动作 write_cmd(0x34);//关绘图显示功能 /*上半屏显示设置*/ for(i=0;i<32;i++)//上半屏 { write_cmd(0x80+i);//垂直地址 write_cmd(0x80); //水平地址,水平地址自动加 1

12864汉字和图片的显示

12864汉字和图片的显示

12864汉字和图片的显示课程设计报告书设计题目:12864汉字和图片的显示课程名称:单片机快速入门系部:电子信息系专业:应用电子技术班级:电子0901姓名:组长:学号:成绩:2011年6月16日目录任务安排 (3)一、项目介绍 (3)1.1 设计内容 (3)1.2 设计要求 (3)1.3 系统主要功能 (4)二、硬件设计 (4)2.1 原理电路图 (4)2.2主要元件功能说明 (5)三、系统软件设计 (10)3.1 分析论证 (10)3.2 程序流程图 (12)3.3 源程序清单 (13)四、个人心得 (19)五、结束语 (20)六、参考文献 (21)七、12864汉字和图片的显示原理图 (21)任务安排一、项目介绍1.1 设计内容利用单片机和12864液晶显示屏通过按键功能实现汉字和图片的显示1.2 设计要求(1)在12864上第一次显示汉字“安徽财贸职业学院大学城翡翠路900/doc/dd174fd133d4b14e852468a7.ht ml ”(2)在12864上第二次显示汉字“单片机实训周6月11日星期六”(3)第三次显示图片:服装,帽子,鞋,皮包等(4)第四次显示汉字:“这就是我们小组的设计方案谢谢欣赏”1.3系统主要功能:12864LCD指令系统及时序该类液晶显示模块(表1-1)控制信号控制代码指令名称R/W RS DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 显示开关0 0 0 0 1 1 1 1 1 1/0 起始行设置0 0 1 1 X X X X X X 页设置0 0 1 0 1 1 1 X X X 列地址设置0 0 0 1 X X X X X X 读状态 1 0 BUSY 0 ON/OFF RST 0 0 0 0 写数据0 1 写数据读数据 1 1 读数据二、硬件设计2.1 原理电路图12864显示屏(图2-1a)独立按键原理图(图2-1b)2.2主要元件功能说明1)12864显示屏内部功能器件及相关功能如下指令寄存器(IR): IR是用于寄存指令码,与数据寄存器数据相对应。

用12864显示任意一张图片

用12864显示任意一张图片

可在12864上显示任何图片有了取模软件,可以将任意一张图片变成代码显示在12864上面;取模软件可以到网上下载,也可以找我要,加qq494891864#include<reg52.h>sbit rs=P1^2;sbit rw=P1^1;sbit cs=P1^0;sbit psb=P1^3;unsigned char lcd_x,lcd_y;unsigned char code image[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x0F,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x0F,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x0F,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x0B,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x07,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x3F,0xD0,0x00,0x0F,0xFF,0xFF,0xE0,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x3F,0xF0,0x00,0x0F,0x90,0x37,0xE0,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x3F,0xF0,0x00,0x07,0xFF,0xFF,0x80,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x3F,0xF0,0x1F,0xBF,0xFF,0xFF,0xFF,0xC0,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x3F,0xC0,0x1F,0xFF,0xFF,0xFF,0xFF,0x40,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x01,0xBF,0xCE,0xDF,0xFF,0xFF,0xFF,0xFF,0xDE,0xC0,0x00,0x00,0x00,0x00 ,0x00,0x00,0x01,0xBF,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,0x00,0x00,0x00 ,0x00,0x00,0x01,0xFF,0xCF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0x80,0x00,0x00,0x00,0x00 ,0x00,0x00,0x05,0xFF,0xEF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xB0,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF0,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0,0x00,0x00,0x00,0x00 ,0x00,0x00,0x07,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,0x00,0x00 ,0x00,0x00,0x07,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0x80,0x00,0x00,0x00 ,0x00,0x00,0x13,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xAD,0x7E,0xC0,0x00 ,0x00,0x00,0x1F,0xFF,0xFF,0xF0,0x1F,0xFF,0xFF,0xFF,0xFF,0xFF,0xBF,0xFF,0xC0,0x00 ,0x00,0x00,0x1F,0xFF,0xFE,0xBC,0x3F,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xB7,0xC0,0x00 ,0x00,0x00,0x1F,0xFF,0xFF,0xFC,0x3F,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0,0x00 ,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x0D,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00 ,0x00,0x00,0x1F,0xFF,0x60,0x00,0x00,0x0F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0,0x00 ,0x00,0x00,0xFF,0xFF,0xE0,0x00,0x00,0x0F,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0,0x00 ,0x00,0x00,0xDF,0xF8,0x00,0x00,0x00,0x00,0x1F,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0x00 ,0x00,0x00,0xFF,0xB8,0x00,0x00,0x00,0x00,0x1F,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0x00 ,0x00,0x00,0xBF,0x18,0x00,0x00,0x00,0x00,0x14,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0x00 ,0x00,0x00,0x7D,0x00,0x00,0x00,0x00,0x00,0x02,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0x00 ,0x00,0x03,0x7F,0x00,0x00,0x00,0x00,0x00,0x07,0xBF,0xFF,0xFF,0xFF,0xEE,0x00,0x00 ,0x00,0x03,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x2F,0xFF,0xFF,0xFF,0xF8,0x00,0x00 ,0x00,0x03,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x37,0xFF,0xFF,0xFF,0xF8,0x00,0x00 ,0x00,0x03,0xBC,0x00,0x00,0x00,0x00,0x00,0x00,0x3D,0xFF,0xFF,0xFF,0x78,0x00,0x00 ,0x00,0x03,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFE,0x00,0x00,0x00 ,0x00,0x03,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xFF,0xFF,0xFF,0x00,0x00,0x00 ,0x00,0x03,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xCF,0xFF,0xE3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xFF,0x60,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x97,0xE0,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x0F,0xFC,0x0F,0xFE,0x1F,0xF8,0x78,0x7C,0x3F,0xF8,0x00,0x00 ,};void delay(unsigned char z) //延时{unsigned i,j;for(i=0;i<z;i++)for(j=0;j<110;j++);}void write_com(unsigned int com) //写命令{rs=0;rw=0;cs=0;P2=com;delay(5);cs=1;delay(5);cs=0;}void write_date(unsigned char dat) //写数据{rs=1;rw=0;cs=0;P2=dat;delay(5);cs=1;delay(5);cs=0;}void init(){psb=1; //1并行,0串行write_com(0x30); //基本指令操作delay(5);write_com(0x0c); //显示开,关光标delay(5);write_com(0x01); //清除led的显示内容delay(5);}/*====================================================函数功能:清除GCROM的内容,如果不清除会出现花屏现象清除方法:向GCROM中写入0x00来清除内========================================================*/void clear_gcrom(){unsigned char i,j,k;lcd_x=0x80;lcd_y=0x80;write_com(0x34);for(i=0;i<2;i++){for(j=0;j<32;j++){write_com(lcd_y+j);write_com(lcd_x);for(k=0;k<16;k++){write_date(0x00);}}lcd_x=0x88;}write_com(0x36);write_com(0x30);}/*================================================================函数功能:向12864中写入一幅图片函数参数:lcd_x为水平显示位置,lcd_y为垂直显示位置,函数将12864屏分成上下两屏写入,上半屏LCD_x=0x80,下半屏lcd_x=0x88 =================================================================*/void write_image(unsigned char *p){unsigned char i,j,k;lcd_x=0x80;lcd_y=0x80;write_com(0x34);for(i=0;i<2;i++) //分为上下两屏{for(j=0;j<32;j++){write_com(lcd_y+j);write_com(lcd_x);for(k=0;k<16;k++) //写入显示数据{write_date(*p++);}}lcd_x=0x88;}write_com(0x36);write_com(0x30);}void main(){init();write_com(0x1c);clear_gcrom();write_image(image);while(1);}(注:可编辑下载,若有不当之处,请指正,谢谢!)。

12864液晶屏点阵显示图片

12864液晶屏点阵显示图片

这是lcd12864液晶静态显示图片的程序,本人采用的是郭天祥的板子,具体电路连接见下图请各位读者具体的结合自己手上的板子及资料好好分析,下面的程序做了简单的注释,请读者自行仔细分析,一定要结合自己手上的板子及资料结合下面的程序,写出适合自己的程序,不要全盘的复制粘贴,不然要出错的哦!!!#include<reg52.h>typedef unsigned char unchar;typedef unsigned int unint;sbit LCD_RS=P3^5;sbit LCD_WS=P3^6;sbit LCD_ENABLE=P3^4;sbit LCD_PSB=P3^7;/*********************************************************************图形字模(可以随意改写)**********************************************************************/code unchar constant[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x80,0x03,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x03,0xE0,0x00,0x00,0x0F,0x80,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x0F,0x80,0x00,0x00,0x03,0xE0,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x03,0xF0,0x00,0x20,0x3F,0x00,0x0F,0xE0,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x1F,0xC0,0x20,0x30,0x30,0x87,0xC3,0xF8,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x7F,0x0C,0x18,0x30,0x46,0x03,0x20,0xFE,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x01,0xFC,0x06,0xEC,0x18,0x63,0x02,0x00,0x3F,0x80,0x00,0x00,0x00, 0x00,0x00,0x00,0x07,0xF0,0x03,0x06,0x00,0x0E,0x06,0x00,0x0F,0xE0,0x00,0x00,0x00, 0x00,0x00,0x00,0x1F,0xC0,0x01,0x80,0x00,0x00,0x04,0x00,0x03,0xF8,0x00,0x00,0x00, 0x00,0x00,0x00,0x3F,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x00, 0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x80,0x00,0x00, 0x00,0x00,0x03,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xC0,0x00,0x00, 0x00,0x00,0x0F,0xC0,0x03,0xFF,0x80,0x00,0x00,0x00,0x0F,0xFE,0x01,0xF0,0x00,0x00, 0x00,0x00,0x1F,0x00,0x0F,0xFF,0xFE,0x00,0x00,0x00,0xFF,0xF0,0x00,0x7C,0x00,0x00, 0x00,0x00,0x7C,0x00,0x3F,0xFF,0xFF,0x80,0x00,0x03,0xFF,0x80,0x00,0x1F,0x00,0x00, 0x00,0x01,0xF0,0x00,0x00,0x7F,0xFF,0xE0,0x00,0x0F,0xFF,0x00,0x00,0x07,0x80,0x00, 0x00,0x03,0xC0,0x01,0xFF,0x80,0x0F,0xF8,0x00,0x1F,0xFC,0x00,0x00,0x01,0xE0,0x00, 0x00,0x0F,0x00,0x07,0xFF,0xFF,0xE0,0xFC,0x00,0x3F,0xF8,0x00,0x00,0x00,0x70,0x00, 0x00,0x1C,0x00,0x0F,0xFF,0xFF,0xFF,0x1E,0x00,0x7F,0xF0,0x00,0x00,0x00,0x1C,0x00, 0x00,0x70,0x00,0x3F,0xFF,0xFF,0xFF,0xCF,0x01,0xFF,0xC0,0x00,0x00,0x00,0x07,0x00, 0x00,0xC0,0x00,0x40,0x00,0x00,0x7F,0xF7,0x03,0xFF,0x80,0x00,0x00,0x00,0x01,0x80, 0x03,0x00,0x00,0x00,0xFF,0xFF,0x03,0xFB,0x07,0xFF,0x00,0x00,0xFC,0x00,0x00,0x60, 0x04,0x00,0x07,0xFF,0xFF,0xFF,0xFC,0x7F,0x1F,0xFE,0x00,0x0F,0xFF,0x80,0x00,0x60, 0x06,0x00,0x0F,0xFF,0xFF,0xFF,0xFF,0x1F,0x3F,0xFC,0x00,0xFF,0xFF,0xF8,0x01,0xC0, 0x03,0x80,0x3F,0xFF,0xFF,0x00,0xFF,0xC7,0xFF,0xF0,0x0F,0xFF,0xFF,0xFF,0x03,0x00, 0x00,0xE0,0xFF,0x80,0x00,0x00,0x0F,0xE7,0xFF,0xC0,0x7F,0xFF,0x80,0x00,0x0E,0x00, 0x00,0x38,0x00,0x00,0x00,0x00,0x03,0xCF,0xF8,0x03,0xFF,0xE0,0x00,0x00,0x38,0x00, 0x00,0x1E,0x00,0x00,0x00,0x00,0x03,0x9C,0x00,0x3F,0xFC,0x00,0x00,0x00,0xF0,0x00, 0x00,0x07,0x80,0x00,0x00,0x00,0x06,0x00,0x07,0xFF,0x80,0x00,0x00,0x03,0xC0,0x00, 0x00,0x01,0xF0,0x00,0x00,0x00,0x1C,0x0F,0xFF,0x80,0x00,0x00,0x00,0x0F,0x80,0x00, 0x00,0x00,0xFC,0x00,0x00,0x00,0x7F,0xE0,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00, 0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0xF8,0x00,0x00, 0x00,0x00,0x0F,0xC0,0x00,0x10,0x42,0x03,0x01,0x20,0x83,0x40,0x03,0xF0,0x00,0x00, 0x00,0x00,0x03,0xF0,0x00,0x0B,0x83,0x44,0xE3,0x47,0xCE,0x60,0x0F,0xC0,0x00,0x00, 0x00,0x00,0x01,0xFC,0x00,0x03,0x8F,0x46,0xE6,0x85,0xC7,0x80,0x3F,0x00,0x00,0x00, 0x00,0x00,0x00,0x7F,0x00,0x3F,0x03,0xCD,0x42,0xC1,0x05,0x80,0x7C,0x00,0x00,0x00, 0x00,0x00,0x00,0x1F,0xC0,0x63,0x30,0x8C,0x4E,0xE7,0x8D,0x71,0xF0,0x00,0x00,0x00, 0x00,0x00,0x00,0x07,0xF0,0x80,0x00,0x00,0x00,0x01,0x00,0x07,0xC0,0x00,0x00,0x00, 0x00,0x00,0x00,0x01,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x80,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x0F,0xC0,0x00,0x01,0x00,0x20,0x01,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x01,0x85,0x96,0x28,0x1F,0x80,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x3F,0x80,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x07,0xE0,0x00,0x00,0x01,0xF0,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x01,0xF8,0x00,0x00,0x07,0xC0,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x1F,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x80,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xE0,0x01,0xE0,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };/***********************************延时函数***********************************/void delay_ms(unchar ms){unchar j;for(ms;ms>0;ms--)for(j=110;j>0;j--);}/***********************************lcd写命令***********************************/void LcdWriteCommand(unchar command){LCD_RS=0;LCD_WS=0;LCD_ENABLE=0;P0=command;delay_ms(1);LCD_ENABLE=1;delay_ms(5);LCD_ENABLE=0;}/*******************************lcd写数据********************************/void LcdWriteData(unchar dat){LCD_RS=1;LCD_WS=0;LCD_ENABLE=0;P0=dat;delay_ms(1);LCD_ENABLE=1;delay_ms(5);LCD_ENABLE=0;}/**********************************led显示函数*********************************/void PhotoDisplay(unchar *constant){unchar j,row;LcdWriteCommand(0x34);/*关闭图形显示*/for(row=0;row<32;row++){LcdWriteCommand(0x80+row);//写入水平坐标值LcdWriteCommand(0x80);//写入垂直坐标值for(j=0;j<16;j++)LcdWriteData(*constant++);}for(row=0;row<32;row++){LcdWriteCommand(0x80+row);LcdWriteCommand(0x88);for(j=0;j<16;j++)LcdWriteData(*constant++);}LcdWriteCommand(0x36);/*打开图形显示*/}/*************************************lcd初始化设置**************************************/void LcdInit(){LCD_PSB=1;//采用并口方式LcdWriteCommand(0x30);//基本指令操作delay_ms(5);LcdWriteCommand(0x34);//扩充指令操作delay_ms(5);LcdWriteCommand(0x0c);//打开显示,关闭光标delay_ms(5);LcdWriteCommand(0x01);//清除lcd显示内容}/**************************************** 主函数*****************************************/ void main(){LcdInit();PhotoDisplay(constant);while(1);}。

12864学习,显示各种图形,和利用算法画几何图形

12864学习,显示各种图形,和利用算法画几何图形

12864学习(控制器S T7920)在学习12864其他功能前先学习一下12864的几个基本函数void delay(uint x)//延时函数{x=x*12;while(x--){_nop_(); //包含在intrins.h头文件_nop_();_nop_();}}void write_lcd_cmd(uchar cmd)//写命令{RS=0;RW=0;EN=1;P0=cmd;// delay(1);EN=0;delay(1);}void write_lcd_date(uchar date)//写数据函数{RS=1;RW=0;EN=1;P0=date;// delay(1);EN=0;delay(1);}void display_pos(uchar x,uchar y)//设置显示地址,用于显示中文字时设计显示地址{uchar pos;switch(x){case 0: pos=0x80; break;//当x为0指向第一行case 1: pos=0x90; break;//当x为1指向第二行case 2: pos=0x88; break;//当x为2指向第三行case 3: pos=0x98; break;//当x为3指向第四行default: pos=0x80; //x为其它值时指向第一行}pos=pos+y;write_lcd_cmd(pos);}/*=========================================================== 函数功能:读取12864液晶繁忙标志BF位状态BF=1繁忙,BF=0不忙注意:与读取数据不同读取繁忙标志位是是属于写指令,要将RS置低============================================================* /void read_lcd_bf(){uchar BF=1;P0=0xff;do{RS=0;RW=1;EN=0;EN=1;_nop_();BF=P0;BF=BF>>7;}while(BF);}12864显示图片要让一个点有显示就要让相应的点置高电平。

12864显示图像

12864显示图像
WRD=0;
RS=DI;
delay(1);
P0=data1;
E=1;
delay(1);
E=0;
}
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* 函数声明 */
/******************************************************************/
void DisplayGraphic(unsigned char code *adder)
0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xC3,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xC3,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/******************************************************************/
/* 主程序 */
/******************************************************************/
void main(void)
{
while(1)
{
initina2(); //调用LCD显示图片(扩展)初始化程序
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

看到工具箱旁边那个LCD12864很久没用了(当初买回来用的时候只是简单地测试了一下),于是萌生了重新写一次接口程序的想法(而且这次要给它加个图片显示的功能),好,说做就做,就用Atmega16和ICCAVR来做吧,最近这MCU和平台用得比较熟练。

马上从书堆里把当初打印出来的中文datasheet给翻了出来,依葫芦画瓢地写了个初始化程序。

好,OK。

编译通过。

于是又写了一个可以自定义从XY坐标值开始输出显示的函数,再次编译,也通过,OK。

于是呼马上写了四行简单的字符烧到单片机上试了一下,嘿嘿,一次通过。

如下图:后来在进一步测试的时候也出了点小问题。

就是我是使用USBISP烧写器把程序烧写进AVR的(此时实验板由USBISP烧写器供电),想要实现从第一行的第一个字符开始连续显示"0123456789"。

刚烧写完程序后能看到LCD12864上正常显示"0123456789",但是把烧写器从实验板上断开连接,单独用USB给实验板供电的时候,LCD的第一行只是显示"123456789",第一个字符消失了……,左思右想地弄了一个多小时后,终于把问题给解决了,就是把初始化程序的延时适当增加了些,真是奇怪。

刚开始一直想不通为什么在烧写器供电的情况下就正常显示,而换到USB供电后就出了问题。

后来再想想,估计是跟供电有关。

在使用USBISP烧写器供电的时候,LCD的背光灯明显比用USB供电的时候来得亮,而且对比度也高很多,看来是因为换到USB供电后,供电不怎么充足,以至于LCD在上电初始化的时候花上了更多的时间去初始化(因为供电低了,功率小了,跑起来有点力不从心,用的时间就久了嘛……我是觉得可以这样去理解的接下来呢,就到了有点难度的画图了。

当初刚买到12864的时候只是简单测试了字符显示功能,除了因为画图还不需要用到,另外一个原因就是那datasheet上关于画图那部分的内容不怎么看得懂…。

现在重新拿起来看,依然一头雾水……。

马上上网百度了一下“12864 7920 显示图片”,看到了不少的例子程序,可是……就是没看到有关于这部分功能实现的详细思路和讲解……下载下来的那些程序,基本上没注释,不是说晦涩难懂,但是至少看起来一团糟,让人家不想继续看下去……于是还是硬着头皮去啃那datasheet。

上面对于画图这部分的内容是这样讲解的:在仔细研究了上面关于它的 X啊 Y啊那些坐标的定位啊写满了哪些地址会自增啊哪些不会啊什么的,最后感觉脑袋里有了一种朦胧的概念……哟西,反正不会弄坏,就先随便写个程序试试。

于是乎,嘀咕嘀咕……捣鼓捣鼓……反反复复又弄了一个多小时后,终于摸清了它显示的规律……LCD12864实现画图功能的思路:首先,画图指令属于扩充指令集,要使用这些指令必须在12864初始化之后写命令字(0x34????36吧)进入扩充指令集设定状态。

接着要做的事就是指定我们的图片要从哪里写入(即写入的XY坐标,这个是最关键,也是最难理解的部分)。

因为我们这里是显示一整个画面的图片,所以我们就从12864的第一个点开始显示。

那这个点的坐标是怎么定位的呢?我们往这个点写入数据后,要是接着再写数据,那坐标值会怎样变化呢?首先我们要弄清楚12864究竟是怎么把数据写入到GDRAM(绘图显示RAM)中去的。

12864(ST7920驱动芯片)把屏幕分成上下两部分(如上图中把垂直坐标分成了两部分的00~1F)。

当我们把坐标值写给LCD后(怎么写后面会说),ST7920控制芯片对LCD屏幕的控制过程可以用下面的图片来表示:(后来发现下面那幅图片有点问题……它这里在水平坐标上的00到0F,应该理解为是同一面的,也就是在12864上,水平坐标00到0F处于同一面,而不是上下屏的关系,[看00行]其实大家只要看箭头,明白控制芯片是按什么顺序写GDRAM的就可以了^_^)如图片上所标注,在向GDRAM中写入要显示的图片时,我们先指定从X:00、Y:00处(也就是第①处)开始写入数据(如何指定后面会说明),我们先在第①处写图形数据(按照图片所标注,第15位在最左边,第0位在最右边,即在写入的时候LCD会先写高位字节,接着再写低位字节),接着LCD会自动把坐标定位到同一行第②处的开头,此时我们可以接着告诉LCD在这里写入图形数据,依此类推,当我们写满16次后,第00行(包括上半屏和下半屏的)就全写满了。

那么我们接下去写入数据会出现什么情况呢?答案是LCD又自动从第00行的第①处重新开始写了。

这是因为ST7920控制芯片设计出来就这样,在写入的时候它只会在水平方向(X轴上)地址自增,并且在增加到0F地址之后就会变成00地址从头开始写。

从这里我们可以明白,每次写满一行(共16部分)后就必须在程序里人为地把垂直方向(Y轴)的地址加1,不然就会造成只是在同一行重复写入的现象(俺前面试验了好多次都是这个问题)。

如何在写入的时候定位初始XY坐标呢?依据datasheet,进行坐标设定的时候首先设垂直地址,接着设定水平地址,这两个指令是连续写入LCD的(就是进入扩充指令集设定状态后,只需要RS引脚置低电平,RW引脚置低电平,接着连续写入上面两个命令,垂直地址在前,列地址在后就可以了),我们先来看看关于设定GDRAM地址的指令:从上面的表格我们可以看到,垂直(列)地址由AC6~AC0指定,我们是从00列开始,那自然就是AC6~AC0全为0喽(这里有个问题需要注意,因为我们在写图片数据的时候是一个字节一个字节连续写入的,所以指定列地址的时候就必须为8的整数倍,呵呵,每个字节有8位嘛),那最终写给LCD的指令是如何的呢?就是上面表格紫色字体的部分,例如我是从00列开始写,AC6~AC0为全0,那就是1AC6AC5AC4AC3AC2AC1AC0,也就是1000 0000(二进制),即0x80(十六进制)。

写完列地址就开始写水平(行)地址了,行地址由AC3~AC0指定,我们从00行开始,所以就是全0,就是1000AC3AC2AC1AC0,也就是1000 0000,即0x80。

1.初始化LCD(如果之前已经有先进行过初始化,则这一步省略)2.给LCD写指令0x34,进入扩充指令集设定状态3.设定GDRAM的列地址和行地址【垂直和水平地址】4.按正确规律(每写满一行,行地址要用程序手动加1)连续写入图形数据5.给LCD写指令0x36,打开绘图开关(这样做写入的图形才能正常显示)6.给LCD写指令0x30,返回基本指令集设定状态(也就是正常的字体显示状态)我们在用C语言设计画图程序时,可以这样写(大家如果对写屏的过程不了解,可以把通过改一下下面的程序,例如把写下半屏的函数给屏蔽掉,然后烧写到单片机上看实际效果,这样可以帮助你更好理解这个程序):void LCD_DrawPic(uchar flash pic[64][16]) //定义一个函数,用来向整个屏幕画图{ //图片数据为数组形式,格式为64行16列,正好对应12864的屏幕uchar i,j; //图片数据如何生成请看下面LCD_Write(lcdcmd,0x34); //笔者自定义的函数,功能为向LCD写入命令0x34,即进入扩充指令集设定状态for(i=0;i<32;i++) //定义32次循环,先写半屏数据(半屏共32行) {LCD_Write(lcdcmd,0x80|i); //0b1000 0000写列地址,列地址在增加LCD_Write(lcdcmd,0x80); //0b1000 0000写行位置for(j=0;j<16;j++) //每行共有16部分{LCD_Write(lcddata,pic[i][j]);//笔者自定义的函数,功能为向LCD写入数据}}for(i=0;i<32;i++) //再写剩下的半屏数据{LCD_Write(lcdcmd,0x80|i); //0b1000 0000写列位置LCD_Write(lcdcmd,0x88); //0b1000 1000写行位置for(j=0;j<16;j++){LCD_Write(lcddata,pic[i+32][j]);}}LCD_Write(lcdcmd,0x36);//向LCD写入命令0x36,即打开绘图开关,此时显示图形LCD_Write(lcdcmd,0x30);//向LCD写入命令0x30,返回基本指令集设定状态}那用来做图片的数据应该如何准备呢?这时候我们就要用到字模软件了,网上有很多这方面的软件,在这里我们使用晓奇工作室的LCMZIMO这个软件来作说明。

首先选一幅图片,然后用图像编辑软件截取128*64像素大小,然后转换成单色BMP图片。

原始图片调整大小为128*64调整为单色128*64 BMP格式图片接着使用LCM字模软件打开图片,按照图示的顺序依次设定,打开准备好的图片,然后点参数确认,最后点数据保存,则图片被转换为64行16列的数组数据:转换后所得到的数据:///////////////////////////////////////////////////////////////////// ////// Bitmap点阵数据表 //// 图片: C:\..\桌面\tp2.bmp,横向取模左高位,数据排列:从左到右从上到下 //// 图片尺寸: 128 *64 /////////////////////////////////////////////////////////////////////// ////unsigned char code nBitmapDot[] = // 数据表,这里“nBitmapDot[] ”修改为pic1[64][16]即可(pic1名字可自定义){……(图形数据省略)};接下来就是把这个数组和画图函数整合到你的程序里去然后就可以画出精美的图片啦!附:程序效果演示视频:。

相关文档
最新文档