您的位置:首页 > 其它

lcd 12864液晶

2009-06-05 13:43 375 查看
前一段时间想搞一下点阵LCD,于是就到本网站上寻找,找到了好多资料,xiaotanlan朋友的资料很好,http: //www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=468165&bbs_page_no=1&sub_kind_id=2065&bbs_id=1000
但是看了已后,觉得自已做的时候还是有很多要注意的地方.于是就写了下面的内容:

LCD12864液晶说明(个人跟椐datasheet的理解):
lcd12864分为左半屏和右半屏,每半个屏幕竖着排列着64(0~63)个字节,每个字节最低位在最上面,高位在最下面,一个字节的8位构成了lcd12864一页中一列的8个点,而它共有8页,即在y方向有8*8=64个点.如下图:



画点的重点:
1,通过x坐标所属的左右半屏.
2,通过y坐标算出点所属的页,及一页内y坐标(即一个字节中一位的位置).
3,读出原来要画点位字节内容,再设要画的点(否则会擦除原来画的点).
程序如下:
环境:ATmega8L, WinAVR GCC, LCD12864, Proteus6.7
/*
ATmega8L LCD12864
作者:zhb2000
*/
#include <avr/io.h>
#define uchar unsigned char
#define uint unsigned int
#define bool unsigned char
#define true 1
#define false 0
#define setbit(sfr,bit) (sfr|=(1<<bit))
#define clrbit(sfr,bit) (sfr&=~(1<<bit))
#define RS 0
#define RW 1
#define CS1 2
#define CS2 3
#define E 4
#define RST 5
#define DATA PORTB
#define CTRL PORTC

void init(void);
uchar getState(void); //得到LCD状态字
bool lcdBusy(void);
void lcdCommand(uchar command); //发送命令字
void lcdOpen(void); //打开LCD
void lcdStartLine(uchar line); //设置起始行
void lcdSetPage(uchar page); //设置页地址
void lcdSetRow(uchar row); //设置列地址
void lcdWrite(uchar dat,uchar cs); //写显示数据,注'0'亮'1'暗
uchar lcdRead(uchar cs); //读数据
void pixel(uchar x,uchar y); //画点
int main(void)
{
init();
lcdOpen();
lcdStartLine(0);
lcdSetPage(0);
lcdSetRow(0);
pixel(30,30);
pixel(100,50);
pixel(15,40);
while(1)
{
}
return 0;
}

void init()
{
PORTB=0xff;
DDRB=0xff;
PORTC=0xff;
DDRC=0xff;
PORTD=0xff;
DDRD=0xff;
}

uchar getState()
{
PORTB=0xff;
DDRB=0x0;
clrbit(CTRL,CS1);
clrbit(CTRL,CS2);
clrbit(CTRL,RS);
setbit(CTRL,RW);
setbit(CTRL,E); //下降沿
clrbit(CTRL,E);
return PINB;
}

bool lcdBusy()
{
uchar state=0;
state=getState();
if(state&0x80)
{ //BUSY
return true;
}
else
{ //idle
return false;
}
}

void lcdCommand(uchar command)
{
DDRB=0xff;
clrbit(CTRL,CS1);
clrbit(CTRL,CS2);
clrbit(CTRL,RS);
clrbit(CTRL,RW);
DATA=command;
setbit(CTRL,E); //下降沿
clrbit(CTRL,E);
}

void lcdOpen()
{
while(lcdBusy());
lcdCommand(0x3f);
}

void lcdStartLine(uchar line)
{
line|=0xc0;
while(lcdBusy());
lcdCommand(line);
}

void lcdSetPage(uchar page)
{
page&=0x7;
page|=0xb8;
while(lcdBusy());
lcdCommand(page);
}

void lcdSetRow(uchar row)
{ //设置列地址
row&=0x3f;
row|=0x40;
while(lcdBusy());
lcdCommand(row);
}

void lcdWrite(uchar dat,uchar cs)
{ //写显示数据
while(lcdBusy());
DDRB=0xff;
if(cs==1)
{ //选择左半屏
clrbit(CTRL,CS1);
setbit(CTRL,CS2);
}
else
{ //选择右半屏
clrbit(CTRL,CS2);
setbit(CTRL,CS1);
}
setbit(CTRL,RS);
clrbit(CTRL,RW);
DATA=dat;
setbit(CTRL,E); //下降沿
clrbit(CTRL,E);
}

uchar lcdRead(uchar cs)
{ //读数据
uchar dat;
while(lcdBusy());
DDRB=0x00;
PORTB=0xff;
if(cs==1)
{ //选择左半屏
clrbit(CTRL,CS1);
setbit(CTRL,CS2);
}
else
{ //选择右半屏
clrbit(CTRL,CS2);
setbit(CTRL,CS1);
}
setbit(CTRL,RS);
setbit(CTRL,RW);
setbit(CTRL,E); //下降沿
clrbit(CTRL,E);
setbit(CTRL,E); //高
dat=PINB;
return dat;
}

void pixel(uchar x,uchar y)
{
uchar page,dX,dY;
uchar cs=2;
uchar dot=0;
if(x>=64)
{
x-=64;
}
else
{
cs=1;
}
dX=x; //算出x坐标
page=y/8; //算出页号
dY=y%8; //算出y坐标
lcdSetPage(page);
lcdSetRow(dX);
dot=lcdRead(cs);
clrbit(dot,dY);
lcdSetPage(page);
lcdSetRow(dX);
lcdWrite(dot,cs);
}

Proteus6.7仿真:



原程序及仿真文件:
点击此处下载armok01104632.rar

希望对想学LCD12864点阵液晶的朋友有所帮助.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: