一下是用12864 绘制出的图
本文作者:林子木
本人学历有限,如有纰漏请见谅!
的补充,是基于430单片机的实现,很简单的可以移植到51单片机上去
如果想具体的实现,请先看上面网址的文章
以下是"Lcd_12664.h"声明代码,注意一定需要,或者也可以写在.c的前面或者,后者函数不能调用前者的函数
voidDelay_1ms(void);
voidDelay(unsignedintn);
voidWrite_Cmd(unsignedcharcod);
voidWrite_Data(unsignedchardat);
voidIni_Lcd(void);
voidDisp_HZ(unsignedcharaddr,constunsignedchar*pt,unsignedcharnum);
voidDisp_ND(unsignedcharaddr,unsignedint thickness);
voidDraw_TX(unsignedcharYaddr,unsignedcharXaddr,constunsignedchar*dp);
voidDraw_PM(constunsignedchar*ptr);
voidDraw_PM_CLR(void);
voidDraw_Point(unsignedcharx,unsignedchary);
unsignedchar Read_Data(void);
unsignedintRead_Add(unsignedcharx,unsignedchary);
Lcd_12664.c
以下标注为红色的,是我们需要注意的地方
#include<msp430x14x.h>
#include"subfuncs.h"
typedefunsignedcharuchar;
typedefunsignedint uint;
externconstunsignedcharshuzi_table[];
#defineLCD_DataIn P4DIR=0x00 //数据口方向设置为输入
#defineLCD_DataOut P4DIR=0xff //数据口方向设置为输出
#defineLCD2MCU_Data P4IN
#defineMCU2LCD_Data P4OUT
#defineLCD_CMDOut P3DIR|=0x07 //P3口的低三位设置为输出
#defineLCD_RS_H P3OUT|=BIT0 //P3.0
#defineLCD_RS_L P3OUT&=~BIT0 //P3.0
#defineLCD_RW_H P3OUT|=BIT1 //P3.1
#defineLCD_RW_L P3OUT&=~BIT1 //P3.1
#defineLCD_EN_H P3OUT|=BIT2 //P3.2
#defineLCD_EN_L P3OUT&=~BIT2 //P3.2
/*******************************************
函数名称:Delay_1ms
功 能:延时约1ms的时间
参 数:无
返回值 :无
********************************************/
voidDelay_1ms(void)
{
uchari;
for(i=150;i>0;i--) _NOP();
}
/*******************************************
函数名称:Delay_Nms
功 能:延时N个1ms的时间
参 数:n--延时长度
返回值 :无
********************************************/
voidDelay_Nms(uintn)
{
uinti;
for(i=n;i>0;i--) Delay_1ms();
}
/*******************************************
函数名称:Write_Cmd
功 能:向液晶中写控制命令
参 数:cmd--控制命令
返回值 :无
********************************************/
voidWrite_Cmd(ucharcmd)
{
ucharlcdtemp=0;
LCD_RS_L;
LCD_RW_H;
LCD_DataIn;
do //判忙
{
LCD_EN_H;
_NOP();
lcdtemp=LCD2MCU_Data;
LCD_EN_L;
}
while(lcdtemp&0x80);
LCD_DataOut;
LCD_RW_L;
MCU2LCD_Data=cmd;
LCD_EN_H;
_NOP();
LCD_EN_L;
}
/*******************************************
函数名称:Write_Data
功 能:向液晶中写显示数据
参 数:dat--显示数据
返回值 :无
********************************************/
void Write_Data(uchardat)
{
ucharlcdtemp=0;
LCD_RS_L;
LCD_RW_H;
LCD_DataIn;
do //判忙
{
LCD_EN_H;
_NOP();
lcdtemp=LCD2MCU_Data;
LCD_EN_L;
}
while(lcdtemp&0x80);
LCD_DataOut;
LCD_RS_H;
LCD_RW_L;
MCU2LCD_Data=dat;
LCD_EN_H;
_NOP();
LCD_EN_L;
}
/*******************************************
函数名称:Ini_Lcd
功 能:初始化液晶模块
参 数:无
返回值 :无
********************************************/
voidIni_Lcd(void)
{
LCD_CMDOut; //液晶控制端口设置为输出
Delay_Nms(500);
Write_Cmd(0x30); //基本指令集
Delay_1ms();
Write_Cmd(0x02); // 地址归位
Delay_1ms();
Write_Cmd(0x0c); //整体显示打开,游标关闭
Delay_1ms();
Write_Cmd(0x01); //清除显示
Delay_1ms();
Write_Cmd(0x06); //游标右移
Delay_1ms();
Write_Cmd(0x80); //设定显示的起始地址
}
/*******************************************
函数名称:Disp_HZ
功 能:控制液晶显示汉字
参 数:addr--显示位置的首地址
pt--指向显示数据的指针
num--显示字符个数
返回值 :无
********************************************/
voidDisp_HZ(ucharaddr,constuchar*pt,ucharnum)
{
uchari;
Write_Cmd(addr);
for(i=0;i<(num*2);i++)
Write_Data(*(pt++));
}
/*******************************************
函数名称:Clear_GDRAM
功 能:清除液晶GDRAM中的随机数据
参 数:无
返回值 :无
********************************************/
voidClear_GDRAM(void)
{
uchari,j,k;
Write_Cmd(0x34); //打开扩展指令集
i=0x80;
for(j=0;j<32;j++)
{
Write_Cmd(i++);
Write_Cmd(0x80);
for(k=0;k<16;k++)
{
Write_Data(0x00);
}
}
i=0x80;
for(j=0;j<32;j++)
{
Write_Cmd(i++);
Write_Cmd(0x88);
for(k=0;k<16;k++)
{
Write_Data(0x00);
}
}
Write_Cmd(0x30); //回到基本指令集
}
/*******************************************
函数名称:Draw_PM
功 能:在整个液晶屏幕上画图
参 数:无
返回值 :无
********************************************/
voidDraw_PM(constuchar*ptr)
{
uchari,j,k;
Write_Cmd(0x34); //打开扩展指令集
i=0x80;
for(j=0;j<32;j++)//32Y(Y是以位位单位,所以是32)32*2
{ //X是以word为单位的 所以为16
Write_Cmd(i++);
//写入Y的地址0x80 代表0//RWRSDB7DB6DB5DB4DB3DB2DB1DB0
//L L H AC6AC5AC4AC3AC2AC1AC0
Write_Cmd(0x80); // 写入X的地址
for(k=0;k<16;k++)//16*8=128
{
Write_Data(*ptr++);//写入数据(8位)
}
}
i=0x80;
for(j=0;j<32;j++)
{
Write_Cmd(i++);
Write_Cmd(0x88);
for(k=0;k<16;k++)
{
Write_Data(*ptr++);
}
}
Write_Cmd(0x36); //打开绘图显示
Write_Cmd(0x30); //回到基本指令集
}
/*******************************************
函数名称:Draw_TX
功 能:显示一个16*16大小的图形
参 数:Yaddr--Y地址
Xaddr--X地址
dp--指向图形数据存放地址的指针
返回值 :无
********************************************/
voidDraw_TX(ucharYaddr,ucharXaddr,constuchar*dp)
{
ucharj;
uchark=0;
Write_Cmd(0x01); //清屏,只能清除DDRAM
Write_Cmd(0x34); //使用扩展指令集,关闭绘图显示
for(j=0;j<16;j++)
{
Write_Cmd(Yaddr++); //Y地址
Write_Cmd(Xaddr); //X地址
Write_Data(dp[k++]);
Write_Data(dp[k++]);
}
Write_Cmd(0x36); //打开绘图显示
Write_Cmd(0x30); //回到基本指令集模式
}
/*******************************************
函数名称:Draw_Point
功 能:在整个液晶屏幕上画图
参 数:无
返回值 :无
********************************************/
voidDraw_Point(unsignedcharx,unsignedchary)
{
uintdat=0; //读取需要写入的两个字节的值
dat=Read_Add(x,y); //注意,因为read 或者 write之后 地址指针AC会自动加
+ 想对莫一块进行读和写的工作,就需要重新写入地址
if(x>127)x=127;
if(y>63) y=63;
uchary_Byte,y_bit,x_Byte,x_bit;
y_Byte=y/32; //0:上半屏幕 1:下半屏幕
y_bit=y%32; //y的行号
x_Byte=x/16; //x的列号
x_bit=x%16; //x的位
Write_Cmd(0x34); //打开扩展指令集
Write_Cmd(0x80+31-y_bit); //因为液晶y是从上往下的,这里简单的转换成从下
往上
Write_Cmd(0x80+x_Byte+(1-y_Byte)*8);//(1-y_Byte)*8 代表上下半页
if(x_bit>7) //因为是地址是两个字节,但是写入还是一个一个字节
的,所以需要判断
{
Write_Data(0x00|((dat>>8)&0xff));
Write_Data((0x80>>x_bit%8)|(dat&0xff));//因为液晶显示,高位在前
} //如如果想把第八位点亮 直接写
0x80 那么会 成100000000
else //而不是我们要的从左到右的 第八
位 00000001 所以需要转换下
{
Write_Data((0x80>>x_bit%8)|((dat>>8)&0xff));
Write_Data(0x00|(dat&0xff));
}
Write_Cmd(0x36); //打开绘图显示
Write_Cmd(0x30); //回到基本指令集
}
/*******************************************
函数名称:Read_Data
功 能:读取液晶屏幕的值
参 数:无
返回值 :无
********************************************/
uchar Read_Data(void)
{
ucharlcdtemp=0;
uchardat=0;
LCD_RS_L;
LCD_RW_H;
LCD_DataIn; //设置为输入方式
do //判忙
{
LCD_EN_H;
_NOP();
lcdtemp=LCD2MCU_Data;
LCD_EN_L;
}
while(lcdtemp&0x80);
LCD_RS_H; //置高
LCD_RW_H; //置高
_NOP();
LCD_EN_H; //使能
_NOP();
dat=LCD2MCU_Data;//读数据
_NOP();
LCD_EN_L;
return(dat);
}
/*******************************************
函数名称:Read_Add
功 能:读取液晶屏幕莫一点的值
参 数:无
返回值 :无
********************************************/
unsignedintRead_Add(unsignedcharx,unsignedchary)
{
unsignedintdat;
uchardat_H=0,dat_L=0;
if(x>127)x=127;
if(y>63) y=63;
uchary_Byte,y_bit,x_Byte,x_bit;
y_Byte=y/32; //0:上半屏幕 1:下半屏幕
y_bit=y%32; //y的行号
x_Byte=x/16; //x的列号
x_bit=x%16; //x的位
Write_Cmd(0x34); //打开扩展指令集
Write_Cmd(0x36); //打开绘图显示
Write_Cmd(0x80+31-y_bit);
Write_Cmd(0x80+x_Byte+(1-y_Byte)*8);
Read_Data(); //
Read_Data(); //
RReeaadd__DDaattaa(());; ////注意:读操作要先执行有一个空读命令
dat_H=Read_Data();
dat_L=Read_Data();
Write_Cmd(0x30); //回到基本指令集
dat=dat_H*0x0100+dat_L;
returndat;
}
完整的pdf格式文档51黑下载地址:
lcd12864-绘图功能实现驱动.pdf
(2.46 MB, 下载次数: 93)
|