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

📄 lcd12864使用练习.c

📁 基于51系列单片机控制的液晶显示程序
💻 C
字号:
/****************************************************************
本函数功能:练习LCD12864F的使用,可以显示字符,汉字,图像
缺陷:数学函数图像无法显示,无法实现滚屏,应当继续改善

	 Author:       CHANG MING
	 Create Time :        2009/3/10


注:本程序在已有程序基础上改进,并非原创,特此声明。
*****************************************************************/

#include<reg51.h>
#include<intrins.h>
#include <zm.h>		   //字模库:汉字,ASCLL码,图像
#include <math.h>	  //显示函数图像的图文件

//端口定义********************************************************
sbit LCD_WR   =  P3^0;
sbit LCD_RD   =  P3^1;
sbit LCD_CE   =  P3^2;
sbit LCD_CD   =  P3^3;
#define LCD_DATA P1

//全局变量声明*****************************************************
#define ulong unsigned long
#define uint unsigned int
#define uchar unsigned char
uchar CurCol,CurRow;
uchar uCol,uRow;//
uchar a,b;//文本指针

//T6963命令字******************************************************
#define LC_CUR_POS 0x21 // 光标位置设置
#define LC_CGR_POS 0x22 // CGRAM偏置地址设置
#define LC_ADD_POS 0x24 // 地址指针位置
#define LC_TXT_STP 0x40 // 文本区首址
#define LC_TXT_WID 0x41 // 文本区宽度
#define LC_GRH_STP 0x42 // 图形区首址
#define LC_GRH_WID 0x43 // 图形区宽度
#define LC_MOD_OR 0x80  // 显示方式:逻辑“或”
#define LC_MOD_XOR 0x81 // 显示方式:逻辑“异或”
#define LC_MOD_AND 0x82 // 显示方式:逻辑“与”
#define LC_MOD_TCH 0x83 // 显示方式:文本特征
#define LC_DIS_SW 0x9B  // 显示开关:D0=1/0:光标闪烁启用/禁用;
                                   // D1=1/0:光标显示启用/禁用;
                                  // D2=1/0:文本显示启用/禁用;
                                  // D3=1/0:图形显示启用/禁用;
#define LC_CUR_SHP 0xA0 // 光标形状选择:0xA0-0xA7 表示光标占的行数
#define LC_AUT_WR 0xB0  // 自动写设置
#define LC_AUT_RD 0xB1  // 自动读设置
#define LC_AUT_OVR 0xB2 // 自动读/写结束
#define LC_INC_WR 0xC0  // 数据一次写,地址加1
#define LC_INC_RD 0xC1  // 数据一次读,地址加1
#define LC_DEC_WR 0xC2  // 数据一次写,地址减1
#define LC_DEC_RD 0xC3  // 数据一次读,地址减1
#define LC_NOC_WR 0xC4  // 数据一次写,地址不变
#define LC_NOC_RD 0xC5  // 数据一次读,地址不变
#define LC_SCN_RD 0xE0  // 屏读
#define LC_SCN_CP 0xE8  // 屏拷贝
#define LC_BIT_OP 0xF0  // 位操作:D0-D2:定义D0-D7 位;D3:1 置位;0:清除
#define RowCharNum 8
#define ColCharNum 16

//1ms延时***********************************************
void delay(unsigned char i)
{  unsigned char j=0;
   for(;i>0;i--)
   for(j=0;j<124;j++)
   ;
}

//检查状态是否忙*****************************************
void CheckStatus(void)
{
	LCD_WR  = 1;
    LCD_CE  = 0;	   //片选信号
    LCD_DATA= 0XFF;
    LCD_CD  = 1;
    LCD_RD  = 0;
    _nop_();
    _nop_();
    while((LCD_DATA & 0x03)!=0x03);
    LCD_RD  = 1;
}

//检查自动写状态是否忙**********************************
void CheckAutoWrite(void)
{

	LCD_WR  = 1;
    LCD_DATA= 0XFF;
    LCD_CE  = 0;
    LCD_CD  = 1;
    LCD_RD  = 0;
    _nop_();
    _nop_();
    while((LCD_DATA & 0x08)==0x00);  //低电平忙 
    LCD_RD  = 1;        
}

//写数据*************************************************
void WriteData(uchar dat)
{
	CheckStatus();
    
	LCD_RD  = 1;
    LCD_CE  = 0;
    LCD_CD  = 0;   //数据	
    LCD_WR  = 0;
	LCD_DATA= dat;
    _nop_();
    _nop_();
    LCD_WR  = 1;
    delay(2);
}

