久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

專注電子技術學習與研究
當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

240_128_lcd 51單片機總線驅動-速度到達最大

作者:佚名   來源:本站原創   點擊數:  更新時間:2012年02月08日   【字體:


 

全部源代碼下載:http://www.zg4o1577.cn/f/128yhj.rar

 

#include"reg51.h"
sbit cd = P2^0;
unsigned char pdata *addr;
#define uchar unsigned  char
#define uint unsigned short
void lcd_writecom_two(uchar onedat,uchar twodat,uchar com);
void lcd_writedat_onebyte(uchar onedat,uchar com);
uchar lcd_readdat_onebyte(uchar com);
void lcd_writedat_nbyte(uchar *dat,uchar len);
void lcd_readdat_nbyte(uchar *dat ,uchar len);
void clear_point(uchar x,uchar y);
void sel_point(uchar x,uchar y);
void sel_rmiddling(uchar x,uchar y);
void clr_rmiddling(uchar x,uchar y);
void sel_rbig(uchar x,uchar y);
void clr_rbig(uchar x,uchar y);
void graph_mode_writeword(uchar x,uchar y,uchar *dat);
void graph_mode_write_letter(uchar x,uchar y,uchar *dat);
void rhorizontal(uchar x0,uchar x1,uchar y);
void erect(uchar y0,uchar y1,uchar x);
void Draw_line(uchar x0,uchar y0,uchar x1,uchar y1);
void draw_circle(int x, int y, int r);
void lcd_init();
/**********************************
       讀取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);
}
/*********************************
   判斷數據自動讀忙碌狀態
*********************************/
void check_auto_read_busy()
{
 uchar temp;
 do{
   temp=lcd_readcom();
   }while((temp&0x04)!=0x04);
}
/*********************************
       向lcd寫命令
*********************************/
void lcd_writecom(uchar dat)
{
check_busy();
 cd=1;
 *addr = dat;
}
/************************************
        向lcd寫數據
************************************/
void lcd_writedat(uchar dat)
{
check_busy();
 cd=0;
 *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_writecom(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);
}
/****************************************
       一次讀n個數據   對應地址指針位置
****************************************/
void lcd_readdat_nbyte(uchar *dat ,uchar len)
{
 
   lcd_writecom(0xb1);
   check_auto_read_busy();
    while(len)
   {
 
    *dat=lcd_readdat();
 dat++;
     len--;
   }
   lcd_writecom(0xb2);
}
/************************************************
 清除一個點坐標 X,Y  左上角第一個點為0,0
************************************************/
void clear_point(uchar x,uchar y)
{
 uint addr;
 uchar temp1,temp2;
 addr=(y<<5)+(y<<3)+(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<<5)+(y<<3)+(x>>3);//32+8
 temp1=addr;//&0x00ff;
 temp2=addr>>8;
 lcd_writecom_two(temp1,temp2,0x24);
 lcd_writecom(0xff-(x&0x07));
}
/*************************************************
  畫中等大小的點 4*4(用畫點方法   效率低)
*************************************************/
/*sel_middling(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%6;
  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;
 }
}*/
/*************************************************
  畫中等大小的點 4*4(用讀修改寫   效率高)
*************************************************/
void sel_rmiddling(uchar x,uchar y)
{
  uint addr;
  uchar temp1,temp2,n,dat;
 addr=(y<<7)+(y<<5)+(x>>1);//x/8*4;//128+32
 for(n=0;n<4;n++)
 {
  temp1=addr;//&0x0ff;
  temp2=addr>>8;
  lcd_writecom_two(temp1,temp2,0x24);
  if(x&0x01)//x%2
  {
  dat=(lcd_readdat_onebyte(0xc5))|0x0f;
  lcd_writedat_onebyte(dat,0xc4);
  }
  else
  {
  dat=(lcd_readdat_onebyte(0xc5))|0xf0;
  lcd_writedat_onebyte(dat,0xc4);
  }
  addr+=40;
 }
}
/*************************************************
  清楚中等大小的點 4*4(用清點方式   效率底)
*************************************************/
/*clr_middling(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%6;
  temp2=addr>>8;
  lcd_writecom_two(temp1,temp2,0x24);
  if(x%2)
  {
  lcd_writecom(0xf3);
  lcd_writecom(0xf2);
  lcd_writecom(0xf1);
  lcd_writecom(0xf0);
  }
  else
  {
  lcd_writecom(0xf7);
  lcd_writecom(0xf6);
  lcd_writecom(0xf5);
  lcd_writecom(0xf4);
  }
  addr+=40;
 }
}*/
/*************************************************
  清楚中等大小的點 4*4(用讀修改寫   效率高)
*************************************************/
void clr_rmiddling(uchar x,uchar y)
{
  uint addr;
  uchar temp1,temp2,n,dat;
 addr=(y<<7)+(y<<5)+(x>>1);//x/8*4;//128+32
 for(n=0;n<4;n++)
 {
  temp1=addr;//&0xff;
  temp2=addr>>8;
  lcd_writecom_two(temp1,temp2,0x24);
  if(x&0x01)
  {
  dat=(lcd_readdat_onebyte(0xc5))&0xf0;
  lcd_writedat_onebyte(dat,0xc4);
  }
  else
  {
  dat=(lcd_readdat_onebyte(0xc5))&0x0f;
  lcd_writedat_onebyte(dat,0xc4);
  }
  addr+=40;
 }
}
/*********************************************************
      畫8*8的大點(用畫點方式  速度慢)
*********************************************************/
/*void sel_big(uchar x,uchar y)
{
  uint addr;
  uchar temp1,temp2,n;
 addr=(y<<8)+(y<<6)+(x);//x/8*4;y*320=y*(256+64)=(y<<8)+(y<<6)
 for(n=0;n<8;n++)
 {
  temp1=addr&0x00ff;//addr%6
  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+=40;
 }
}
*/
/*********************************************************
      畫8*8的大點(用讀改寫方式  速度快)
*********************************************************/
void sel_rbig(uchar x,uchar y)
{
  uint addr;
  uchar temp1,temp2,n,dat;
 addr=(y<<8)+(y<<6)+(x);//x/8*4;y*320=y*(256+64)=(y<<8)+(y<<6)
 for(n=0;n<8;n++)
 {
  temp1=addr;//&0x00ff;//addr%6
  temp2=addr>>8;
  lcd_writecom_two(temp1,temp2,0x24);
  //dat=(lcd_readdat_onebyte(0xc5))|0xff;
  dat=0xff;
  lcd_writedat_onebyte(dat,0xc4);
  addr+=40;
 }
}
/*********************************************************
       清楚8*8的大點(用畫點方式  速度慢)
*********************************************************/
/*void clr_big(uchar x,uchar y)
{
  uint addr;
  uchar temp1,temp2,n;
 addr=(y<<8)+(y<<6)+(x);//x/8*4;y*320=y*(256+64)=(y<<8)+(y<<6)
 for(n=0;n<8;n++)
 {
  temp1=addr&0x00ff;//addr%6
  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+=40;
 }
}
*/
/*********************************************************
       清除8*8的大點(用讀修改寫方式  速度快)
*********************************************************/
void clr_rbig(uchar x,uchar y)
{
  uint addr;
  uchar temp1,temp2,n,dat;
 addr=(y<<8)+(y<<6)+(x);//x/8*4;y*320=y*(256+64)=(y<<8)+(y<<6)
 for(n=0;n<8;n++)
 {
  temp1=addr;//&0x00ff;//addr%6
  temp2=addr>>8;
  lcd_writecom_two(temp1,temp2,0x24);
  //dat=(lcd_readdat_onebyte(0xc5))|0x00;
  dat=0x00;
  lcd_writedat_onebyte(dat,0xc4);
  addr+=40;
 }
}
/*************************************************************
          圖形方式   屏上寫漢字 16*16
************************************************************/
void graph_mode_writeword(uchar x,uchar y,uchar *dat)
{
  uint addr;
  uint temp1;
  uchar n;
  temp1=y;temp1=(temp1<<9)+(temp1<<7);//512+128
  addr=temp1+(x<<1);
   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+40;
  }
}
/*************************************************************
       圖形方式   屏上寫字母,數字 8*16
************************************************************/
void graph_mode_write_letter(uchar x,uchar y,uchar *dat)
{
  uint addr;
  uint temp1;
  uchar n;
  temp1=y;temp1=(temp1<<9)+(temp1<<7);//512+128
  addr=temp1+(x<<1);
   for(n=0;n<16;n++)
  {
   lcd_writecom_two((addr&0x00ff),(addr>>8),0x24);
  lcd_writedat_onebyte(*dat,0xc0);
  dat++;
  addr=addr+40;
  }
}
/******************************************************
     用畫點的方式劃橫線  (可以用讀改寫的方式)
******************************************************/
/*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);
 }
}*/
/*************************************
    劃橫線  (用讀改寫的方式)
***************************************/
uchar get_num(uchar x0)
{
uchar dat;
  switch(x0)
 {
  case 0: dat=0xff;break;
  case 1: dat=0x7f;break;
  case 2: dat=0x3f;break;
  case 3: dat=0x1f;break;
  case 4: dat=0x0f;break;
  case 5: dat=0x07;break;
  case 6: dat=0x03;break;
  case 7: dat=0x01;break;
 }
 return dat;
}
uchar get_num_n(uchar x1)
{
uchar dat;
  switch(x1)
 {
  case 0: dat=0x80;break;
  case 1: dat=0xc0;break;
  case 2: dat=0xe0;break;
  case 3: dat=0xf0;break;
  case 4: dat=0xf8;break;
  case 5: dat=0xfc;break;
  case 6: dat=0xfe;break;
  case 7: dat=0xff;break;
 }
 return dat;
}
void rhorizontal(uchar x0,uchar x1,uchar y)
{
 uint addr;
 uchar temp,n,temp1,temp2,dat,dat1;
 if(x0>x1)
 {
  temp=x0;
  x0=x1;
  x1=temp;
 }
  addr=(y<<5)+(y<<3)+(x0>>3);
  temp1=addr;//&0xff;
  temp2=addr>>8;
  lcd_writecom_two(temp1,temp2,0x24);
  lcd_writecom_two(temp1,temp2,0x24);
   n=x1-x0;
  dat1=lcd_readdat_onebyte(0xc5);
   if((x0>>3)!=(x1>>3))
 {
   
   lcd_writedat_onebyte((get_num(x0&0x3)|dat1),0xc0);
    temp1=x0>>3;
    temp2=x1>>3;
   temp=temp2-temp1-1;
      lcd_writecom(0xb0);
         check_auto_write_busy();
         while(temp)
         {
          lcd_writedat(0xff);
          temp--;
         }
          lcd_writecom(0xb2);
   
   dat1=lcd_readdat_onebyte(0xc5);
 
   lcd_writedat_onebyte((get_num_n(x1&0x03)|dat1),0xc4);
  }
    else
     {
  x0=x0&0x07;
  x1=x1%0x07;
   dat =~(get_num(x0)^get_num_n(x1));
   lcd_writedat_onebyte((dat|dat1),0xc4);
     }
}
/*****************************************
       用畫點的方式畫豎線
*****************************************/
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);
 }
}
/*******************************************************
布蘭森漢姆(Bresenham)算法畫線  兩端點(x0,y0) (x1,y1)
*******************************************************/
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)               
   erect(y0,y1,x0);
