⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ocm12864.c

📁 本例子为OCM12864-3液晶显示C程序
💻 C
字号:
//OCM12864参考程序
#pragma		code
#include	<REG52.h>
//#include	<math.h>
#include	<absacc.h>
//#include	<intrins.h>
#include	<string.h>
#include	"GSOPYJZM.H"

#define uint       unsigned int
#define uchar      unsigned char
#define disp_off   0x3e   //关显示
#define disp_on    0x3f   //开显示
#define disp_x     0xb8   //页面地址设置,  1 0 1 1 1 P2 P1 P0
#define disp_z     0xc0   //显示起始行设置, 1 1 L5 L4 L3 L2 L1 L0
#define disp_y     0x40   //列地址设置,    0 1 C5 C4 C3 C2 C1 C0
#define data_ora   P0       //MCU P1<------> LCM
uchar volatile xdata LCD_LWC _at_ 0X0100;	// W,液晶左屏写指令
uchar volatile xdata LCD_LWD _at_ 0X0500;	// W,液晶左屏写数据
uchar volatile xdata LCD_LRS _at_ 0X0900;	// R,液晶左屏读状态
uchar volatile xdata LCD_LRD _at_ 0X0D00;	// R,液晶左屏读数据

uchar volatile xdata LCD_RWC _at_ 0X0200;	// W,液晶右屏写指令
uchar volatile xdata LCD_RWD _at_ 0X0600;	// W,液晶右屏写数据
uchar volatile xdata LCD_RRS _at_ 0X0A00;	// R,液晶右屏读状态
uchar volatile xdata LCD_RRD _at_ 0X0E00;	// R,液晶右屏读数据
void delay(unsigned char cc)
	{
		while(--cc);
	}
// 液晶(LCD)写入命令字程序,
	// e   :左、右屏选择,取值范围:e = 1(左屏) 、2(右屏) ,
	// com :送往 LCD 的指令代码。
void LcdCommW(unsigned char e,unsigned char com)
	{
		xdata unsigned char st;
	
		if(e==1)	// 左屏
		{
			do st=LCD_LRS;  // Y2,R,液晶左屏读状态
			while(st&0x80);	// 判“忙”
			LCD_LWC=com;
		}
		else		// 右屏
		{
			if(e==2)
			{
				do st=LCD_RRS;// Y3,R,液晶右屏读状态
				while(st&0x80);	// 判“忙
				LCD_RWC=com;
			}
		}
	}
	
	// 液晶(LCD)写入显示数据程序,
	// e   :左、右屏选择,取值范围:e = 1(左屏) 、2(右屏),
	// dat :送往 LCD 的显示数据。
	void LcdDataW(unsigned char e,unsigned char dat)
	{
		xdata unsigned char st;
	
		if(e==1)	// 左屏
		{
			do st=LCD_LRS;   // Y2,R,液晶左屏读状态
			while(st&0x80);	 // 判忙BUSY
			LCD_LWD=dat;     // Y2,W,液晶左屏写数据
		}
		else		// 右屏
		{
			if(e==2)
			{
				do st=LCD_RRS;  // Y3,R,液晶右屏读状态
				while(st&0x80);	// 判忙BUSY
				LCD_RWD=dat;    // Y3,W,液晶右屏写数据
			}
		}
	}
	
	// 液晶(LCD)初始化程序,
	// 其中,调用:LcdCommW(),
	void LcdInit(void)
	{
		LcdCommW(1,0xC0);	// 左屏设置显示起始行为第一行
		LcdCommW(2,0xC0);	// 右屏设置显示起始行为第一行
	
		LcdCommW(1,0x3f);	// 左屏开显示设置
		LcdCommW(2,0x3f);	// 右屏开显示设置
	}
	
	// 清LCD显示子程序,
	void LcdClean(void)
	{
		xdata unsigned char line,colu,ct;
	
		for(line=0;line<8;line++)
		{
			ct=0xb8|line;  //页面地址设置
			LcdCommW(1,ct);	// 设置'页'地址,即设置显示行
			LcdCommW(2,ct);	// 设置'页'地址,即设置显示行
	
			LcdCommW(1,0x40);	// 设置列地址
			LcdCommW(2,0x40);	// 设置列地址
	
			for(colu=0;colu<64;colu++)
			{
				LcdDataW(1,0);	// 写入数据
				LcdDataW(2,0);	// 写入数据
			}
		}
	}