//写指令*************************************************
void WriteCmd(uchar dat)
{
	CheckStatus();

    LCD_RD  = 1;
    LCD_CE  = 0;
    LCD_CD  = 1;   //指令	
    LCD_WR  = 0;
	LCD_DATA= dat;
    _nop_();
    _nop_();
    LCD_WR  = 1;
  	delay(5);
}

//先写数据,后写指令,只含一个参数的指令******************
void WriteOneData(uchar commd,uchar dat)
{
	CheckStatus();

	WriteData(dat);
	CheckStatus();

	WriteCmd(commd);
}

//含两个参数的指令*****************************************
void WriteTwoData(uchar commd,uchar dat1,uchar dat2)
{
	CheckStatus();

	WriteData(dat1);
	CheckStatus();

	WriteData(dat2);
	CheckStatus();

	WriteCmd(commd);
}

//清屏*****************************************************
void cls(uchar dat)
{
	uint i;
	WriteTwoData(LC_ADD_POS,0x00,0x00);  // 置地址指针
    //CheckAutoWrite();				    //自动写忙判断 ,易进入死循环!!!!!!!!!!!!
	WriteCmd(LC_AUT_WR);            	// 自动写
	for(i=0;i<16*64;i++)
	{
		WriteData(dat);            // 写数据
	}
	WriteCmd(LC_AUT_OVR);           // 自动写结束
	WriteTwoData(LC_ADD_POS,0x00,0x00);  // 重置地址指针  ,很重要
	CurRow = 0;                  // 置地址指针存储变量
	CurCol = 0;
}

//端口初始化***********************************************
void LCMInit(void)
{

	WriteTwoData(LC_TXT_STP,0xDF,0x01) ;   // 文本显示区首地址
	WriteTwoData(0x41,0x10,0x00);          // 文本显示区宽度
	WriteTwoData(LC_GRH_STP,0x00,0x00);    // 图形显示区首地址
	WriteTwoData(LC_GRH_WID,0x10,0x00);    // 图形显示区宽度
  //WriteCmd(0x90);                       // 光标形状
 
 	WriteTwoData(0x21,0x06,0x02);
	WriteCmd(0x81);                   // 显示方式设置
	WriteCmd(0x98);                   // 显示开关设置
	cls(0x00);
}

//可以单独使用的模块函数1,row表示屏上第几行共4行,col表示列,可以分别显示16个8*16字符
//显示单个字符函数****************************************
void ShowChar(uchar row,uchar col,uchar ch)
{
	uchar i;
	uchar dat;
	unsigned int StartAddr;
	while(col>15)
	{
		col=col-16;
		row=row+1;
	}
	if (row>3) return;
	StartAddr=(row<<8)+col;
	for (i=0;i<16;i++)
	{    
		dat=ASCII86[(ch-32)*16+i];
		WriteTwoData(0x24,(uchar)(StartAddr),(uchar)(StartAddr>>8));//将要送入的数据存放的位置
		WriteOneData(0xc4,dat);
		StartAddr=StartAddr+ColCharNum;	      //每行共进行16次编址,每8点一次
	}
}

//可以单独使用的模块函数2,*puts表示一个字符串,i表示字符串中字符的个数
//显示多个字符******************************************************
void ShowLine(uchar row,uchar col,uchar *puts,uchar i)
{
  uchar j,byte,k;
  while(col>15)
  {
     col=col-16;
     row=row+1;
  }
  if (row>3)  return;//看首行是否超出屏幕

  for (k=col,j=0;j<i;j++)
  {
  	byte = puts[j];    
    ShowChar(row,k,byte);
    k=k+1; 
  }
 }

//可以单独使用的模块函数3,每行可显示8个16*16字符,扫描方式为行扫描
//n表示将要显示的字符在字符库HANZI[]中的位置
//显示汉字****************************************************
void ShowHZ(uchar row,uchar col,uint n)
{
   unsigned char i;
   unsigned int StartAddr;

	while(col>14)
	{
     col=col-16;
     row=row+1;
    }
	if (col<0) col=0;

	if (row>3)  return;

	StartAddr=(row<<8)+col; //定位起始单元地址 ,好方法

	for(i=0;i<16;i++)
	{
		WriteTwoData(0x24,(unsigned char)(StartAddr),(unsigned char)(StartAddr>>8));
		WriteOneData(0xc0,HANZI[n*32+i*2]); //左半部 地址加一
		WriteOneData(0xc4,HANZI[n*32+i*2+1]); //右半部 字模地址加一
		StartAddr=StartAddr + ColCharNum;		 //下一行字符首地址
	}
}

/*
//可以单独使用的模块函数4,用于显示图片

⌨️ 快捷键说明

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