单片机控制12864液晶显示程序.docx
《单片机控制12864液晶显示程序.docx》由会员分享,可在线阅读,更多相关《单片机控制12864液晶显示程序.docx(29页珍藏版)》请在冰豆网上搜索。
![单片机控制12864液晶显示程序.docx](https://file1.bdocx.com/fileroot1/2023-1/28/e8227b38-0d8b-41c4-9eef-ba6a08b5ff51/e8227b38-0d8b-41c4-9eef-ba6a08b5ff511.gif)
单片机控制12864液晶显示程序
/**********************************
//=函数原型:
Pixel(unsignedcharPointX,unsignedcharPointY,bitMode)
//=功能:
在指定坐标位置显示一个点
//=参数:
坐标,显示点或清除点
//=返回值:
//=函数性质:
私有函数
//=如果显示屏超过了256*256,请修改这个函数PointX,PointY的类型
//=Mode1:
显示0:
清除该点
**********************************/
Pixel(unsignedcharPointX,unsignedcharPointY,bitMode)
{
unsignedintStartAddr;
unsignedchardat;
StartAddr=(uint)PointX*30+PointY/8+grhome;
dat=LC_BIT_OP+7-PointY%8;//生产位操作命令画点的数据
if(Mode)dat=dat|0x08;
wr_cmd_2(LC_ADD_POS,StartAddr);//设置该点所在单元地址
wr_cmd_0(dat);//利用位操作命令画点
}
/**********************************
//=函数原型:
voidline(unsignedcharx1,unsignedchary1,unsignedcharx2,unsignedchary2,bitMode)
//=功能:
划线函数
//=参数:
坐标1,坐标2,显示点或清除点
//=返回值:
//=函数性质:
私有函数
//=其它:
显示点阵不超过255*255
/**********************************/
voidline(unsignedchary1,unsignedcharx1,unsignedchary2,unsignedcharx2,bitMode)
{
unsignedcharx,y;
floatk,b;
if(abs(y1-y2)<=abs(x1-x2))//|k|<=1
{
k=((float)y2-y1)/((float)x2-x1);
b=y1-k*x1;
if(x1<=x2)
{
for(x=x1;x<=x2;x++)
{
y=(uchar)(k*x+b);
Pixel(x,y,Mode);
}
}
else
{
for(x=x2;x<=x1;x++)
{
y=(uchar)(k*x+b);
Pixel(x,y,Mode);
}
}
}
else//abs(y1-y2)>abs(x1-x2)|K|>1
{
k=((float)x2-x1)/((float)y2-y1);
b=x1-k*y1;
if(y1<=y2)
{
for(y=y1;y<=y2;y++)
{
x=(uchar)(k*y+b);
Pixel(x,y,Mode);
}
}
else
{
for(y=y2;y<=y1;y++)
{
x=(uchar)(k*y+b);
Pixel(x,y,Mode);
}
}
}
}
/***********************************/
/*LCM(RT-240128TA)显示程序*/
/*LCM控制芯片T6963C带32KRAM*/
/*MCU型号:
STC89C52RD2*/
/*时钟频率:
11.0592MHz*/
/*接口方式:
直接接口(总线方式)*/
/*开发环境:
KeilC51V7.03*/
/*开发日期:
2006.07.01*/
/*程序编写:
liu1234*/
/***********************************/
#definet6963c_c1
#include"t6963c3.h"
uinttxthome,grhome;
/**********************************
//=函数原型:
ucharcheck_cmd_st()
//=功能:
查询是否可读写命令和数据的状态
//=参数:
//=返回值:
非0不忙,否则忙
//=函数性质:
私有函数
**********************************/
ucharcheck_cmd_st(void)//状态位STA1,STA0判断(读写指令和读写数据)
{
uchari;
for(i=100;i>0;i--)
{
if((LCMCP&0x03)==0x03)
break;
}
returni;//若返回零,说明错误
}
/**********************************
//=函数原型:
ucharcheck_ar_st
//=功能:
查询是否可数据自动读状态
//=参数:
//=返回值:
非0不忙,否则忙
//=函数性质:
私有函数
**********************************/
ucharcheck_ar_st(void)//状态位ST2判断(数据自动读状态)
{
uchari;
for(i=100;i>0;i--)
{
if((LCMCP&0x04)==0x04)
break;
}
returni;//若返回零,说明错误
}
/**********************************
//=函数原型:
ucharcheck_aw_st
//=功能:
查询是否可数据自动写状态
//=参数:
//=返回值:
非0不忙,否则忙
//=函数性质:
私有函数
**********************************/
ucharcheck_aw_st(void)//状态位ST3判断(数据自动写状态)
{
uchari;
for(i=100;i>0;i--)
{
if((LCMCP&0x08)==0x08)
break;
}
returni;//若返回零,说明错误
}
/**********************************
//=函数原型:
ucharcheck_scrPeek_st()
//=功能:
查询是否可屏读/屏拷贝状态状态
//=参数:
//=返回值:
非0不忙,否则忙
//=函数性质:
私有函数
**********************************/
ucharcheck_scrPeek_st(void)//状态位ST6判断(屏读/屏拷贝状态)
{
uchari;
for(i=100;i>0;i--)
{
if((LCMCP&0x40)==0x40)
break;
}
returni;//若返回零,说明错误
}
/**********************************
//=函数原型:
ucharwr_cmd_2(ucharuCmd,uintuPar)
//=功能:
给T6963C写带双参数的指令
//=参数:
//=返回值:
返回0成功,否则忙
//=函数性质:
私有函数
**********************************/
ucharwr_cmd_2(ucharuCmd,uintuPar)//写双参数的指令
{
if(check_cmd_st()==0)return1;
LCMDP=(uchar)(uPar&0xFF);//先写低字节,再写高字节
if(check_cmd_st()==0)return2;
LCMDP=(uchar)(uPar>>8);
if(check_cmd_st()==0)return3;
LCMCP=uCmd;
return0;//返回0成功
}
/**********************************
//=函数原型:
ucharwr_cmd_1(ucharuCmd,ucharuPar1)
//=功能:
给T6963C写带单参数的指令
//=参数:
//=返回值:
返回0成功,否则忙
//=函数性质:
私有函数
**********************************/
ucharwr_cmd_1(ucharuCmd,ucharuPar)//写单参数的指令
{
if(check_cmd_st()==0)return1;
LCMDP=uPar;
if(check_cmd_st()==0)return2;
LCMCP=uCmd;
return0;//返回0成功
}
/**********************************
//=函数原型:
ucharwr_cmd_0(ucharuCmd)
//=功能:
给T6963C写无参数的指令
//=参数:
//=返回值:
返回0成功,否则忙
//=函数性质:
私有函数
**********************************/
ucharwr_cmd_0(ucharuCmd)//写无参数的指令
{
if(check_cmd_st()==0)return1;
LCMCP=uCmd;
return0;//返回0成功
}
/**********************************
//=函数原型:
ucharwr_data(ucharuData)
//=功能:
给T6963C写一次数据
//=参数:
//=返回值:
返回0成功,否则忙
//=函数性质:
私有函数
**********************************/
ucharwr_data(ucharuData)//写一次数据
{
if(check_cmd_st()==0)return1;
LCMDP=uData;
return0;//返回0成功
}
/**********************************
//=函数原型:
ucharawr_data(ucharuData)
//=功能:
给T6963C写一个地址增加自动连续数据
//=参数:
//=返回值:
返回0成功,否则忙
//=函数性质:
私有函数
**********************************/
ucharawr_data(ucharuData)//自动写数据
{
if(check_aw_st()==0)return1;
LCMDP=uData;
return0;//返回0成功
}
/**********************************
//=函数原型:
ucharard_data(ucharuData)
//=功能:
从T6963C读一个地址增加自动连续数据
//=参数:
//=返回值:
返回0成功,否则忙
//=函数性质:
私有函数
**********************************/
ucharard_data(void)//自动读数据
{
if(check_ar_st()==0)return1;
returnLCMDP;
}
/**********************************
//=函数原型:
voidchar_addr_Pointer_Set(ucharurow,ucharucol)
//=功能:
根据字符的行列设置vram地址
//=参数:
//=返回值:
//=函数性质:
私有函数
**********************************/
voidchar_addr_Pointer_Set(ucharurow,ucharucol)
{
uintiPos;
iPos=urow*30+ucol+txthome;
wr_cmd_2(LC_ADD_POS,iPos);
}
/**********************************
//=函数原型:
Clr_char_Scr(void)
//=功能:
清除当前文本屏幕
//=参数:
//=返回值:
//=函数性质:
公有函数
**********************************/
voidClr_char_Scr(void)//文本屏可以在内存中保持很多屏
{
uinti;
//char_addr_Pointer_Set(0,0);//从0行0列开始
char_addr_Pointer_Set(2,0);//从0行0列开始
wr_cmd_0(LC_AUT_WR);//自动写
//for(i=0;i<16*30;i++)//16行30列字符
for(i=0;i<14*30;i++)//16行30列字符
{
awr_data(0x00);//写数据空白
}
wr_cmd_0(LC_AUT_OVR);//自动写结束
char_addr_Pointer_Set(0,0);//重置地址指针
}
/**********************************
//=函数原型:
Clr_lcdram(void)
//=功能:
清除所有的显示内存
//=参数:
//=返回值:
//=函数性质:
私有函数
**********************************/
voidClr_lcdram(void)
{
uinti;
wr_cmd_2(LC_ADD_POS,0x0000);//设置地址指针0
wr_cmd_0(LC_AUT_WR);//自动写
for(i=0;i<=DISRAM_SIZE;i++)
{
awr_data(0x00);//写数据
}
wr_cmd_0(LC_AUT_OVR);//自动写结束
wr_cmd_2(LC_ADD_POS,0x0000);//重置地址指针
}
/**********************************
//=函数原型:
reset_lcm(void)
//=功能:
复位液晶模块
//=参数:
//=返回值:
//=函数性质:
私有函数
**********************************/
voidreset_lcm(void)
{
LCMRESET=0;
_nop_();
_nop_();
LCMRESET=0XFF;
}
/**********************************
//=函数原型:
voidlcm_init(void)
//=功能:
初始化液晶模块
//=参数:
//=返回值:
//=函数性质:
公有函数
**********************************/
voidlcm_init(void)
{
reset_lcm();//复位
wr_cmd_2(LC_TXT_HOME,TXTSTART);//文本显示区首地址
wr_cmd_2(LC_TXT_AREA,30);//文本显示区宽度30列
txthome=TXTSTART;
wr_cmd_2(LC_GRH_HOME,GRSTART);//图形显示区首地址
wr_cmd_2(LC_GRH_AREA,30);//图形显示区宽度30列
grhome=GRSTART;
wr_cmd_2(LC_CGR_OFFSET,CGRAMSTART>>11);//CGRAM偏移地址设置
wr_cmd_0(LC_MOD_XOR|0x08);//显示方式设置,异或,字符全部用RAM区域生成
wr_cmd_0(LC_DIS_SW|0x0c);//显示开关设置,图文混和模式
Clr_lcdram();//清除内存
}
/**********************************
//=函数原型:
Pixel(unsignedcharPointX,unsignedcharPointY,bitMode)
//=功能:
在指定坐标位置显示一个点
//=参数:
坐标,显示点或清除点
//=返回值:
//=函数性质:
私有函数
//=如果显示屏超过了256*256,请修改这个函数PointX,PointY的类型
//=Mode1:
显示0:
清除该点
**********************************/
Pixel(unsignedcharPointX,unsignedcharPointY,bitMode)
{
unsignedintStartAddr;
unsignedchardat;
StartAddr=(uint)PointX*30+PointY/8+grhome;
dat=LC_BIT_OP+7-PointY%8;//生产位操作命令画点的数据
if(Mode)dat=dat|0x08;
wr_cmd_2(LC_ADD_POS,StartAddr);//设置该点所在单元地址
wr_cmd_0(dat);//利用位操作命令画点
}
/**********************************
//=函数原型:
voidline(unsignedcharx1,unsignedchary1,unsignedcharx2,unsignedchary2,bitMode)
//=功能:
划线函数
//=参数:
坐标1,坐标2,显示点或清除点
//=返回值:
//=函数性质:
私有函数
//=其它:
显示点阵不超过255*255
/**********************************/
voidline(unsignedchary1,unsignedcharx1,unsignedchary2,unsignedcharx2,bitMode)
{
unsignedcharx,y;
floatk,b;
if(abs(y1-y2)<=abs(x1-x2))//|k|<=1
{
k=((float)y2-y1)/((float)x2-x1);
b=y1-k*x1;
if(x1<=x2)
{
for(x=x1;x<=x2;x++)
{
y=(uchar)(k*x+b);
Pixel(x,y,Mode);
}
}
else
{
for(x=x2;x<=x1;x++)
{
y=(uchar)(k*x+b);
Pixel(x,y,Mode);
}
}
}
else//abs(y1-y2)>abs(x1-x2)|K|>1
{
k=((float)x2-x1)/((float)y2-y1);
b=x1-k*y1;
if(y1<=y2)
{
for(y=y1;y<=y2;y++)
{
x=(uchar)(k*y+b);
Pixel(x,y,Mode);
}
}
else
{
for(y=y2;y<=y1;y++)
{
x=(uchar)(k*y+b);
Pixel(x,y,Mode);
}
}
}
}
/**********************************
//=函数原型:
voidShowChar(ucharrow,ucharcol,ucharch)
//=功能:
在指定行列显示8*16字符
//=参数:
坐标行,坐标列,字符串指针
//=返回值:
//=函数性质:
公有函数
//=其它:
所有可显示字符不超过128个,否则本函数有溢出的可能
**********************************/
voidshowchar(ucharcol,ucharrow,uchar*chp)
{
#definehzpchp
ucharchar_sequence_number;
ucharascii_num;
row/=8;col/=8;
while(*chp!
='\0')
{
if(*chp<0x80)//西文
{
for(char_sequence_number=0;ASCII_SUB_INDEX[char_sequence_number]!
='\0';char_sequence_number++)
{
if(ASCII_SUB_INDEX[char_sequence_number]==*chp)
{
chp++;
break;
}
}
if(ASCII_SUB_INDEX[char_sequence_number]=='\0'){chp++;char_sequence_number=1;}
char_sequence_number*=2;//一个ASCII字符占两个8*8字符
//写字符上半部分
char_addr_Pointer_Set(row,col);//设置Vram地址
wr_data(char_sequence_number);//写数据
wr_cmd_0(LC_UNCHANGED_WR);//写命令
//写字符下半部分
row+=1;//下半部分在下一行
char_addr_Pointer_Set(row,col);//设置Vram地址
wr_data(char_sequence_number+1);//写数据
wr_cmd_0(LC_UNCHANGED_WR);//写命令
//行列地址自动指向下个字符位