返回首页

mega8——lcd12864分为左半屏和右半屏

时间:2010-05-13 22:57来源:unknown 作者:xiaoma07 点击:
2010年02月08日

  lcd12864分为左半屏和右半屏,每半个屏幕竖着排列着64(0~63)个字节,每个字节最低位在最上面,高位在最下面,一个字节的8位构成了

  2010年02月08日

  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);

  }

  转自ouravr

顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
最新评论 查看所有评论
发表评论 查看所有评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 密码: 验证码:
发布者资料
drillfpcinfocn 查看详细资料 发送留言 加为好友 用户等级:高级会员 注册时间:2009-09-11 16:09 最后登录:2010-03-18 11:03
推荐内容