这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » 驱动lcd_t6963_240*128

共1条 1/1 1 跳转至

驱动lcd_t6963_240*128

助工
2014-11-13 19:45:52     打赏

#ifndef _lcd_h
#define _lcd_h
#include"reg51.h"
#define uchar unsigned  char 
#define uint unsigned short
//#define port P0
//sbit cd=P2^0;


//sbit rd=P2^1;
//sbit wr=P2^2;
//sbit ce=P2^3;
extern void lcd_init();
extern void lcd_writecom(uchar dat);
extern void sel_big(uchar x,uchar y);
extern void erect(uchar y0,uchar y1,uchar x);
extern void horizontal(uchar x0,uchar x1,uchar y);
extern void graph_mode_writeword(uchar x,uchar y,uchar *dat);
extern void word_byte(uchar row ,uchar list, uchar *pdat);
extern void lcd_writecom_two(uchar onedat,uchar twodat,uchar com);
extern void lcd_writedat_onebyte(uchar onedat,uchar com);
extern void lcd_writedat_nbyte(uchar *dat,uchar len);
extern void clear_point(uchar x,uchar y);
extern void sel_point(uchar x,uchar y);
extern void clr_big(uchar x,uchar y);
extern void draw_circle(int x, int y, int r);
extern void clr_lcd(void);
#endif


 


 


#include"lcd.h"
unsigned char pdata *addr;
sbit cd=P2^0;


/**********************************
       读取lcd状态
**********************************/
uchar lcd_readcom()
{
  uchar temp;
  cd=1;
  addr = 0xFF;
  temp = *addr;
  return temp;
}
/*********************************
   判断指令/数据读写忙碌状态
*********************************/
void check_busy()
{
 uchar temp;
 do{
   temp=lcd_readcom();
   }while((temp&0x03)!=0x03);
}
/*********************************
   判断数据自动写忙碌状态
*********************************/
void check_auto_write_busy()
{
 uchar temp;
 do{
   temp=lcd_readcom();
   }while((temp&0x08)!=0x08);
}
/*********************************
       向lcd写命令
*********************************/
void lcd_writecom(uchar dat)
{
check_busy();
 cd=1;
   addr = 0xFF;
 *addr = dat;
}
/************************************
        向lcd写数据
************************************/
void lcd_writedat(uchar dat)
{
check_busy();
 cd=0;
  addr = 0xFF;
 *addr = dat;
}
/********************************
     从lcd读数据
*********************************/
uchar lcd_readdat()
{
  uchar temp;
  cd=0;
  addr = 0xFF;
  temp = *addr;
  return temp;


}
/************************************************
  发出命令控制 参数 onedat  twodat 命令com
*************************************************/
void lcd_writecom_two(uchar onedat,uchar twodat,uchar com)
{
 lcd_writedat(onedat);
 lcd_writedat(twodat);
 lcd_writecom(com);
}
/****************************************
      一次读/写一个数据
****************************************/


void lcd_writedat_onebyte(uchar onedat,uchar com)
{
 lcd_writedat(onedat);
 lcd_writecom(com);
}


/*uchar lcd_readdat_onebyte(uchar com)
{
 uchar dat;
 lcd_writedat(com);
 dat=lcd_readdat();
 return dat;
}*/
/****************************************
       一次写n个数据
****************************************/
void lcd_writedat_nbyte(uchar *dat,uchar len)
{
   
   lcd_writecom(0xb0);
  check_auto_write_busy();
   while(len)
   {
     lcd_writedat(*dat);
  dat++;
     len--;
   }
   lcd_writecom(0xb2);
}
/************************************************
 清除一个点坐标 X,Y  左上角第一个点为0,0
************************************************/
void clear_point(uchar x,uchar y)
{
 uint addr;
 uchar temp1,temp2;
 addr=y*30+(x>>3);//32+8
 temp1=addr&0x00ff;
 temp2=addr>>8;
 lcd_writecom_two(temp1,temp2,0x24);
 lcd_writecom(0xf7-(x&0x07));
}


/************************************************
 点亮一个点 坐标 X,Y  左上角第一个点为0,0
************************************************/
void sel_point(uchar x,uchar y)
{
 uint addr;
 uchar temp1,temp2;
 addr=y*30+(x>>3);//32+8
 temp1=addr&0x00ff;
 temp2=addr>>8;
 lcd_writecom_two(temp1,temp2,0x24);
 lcd_writecom(0xff-(x&0x07));
}


void clr_lcd(void)
{
 unsigned int len ;
  len=30<<7;
 lcd_writecom_two(0,0x00,0x24);


  lcd_writecom(0xb0);
  check_auto_write_busy();
   while(len)
   {
     lcd_writedat(0x00);
     len--;
   }
   lcd_writecom(0xb2);


}
/*sel_big(uchar x,uchar y)
{
  uint addr;
  uchar temp1,temp2,n;
 addr=y*160+(x>>1);//x/8*4;
 for(n=0;n<4;n++)
 {
  temp1=addr%256;
  temp2=addr>>8;
  lcd_writecom_two(temp1,temp2,0x24);
  if(x%2)
  {



    lcd_writecom(0xfb);
  lcd_writecom(0xfa);
  lcd_writecom(0xf9);
  lcd_writecom(0xf8);
  }
  else
  {
  lcd_writecom(0xff);
  lcd_writecom(0xfe);
  lcd_writecom(0xfd);
  lcd_writecom(0xfc);


  
}
  addr+=40;
 }


}*/


void sel_big(uchar x,uchar y)
{
  uint addr;
  uchar temp1,temp2,n;
 addr=y*240+(x);//x/8*4;y*320=y*(256+64)=(y<<8)+(y<<6)
 for(n=0;n<8;n++)
 {
  temp1=addr&0x00ff;//addr%256
  temp2=addr>>8;
  lcd_writecom_two(temp1,temp2,0x24);



  lcd_writecom(0xfb);
  lcd_writecom(0xfa);
  lcd_writecom(0xf9);
  lcd_writecom(0xf8);


  lcd_writecom(0xff);
  lcd_writecom(0xfe);
  lcd_writecom(0xfd);
  lcd_writecom(0xfc);
  addr+=30;
 }


}
void clr_big(uchar x,uchar y)
{
  uint addr;
  uchar temp1,temp2,n;
 addr=y*240+(x);//x/8*4;y*320=y*(256+64)=(y<<8)+(y<<6)
 for(n=0;n<8;n++)
 {
  temp1=addr&0x00ff;//addr%256
  temp2=addr>>8;
  lcd_writecom_two(temp1,temp2,0x24);



  lcd_writecom(0xf3);
  lcd_writecom(0xf2);
  lcd_writecom(0xf1);
  lcd_writecom(0xf0);


  lcd_writecom(0xf7);
  lcd_writecom(0xf6);
  lcd_writecom(0xf5);
  lcd_writecom(0xf4);
  addr+=30;
 }


}
void graph_mode_writeword(uchar x,uchar y,uchar *dat)
{
  uint addr;
  uint temp1;   //4
  uchar n;
  temp1=y;temp1=temp1*480;//512+128  640
  addr=temp1+2*x;
   for(n=0;n<16;n++)
  {
  
  lcd_writecom_two((addr&0x00ff),(addr>>8),0x24);
  lcd_writedat_onebyte(*dat,0xc0);
  dat++;
  lcd_writedat_onebyte(*dat,0xc4);
  dat++;
  addr=addr+30;
  }
}


void word_byte(uchar row ,uchar list, uchar *pdat)
{
 uchar addr_h,addr_l,n;
 uint p_addr;
 for(n=0;n<16;n++)
 {
 p_addr=(list+n)*30+row;
 addr_h=p_addr>>8;
 addr_l=p_addr%256;
 lcd_writecom_two(addr_l,addr_h,0x24);
 lcd_writecom(0xb0);
  
  lcd_writedat(*(pdat+n));
 lcd_writecom(0xb2);


 }


}



void horizontal(uchar x0,uchar x1,uchar y)
{
 uchar temp,n;
 if(x0>x1)
 {
  temp=x0;
  x0=x1;
  x1=temp;
 }
 n=x1-x0;
 for(;n>0;n--)
 {
  sel_point(x0+n,y);
 }


}



void erect(uchar y0,uchar y1,uchar x)
{
  uchar temp,n;
 if(y0>y1)
 {
  temp=y0;
  y0=y1;
  y1=temp;
 }
 n=y1-y0;
 for(;n>0;n--)
 {
  sel_point(x,y0+n);
 }


}


 


 



void Draw_line(uchar x0,uchar y0,uchar x1,uchar y1)