void delay1 (uint ms)
{
  uint i,j;
  for(i=0;i<ms;i++)
  for(j=0;j<1000;j++)
  ;
}

// zm16_16[c].dt[2][16]所包含的 16×16 点阵字符送往 LCD 显示,
// x  :水平坐标,范围:0 - 15,字符位表示,取字符左边所在位置,
// y  :竖直坐标,范围:1 - 7,字符位表示,取字符下方所在位置,
// 上述坐标零点对应于液晶显示屏的左上角,
// c  :要写入的字符序号 c(对应于 zm16_16[c].dt[2][16]),
// color:显示颜色,1:反色;0:正常
void DisZm16_16(unsigned char x, unsigned char y, unsigned char c,bit color)
{
	xdata unsigned char i,j,d;//定义的局部变量
	xdata unsigned char screen;//左右屏幕
	xdata unsigned char colu; //计算列数,x*8代表第几列

	if(x<16 && y<8 && y>0)//是否位于128=16*8,8*8=64行范围内,不显示乱吗
	{
		y-=1;//y代表下半字所处的页地址,y-1代表上半字所在页位置
		for(i=0;i<2;i++)//i=0写上半字,i=1写下半字
		{
			y+=i;//因为前面y已经变为上半字页地址了,当i=1时候就写下半字页地址了
			y|=0xb8;//页地址设置,页地址在初始页地址基础上偏移
			colu=x*8;//判断是否超出左屏幕,大于63意味在右屏幕写汉字
			if(colu>63)//判断是否超出左屏幕
			{
				colu-=64;//超出左屏幕,colu-64取得相对的
				screen=2;//选择右屏幕
			}
			else screen=1;//如果没超出就选择左屏幕
			LcdCommW(screen,y);	// 设置'页'地址,即设置显示行
			LcdCommW(screen,(colu|0x40));//设置列地址,在初始列地址基础上加偏移量
			for(j=0;j<16;j++)//引用数组,i=0第一行,i=1第二行,一个字符有两行,每行16列
			{
				d=zm16_16[c].dt[i][j];//引用结构体变量
				if(color==1) d=~d;//"~"(按位取反),如果要反显示就取反,否则正常显示
				LcdDataW(screen,d);//写入数据
				if(++colu>63 && screen==1)//左屏幕放不下时候,写在右屏幕
				{
					colu-=64;
					screen=2;
					LcdCommW(screen,y);			// 设置'页'地址,即设置显示行
					LcdCommW(screen,(colu|0x40));	// 设置列地址
				}
			}
		}
	}
}

// zm8_16[c][2][8]所包含的 8×16 点阵字符送往 LCD 显示,
// x  :水平坐标,范围:0 - 15,字符位表示,取字符左边所在位置,
// y  :竖直坐标,范围:1 - 7,字符位表示,取字符下方所在位置,
// 上述坐标零点对应于液晶显示屏的左上角,
// c  :要写入的字符序号 c(对应于 zm8_16[c][2][8]),
// color:显示颜色,1:反色;0:正常
void DisZm8_16(unsigned char x, unsigned char y, unsigned char c,bit color)//列,页,要显示字符,显示颜色
{
	xdata unsigned char i,j,d;//分别对应二维数组的行列,从而选择上下半字,d代表要显示的字符,写入
	xdata unsigned char screen;//选择左右屏幕
	xdata unsigned char colu;//计算所处列位置,colu=x*8;

	if(x<16 && y<8 && y>0)//判断是否位于128*64液晶显示屏幕内
	{
		y-=1;//计算上半列地址
		for(i=0;i<2;i++)//选择要显示的字符,每个字符两行,每行8列,i为行选择
		{
			y+=i;//因为前面y已经变为上半字页地址了,当i=1时候就写下半字页地址了
			y|=0xb8;//求页地址,页地址在初始页地址基础上偏移
			colu=x*8;//求列地址
			if(colu>63)//如果大于63,表示在右屏幕了
			{
				colu-=64;//处于右屏幕中,列地址相对位置
				screen=2;//选择右屏幕
			}
			else screen=1;//否则选择左屏幕
			LcdCommW(screen,y);			// 设置'页'地址,即设置显示行
			LcdCommW(screen,(colu|0x40));	// 写入列地址
			for(j=0;j<8;j++)//写列数据,数组中共有两行,每行8列
			{
				d=zm8_16[c][i][j];//结构体变量引用
				if(color==1) d=~d;//如果要反显示,数据取反
				LcdDataW(screen,d);//数据写入LCD
				if(++colu>63 && screen==1)//写数据的时候判断每列是否超出左屏幕
				{
					colu-=64;//如果超出,就在右屏幕显示
					screen=2;
					LcdCommW(screen,y);			// 设置'页'地址,即设置显示行
					LcdCommW(screen,(colu|0x40));	// 设置列地址
				}
			}
		}
	}
}

// 在液晶上从指定位置开始显示16点阵高字符串程序,
// x  :水平坐标,范围:0 - 15,字符位表示,取字符串左边所在位置,
// y  :竖直坐标,范围:1 - 7,字符位表示,取字符串下方所在位置,
// 若中英文混合,则中文及全角英文显示16*16点阵,半角英文显示8*16点阵,
// 字符串末尾应以0x00结尾,且超出可显示范围的字符将不显示,
// p:字符串首指针。
// color:显示颜色,1:反色;0:正常
void DisH16Str(unsigned char x, unsigned char y,unsigned char *p,bit color)//列,页,字符串,反色与否标志
{
	xdata unsigned char c,d;//c,d
	xdata unsigned int i;//

	if(y<8 && y>0)//判断是否显示在这8页中,超出范围不显示
	{
		for(;x<16;x++)//判断是否在16*8列中
		{
			c=*p;//取字符
			p++;//字符串地址加1,取下个字符
			if(c==0) break;//判断字符串是否结束
			if(c>0xA0)//判断是否为全角字符,<=0xa0是半角字符,>0xa0是全角字符
			{
				i=c;//取得字符,全角字符是两个字节组成一个字符,高位在前,低位在后
				i*=256;//存到高8位上
				i+=*p;//高8位加上低8位组成一个
				p++;//指向下一个字符

				d=sizeof(zm16_16)/34;//每个zm16_16变量占用34个字节,一个整型变量占2个字节,一个字符数组2行16列,2+32=34
				for(c=0;c<d;c++)//d为计算得出有多少个字符,
				{
					if(i==zm16_16[c].cd) break;//与zm16_16结构中的各个值比较,选择相同的一个
				}
				if(c==d) c=0;
				DisZm16_16(x,y,c,color);
				x++;
			}
			else
			{
				if(c>'~' || c<' ') c=' ';//保证不显示乱码
				c-=' ';
				DisZm8_16(x,y,c,color);
			}
		}
	}
}


void main(void)
	{
		//unsigned char c=0;
		//do delay(0);
		//while(--c);		// 开机延时65536个机器周期
	
		LcdInit();		// 液晶显示初始化
		LcdClean();		// 液晶显示清屏
	
			
		DisH16Str(4,1,"TYPE",0);
		DisH16Str(6,4,"V 0.0",0);
		DisH16Str(3,7,"2006/11/30",0);
	
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -