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点阵液晶的朋友有所帮助.
但是看了已后,觉得自已做的时候还是有很多要注意的地方.于是就写了下面的内容:
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点阵液晶的朋友有所帮助.
相关文章推荐
- lcd 12864液晶 显示图片
- 12864液晶驱动源码,独创中英文混合输出
- 12864液晶深入学习笔记_1——基于msp430g2553
- LCD-读液晶型号
- 转帖玩转12864液晶:3串行驱动
- 【连载】【FPGA黑金开发板】Verilog HDL那些事儿--LCD(12864)封装(二十一)
- 用12864液晶作了一个万年历
- AVR 单片机小学期 12864液晶 双人贪吃蛇游戏
- 12864液晶菜单设计-转子傻孩子
- 利用SPI驱动12864液晶
- HT1621B驱动液晶LCD连接及程序
- 12864液晶显示问题
- FPGA驱动12864液晶
- 51单片机12864液晶字符显示
- STM32驱动ST7920的12864液晶(串行方式)
- 推箱子,12864液晶实物
- 12864lcd显示屏多级菜单代码实现
- DIY MP3与FM STM32F103RCT6 sd SPI ff9 LCD液晶 触摸
- 液晶12864(KS0108主控)
- stm32接12864液晶,用串口好,还是并口好?串口速度能有多快?能满足哪些方面的需求?