int dx,dy;                //定义X.Y轴上增加的变量值 
int  sub; 
int temp;                //起点、终点大小比较,交换数据时的中间变量 
uchar flag;
if(x0>x1)                //X轴上,起点大于终点,交换数据 
   { 
   temp=x1; 
   x1=x0; 
   x0=temp;  
   temp=y1; 
   y1=y0; 
   y0=temp;    
   }


 


   
dx=x1-x0;                //X轴方向上的增量 
dy=y1-y0;                //Y轴方向上的增量 
   if(dx==0)                
   //Draw_shu(x0,y0,y1);
   erect(y0,y1,x0);
if(dy==0)                 
   //Draw_zhi(x0,x1,y0);
   horizontal(x0,x1,y0);


 



   if(dy>0)
    flag=1;
    else
    flag=0;


 


if((dx!=0)&&(dy!=0))
{
// 布兰森汉姆(Bresenham)算法画线 / 
if(flag==1)
{
  if(dx>=dy)                  //靠近X轴 
 { 
   sub=2*dy-dx;              //计算下个点的位置          
   while(x0!=x1) 
   { 
   sel_point(x0,y0);        //画起点 
     x0++;                  // X轴上加1 
     if(sub>0)                // 判断下下个点的位置 
     { 
       y0++;                  // 为右上相邻点,即(x0+1,y0+1) 
       sub+=2*dy-2*dx; 
     } 
     else          
       sub+=2*dy;            // 判断下下个点的位置          
   } 
   sel_point(x0,y0); 
 } 
     
   else 
   { 
   sub=2*dy-dx;              //靠近Y轴        
   while(y0!=y1) 
     {
   sel_point(x0,y0);        //画起点 
   y0++;                  
     if(sub>0)              //判断下下个点的位置


 


     { 
       x0++;                
       sub+=2*dx-2*dy; 
     } 
     else 
       sub+=2*dx; 
     } 
    sel_point(x0,y0); 
   } 
}
else
{
   dy=y0-y1;
   if(dx>=dy)                  //靠近X轴 
 { 
   sub=2*dy-dx;              //计算下个点的位置          
   while(x0!=x1) 
   { 
   sel_point(x0,y0);        //画起点 
     x0++;                  // X轴上加1 
     if(sub>0)                // 判断下下个点的位置 
     { 
       y0--;                  // 为右上相邻点,即(x0+1,y0+1) 
       sub+=2*dy-2*dx; 
     } 
     else          
       sub+=2*dy;            // 判断下下个点的位置          
   } 
   sel_point(x0,y0); 
 } 
 else
  {
    sub=2*dx-dy;              //靠近Y轴        
   while(y0!=y1) 
     {
   sel_point(x0,y0);        //画起点 
     y0--;                  
     if(sub>0)              //判断下下个点的位置 
     { 
       x0++;                
       sub+=2*dx-2*dy; 
     } 
     else 
       sub+=2*dx; 
     } 
    sel_point(x0,y0); 
  }
      
}
}   

 
 
 void draw_circle(int x, int y, int r)
{
    int a, b, num;
    a = 0;
    b = r;
    while(2 * b * b >= r * r)          // 1/8圆即可
    {
        sel_point(x + a, y - b); // 0~1
        sel_point(x - a, y - b); // 0~7
        sel_point(x - a, y + b); // 4~5
        sel_point(x + a, y + b); // 4~3


        sel_point(x + b, y + a); // 2~3
        sel_point(x + b, y - a); // 2~1
        sel_point(x - b, y - a); // 6~7
        sel_point(x - b, y + a); // 6~5
        
        a++;
        num = (a * a + b * b) - r*r;
        if(num > 0)
        {
            b--;
            a--;
        }
    }
}



void lcd_init()
     {
     lcd_writecom_two(0x00,0x00,0x24);
        lcd_writecom_two(0x01,0x01,0x21);
        lcd_writecom_two(0x00,0x00,0x42);
        lcd_writecom_two(0x1e,0x00,0x43);
        lcd_writecom_two(0x00,0x10,0x40);
        lcd_writecom_two(0x1e,0x00,0x41); 
        lcd_writecom(0xa0);
        lcd_writecom(0x9c);
        lcd_writecom(0x80);


     }


 


#include"lcd.h"
main()
{
 lcd_init();
 draw_circle(120, 64, 60);
 while(1);
}


共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]