portues软件仿真--LCD12864

proteus 软件仿真之LCD12864(中文显示) 一

大二电子专业小白一名,平时闲来无事在学校老师实验室自学,自学过程中发现一些有困扰到自己的地方,所以特来此记录。一是当作自己学习笔记;二是有幸帮助到有和自己遇到相同问题的童鞋,也是一大善事。因个人水平能力有限,错误之处还请及时纠正。

注:只适合于仿真使用与现实中LCD12864有不同!!!!

以下为proteus 原理图

portues软件仿真--LCD12864_第1张图片

代码

#include "reg52.h"
#include 

#define uchar unsigned char
#define uint unsigned int
#define width	15						/* 显示宽度 */	
#define Graphic	1
#define TXT     0
#define LcmLengthDots	128
#define LcmWidthDots  64 

sbit REST = P2^0;			  			//复位信号,低电平有效
sbit C_D = P2^1;						//L:数据   H:指令
sbit C_E = P2^2;						//使能端,低电平有效
sbit R_D = P2^3;						//读
sbit W_R = P2^4;						//写

/****************************************液晶字库**************************************/

uchar num[] = "0123456789";
typedef struct typFNT_GB16
{
	char Mask[60];
};

code struct typFNT_GB16  GB_16[] = 					/* 汉字取模 */
{
	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xD0,0x3F,0xF0,0x04,0xC0,0x7F,0xFC,		/* 我,0 */
   0x04,0xD0,0x1F,0x60,0x74,0x40,0x04,0xB0,0x4F,0x3E,0x30,0x0C,0x00,0x00,0x00,0x00,},
	 
	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x1F,0x90,0x0C,0xB0,0x3F,0xFC,		/* 爱,1 */
	 0x27,0xF4,0x23,0x24,0x07,0xC0,0x18,0xC0,0x63,0x3E,0x1C,0x0C,0x00,0x00,0x00,0x00,},

	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x80,0x39,0x80,0xF9,0xFC,0x1E,0x64,		/* 你,2 */
	 0x19,0x74,0x19,0x78,0x1A,0x6C,0x1C,0x66,0x18,0x60,0x11,0xC0,0x00,0x00,0x00,0x00,},
	
	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x01,0x80,0x3F,0xFC,0x21,0x8C,		/* 中,3 */
	 0x21,0x8C,0x3F,0xFC,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x00,0x00,0x00,0x00,0x00},
	
	
	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x3F,0xFC,0x2F,0xEC,0x21,0x8C,
	 0x27,0xEC,0x21,0xAC,0x2F,0xFC,0x20,0x0C,0x3F,0xFC,0x00,0x00,0x00,0x00,0x00,0x00},		/* 国,4 */

	{0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x0C,0x00,0x08,0x00,0x08,0x00,0x08,0x00,   /* !,5 */
	 0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x00,0x00},

	{0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x0C,0x00,0x08,0x00,0x08,0x00,0x08,0x00,		/* !,6 */
	 0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x00,0x00},	

	{0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x0C,0x00,0x08,0x00,0x08,0x00,0x08,0x00,		/* !,7 */
	 0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x00,0x00},	

};

/***************************************液晶字库结束***************************************/


void delay_nms(uint i);										/* 延时函数 */
void write_commond(uchar com);								/*LCD12864写入8位命令子函数*/
void write_date(uchar dat)	;								/*LCD12864写入8位数据子函数*/									
void F12864_init();											/*LCD12864 并行初始化子程序*/		
void F12864_clear(void);									/* LCD12864初始化函数 */
void goto_xy(uchar x,uchar y,uchar mode);					/* 设定显示地址 */
void Putchar(uchar x,uchar y,uchar Charbyte);				/* 显示一个字符 */
void display_string(uchar x,uchar y,uchar *p);				/* 显示字符串 */
void display_num(uchar x,uchar y,uchar z);					/* 显示数字 */
																							
void dprintf_hanzi_string_1(struct typFNT_GB16 code *GB_16,uint X_pos,uint Y_pos,uchar j,uchar k);	
/*	汉字显示 更改汉字取模 可以更改显示汉字(数组),坐标,坐标,j=k+n (n,显示字的个数,k,从那个字开始)   */
void main(void)
{
	F12864_init();
	F12864_clear();
	while(1)
	{
		dprintf_hanzi_string_1(GB_16,1,16,7,0);			
	}
}

void delay_nms(uint i)
{
	while(i)
	i--;
}


/* 并行
 * 写命令
 */
void write_commond(uchar com)
{
	C_E = 0;	
	C_D = 1;
	R_D = 1;
	P0 = com;
	W_R = 0;																// write	  
	_nop_();					
	W_R = 1;																// disable write
	C_E = 1;						   	   		
	C_D = 0;
}

/* 并行->写数据 */
void write_date(uchar dat)									
{
	C_E = 0;
	C_D = 0;
	R_D = 1;
	P0 = dat;
	W_R = 0;
	_nop_();
	W_R = 1;
	C_E = 1;
	C_D = 1;
}

/*
 * 写一个指令 一个数据
 */
 void write_dc(uchar com,uchar dat)											
{
	write_date(dat);
	write_commond(com);
}

/*
 * 写一个指令两个数据 
 */
void write_ddc(uchar com,uchar dat1,uchar dat2)
{
	write_date(dat1);
	write_date(dat2);
	write_commond(com);
}

/* 并行初始化 */
void F12864_init(void)
{	
	REST = 0;
	delay_nms(2000);					
	REST = 1;
	write_ddc(0x40,0x00,0x00);			     				 		/* 设置文本显示首地址 */
	write_ddc(0x41,128/8,0x00);  									/* 设置文本显示宽度 */
	write_ddc(0x42,0x00,0x08);			      						/* 设置文本显示首地址0x0800 */
	write_ddc(0x43,128/8,0x00);  									/* 设置图形显示宽度 */
	write_commond(0xA0);                     						/* 设置光标形状8*8 */
	write_commond(0x80);                     						/* 显示方式设置 文本and图形(异或) */
	write_commond(0x92);                     						/* 设置光标 */
	write_commond(0x9F);                     						/* 显示开关设置,文本开,图形开,光标闪烁关 */
}

/* 清除显示函数 */
void F12864_clear(void)
{
	unsigned int i;
	write_ddc(0x24,0x00,0x00); 													/* 设置地址指针从零开始 */									
   	write_commond(0xb0); 															/* 自动写 */
	for(i = 0;i < 128 * 64 ;i++)write_date(0x00); 			/* 清一屏 */
	write_commond(0xb2); 																/* 自动写结束 */
	write_ddc(0x24,0x00,0x00); 													/* 重置地址指针 */
}

/* 设定显示地址 
 * mode 1:图形
 *      0:汉字
 */
void goto_xy(uchar x,uchar y,uchar mode)
{
     uint  temp;
     temp = 128 / 8 * y + x;
     if(mode)                                 								//mode = 1为Graphic
     {                                        								//图形模式要加上图形区首地址0x0800
         temp = temp + 0x0100;
     }
     write_ddc(0x24,temp & 0xff,temp / 256);	  							//地址指针位置
}

/* 显示一个ASCII码 */
void Putchar(uchar x,uchar y,uchar Charbyte)
{
     goto_xy(x,y,TXT);
     write_dc(0xC4,Charbyte-32);		     								//数据一次写入 
}

void display_string(uchar x,uchar y,uchar *p)
{
	while(*p != 0)
	{
		if(x > 15 )                          								//超出一行,自动换行
		{										 	
			x = 0;
			y++;
		}
		Putchar(x,y,*p);
		++x;
		++p;
	}
}

void display_num(uchar x,uchar y,uchar z)
{
	uchar z1,z2;
	z1 = num[z / 10];
	z2 = num[z % 10];
	Putchar(x,y,z1);
	Putchar(x+1,y,z2);
}


/* 显示一串汉字,j=k+n (n,显示字的个数,k,从那个字开始)  */
void dprintf_hanzi_string_1(struct typFNT_GB16 code *GB_16,uint X_pos,uint Y_pos,uchar j,uchar k)
{  
	unsigned int address;
	unsigned char m,n;
	while(k < j)
	{
		m = 0;
		address = LcmLengthDots / 8 * Y_pos + X_pos + 0x0800;
		for(n = 0;n < 16;n++)                                  			  	//计数值16
    	{
		   write_ddc(0x24,(uchar)(address),(uchar)(address>>8)); //设置显示存储器地址
		   write_dc(0xc0,GB_16[k].Mask[m++]);                    //写入汉字字模左部
		   write_dc(0xc0,GB_16[k].Mask[m++]);                 	//写入汉字字模右部
		   address = address + 128/8;                           //修改显示存储器地址,显示下一列(共16列)
	    }
		X_pos += 2;
		k++;
	}
}

仿真后屏幕显示“我爱你中国”

汉字取模使用PCtoLCD2002软件 如下配置portues软件仿真--LCD12864_第2张图片

G.Z.W
2019年6月9日

你可能感兴趣的:(protues软件仿真)