if(dy==0)                
  rhorizontal(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);
  }
     
}
}  
}
 
/****************************************************
             畫圓 圓點(x,y) 半徑 r
****************************************************/
 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(0x00,0x00,0x21);
        lcd_writecom_two(0x00,0x00,0x42);
        lcd_writecom_two(0x28,0x00,0x43);//28
        lcd_writecom_two(0x00,0x00,0x40);
        lcd_writecom_two(0x01e,0x00,0x41);//1e
        lcd_writecom(0xa0);
        lcd_writecom(0x98);
        lcd_writecom(0x80);
     }
main()
{
unsigned char i;
  lcd_init();
 Draw_line(0,0,239,127);
 Draw_line(0,127,239,0);
  Draw_line(0,0,239,0);
  Draw_line(0,127,239,127);
  Draw_line(0,0,0,127);
  Draw_line(239,0,239,127);
 while(1)
 {
 for(i=60;i<150;i++)
 draw_circle(i,64, 60);
 }
}
關閉窗口

相關文章

主站蜘蛛池模板: 天天操妹子 | 久久精品91 | 欧美日韩在线观看一区二区三区 | av中文字幕在线播放 | 在线观看你懂的网站 | 成人免费视频观看视频 | 日本午夜免费福利视频 | 久久蜜桃精品 | jvid精品资源在线观看 | av天天看 | 久久久精品视频免费看 | 日本精品视频在线观看 | 九九久久久 | 欧美日韩综合 | 一区二区三区在线 | 一区二区播放 | 国产乱码高清区二区三区在线 | 国产高清精品一区二区三区 | 国产三级国产精品 | 精品一区在线 | 亚洲视频免费在线观看 | 国产一区二区三区四区五区加勒比 | 精品欧美一区二区在线观看欧美熟 | 久久99精品久久久久久青青日本 | 精品国产乱码久久久久久蜜柚 | 久久人体视频 | 国产综合久久久久久鬼色 | 一区二区在线观看免费视频 | 亚洲综合伊人 | 国产成人一区二区三区 | 日韩高清国产一区在线 | 国产乱码精品1区2区3区 | 日韩色图视频 | 亚洲美女在线一区 | 欧美在线国产精品 | 久久久久国产一区二区三区四区 | 国产91久久精品一区二区 | 黄色片在线网站 | 日韩中文视频 | 黄色网址在线免费播放 | 精品国产伦一区二区三区观看说明 |