⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lcd12864_driver.c

📁 该程序是基于c8051f020的平台
💻 C
字号:
#include <c8051f020.h>
#include <math.h>
#include "delay.h"
#include "LCD12864_Driver.h"

#define uchar  unsigned char
#define uint   unsigned int

//初始化-----------------------------
void Lcd_Ini(void)
{
     RST=1;
     Delay(100,100);
     RST=0;       //复位
     Delay(100,100);
     RST=1;
     Delay(100,100);

     WR=1;RD=1;CD=1;


    // Clr_Char_Area() ;
     //Clr_Graph_Area();

     Send_cmd1(0x80); //设置显示方式: CGROM方式 文本与图形或显示
     Send_cmd3(0x00,0x00,0x21);    //光标位置
     Send_cmd1(0xa7);             //设置光标形状 cursor size 8x8                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     


     Send_cmd3(0x00,0x00,0x40);    //文本区首地址设置
     Send_cmd3(0x10,0x00,0x41);    //字符宽度:16*16,可设置
     Send_cmd3(0x00,0x04,0x42);    //图形区首址设置
     Send_cmd3(0x10,0x00,0x43);    //宽度

     Send_cmd1(0x94);            //设置显示开关:启用文本显示 禁止图形显示
     // Send_cmd1(0x98);          //设置显示开关:禁止文本显示启用图形显示  /****显示汉字和动画时选用****/
    
     Send_cmd1(0x80);          //设置显示开关:启用文本显示 启用图形显示 
     //Send_cmd1(0x90);            //设置显示开关:禁止文本显示 禁止图形显示
}

 
void ShowChar(unsigned char lin,unsigned char column, uchar str[])
{
  unsigned int i;        //定义字符显示个数变量
  unsigned int StartAddr; //起始地址变量
  uchar temp;
 
  
  StartAddr=lin*16+column; //定位起始行
  Send_cmd3((unsigned char)StartAddr,0x00, 0x24); //set address

  Send_cmd1(0xb0);//自动写方式
  for(i=0;str[i]!=0;i++)
     {
         temp = str[i] - 0x20;  
         Send_data(temp);        //写字符
      }
  Send_cmd1(0xb2);//退出自动写

}

 


void ShowHZ(unsigned char lin,unsigned char column,uchar HZTable[],uchar HZ_num )
{  unsigned char i,j;     //i为汉字点阵字节数变量,j为显示汉字个数变量
   unsigned int StartAddr; //定义起始地址变量
   unsigned int Abos_Addr;
   unsigned char tcolumn; //每个汉字显示的开始列地址

  // StartAddr = 0x0400;   // Send_cmd3(0x00,0x04,0x40);    与文本区首地址设置保持一致

   for(j=0;j<HZ_num;j++)
       {  tcolumn=column+j*2;
          StartAddr=lin*16 + tcolumn; //定位起始行

          for(i=0;i<32;i++)  //一个汉字共32字节,一次显示两字节,共显示16次
            { Abos_Addr=StartAddr + 0x0400;
              Send_cmd3((unsigned char)(Abos_Addr),(unsigned char)(Abos_Addr>>8), 0x24);
              Send_cmd2( HZTable[j*32+i], 0xc0); //左半部 地址加一
              Send_cmd2( HZTable[j*32+i+1], 0xc4); //右半部 字模地址加一
			  i++;
              StartAddr=StartAddr + 16; //下一字节先地址
             }
       }

}


void ShowPicture(unsigned char Startline,unsigned char Startcolumn,unsigned char LineWidth,unsigned char ColumnWidth,unsigned char code * address,unsigned int StartAddr)
{   unsigned char i,j; //i为列宽变量,j为行宽变量
    unsigned int StartAddr0;//定义起始地址变量

//    StartAddr = 0x0400;   // Send_cmd3(0x00,0x04,0x40);    与文本区首地址设置保持一致
    StartAddr0=StartAddr + Startline*16 + Startcolumn; //定位起始位置

    for(i=0;i<ColumnWidth;i++) //汉字为16*16点阵,ColumnWidth为16,以像数计算
      {  Send_cmd3( (unsigned char)(StartAddr0), (unsigned char)(StartAddr0>>8),0x24); //set address
         
         for(j=0;j<LineWidth;j++) //LineWidth为2,以字节计算
           {  //Send_cmd2( *(address+i*LineWidth+ j ), 0xc0); //写数据,地址增一
              Send_cmd2( *(address+i*LineWidth+ j ), 0xc0); //写数据,地址增一
           }
         StartAddr0=StartAddr0 + 16;  //图片下一个字节的地址
     }  
}


//清理字符区-----------------------------------

void Clr_Char_Area(void)
{
    uint i;
    Send_cmd3(0x00,0x00,0x24);
    Send_cmd1(0xb0);                  //自动写设置
    for (i=0;i<128;i++)
       {
          // Autowr_check();
           Send_data(0x00);

       }
    Send_cmd1(0xb3);                  //自动读/写结束

    Send_cmd3(0x00,0x00,0x24);
}


//=========================================
 //清理图形区
void Clr_Graph_Area(void)
{
    uint i;
    Send_cmd3(0x00,0x04,0x24);            //地址指针位置
    Send_cmd1(0xb0);                   //自动读设置
    for (i=0;i<1024;i++) 
      {
          // Autowr_check();
           Send_data(0x00);
          
      }     		   
    Send_cmd1(0xb3);                   //自动读/写结束
    Send_cmd3(0x00,0x04,0x24);
}    


void Locat_Dot(uchar x_loc, uchar y_loc)
{
     uint StartAddr;//定义起始地址变量   volatile
     uchar dot_data,ori_data, move;
     uchar Line,Column;

    y_loc = 63 - y_loc ;
    Column = x_loc/8;  
    Line = y_loc;

    StartAddr = 0x0400;   // Send_cmd3(0x00,0x04,0x40);    与文本区首地址设置保持一致
    StartAddr =StartAddr +  Line*16 + Column;
    Send_cmd3( (unsigned char)(StartAddr), (unsigned char)(StartAddr>>8),0x24);
    
     Send_cmd1(0xc5);     // 数据读,地址不变
     Delay(5,4);         // 本来读端口数据时,要把端口配为漏极,且向端口写“1”Data_Port=0XFF; 但在函数Send_cmd(0xc5);里面已经包括了该句
     CD=0;CE=0;RD=0;WR=1; 
     ori_data=Data_Port;
     Delay(10,5);
     CD=1;RD=1;CE=1;  
     
    move = x_loc%8;  dot_data = 0x80>>move;
    dot_data = dot_data | ori_data;
    Send_cmd2(dot_data, 0xc4);   // 地址不变

}


void Line(uchar x1,uchar y1,uchar x2,uchar y2)
{   char i;
    //y1 = 64 - y1 ;
    //y2 = 64 - y2 ;

    char x,y;
	float y_add;
	x=x2-x1;
	y=y2-y1;
	if(x==0)
      {	     
		 if(y>0)
		  {
		  	  for(i=0;i<y;i++)	
			    {
                  Locat_Dot(x1,y1+i);
			    }
		  }
		 else if(y==0)
		     Locat_Dot(x1,y1);
		 else
		  {
		     for(i=y;i<0;i++)	
			   {
                  Locat_Dot(x1,y1+i);
			   }
		  }

	  }
	else 
	   y_add = y*1.000/x;
	if(x>0)
	{
	  if(y_add <=1&&y_add>=-1)
	   {
	     for(i=0;i<x;i++)	
	      {
		    y=y1+y_add*i;
		    Locat_Dot(x1+i,y);
	      }
	   }
	 else
	  {
	    if(y>0)
		 {
		   for(i=0;i<y;i++)
		    {
			  x=x1+i/y_add;
			  Locat_Dot(x,y1+i);
			}
		 }
		 else if(y==0)
		  {
		     for(i=0;i<x;i++)	
	          {
		         Locat_Dot(x1+i,y1);
	          }
		  }
		 else
		 {
		    for(i=y;i<0;i++)
		    {
			  x=x1+i/y_add;
			  Locat_Dot(x,y1+i);
			}
		 }

	  } 
	   
	}
   else if(x<0)
    {	   
	  if(y_add <=1&&y_add>=-1)
	   {
	     for(i=x;i<0;i++)	
	      {
		    y=y1+y_add*i;
		    Locat_Dot(x1+i,y);
	      }
	   }
	  else
	  {
	    if(y>0)
		 {
		   for(i=0;i<y;i++)
		    {
			  x=x1+i/y_add;
			  Locat_Dot(x,y1+i);
			}
		 }
		 else if(y==0)
		  {
		     for(i=x;i<0;i++)	
	          {
		         Locat_Dot(x1+i,y1);
	          }
		  }
		 else
		 {
		    for(i=y;i<0;i++)
		    {
			  x=x1+i/y_add;
			  Locat_Dot(x,y1+i);
			}
		 }

	  } 
    }
   
      
}

void Circle(uchar x1,uchar y1,uchar R)
{
   uchar x,y;
   uint a,b;

  // y1 = 64 - y1 ;

   for(x=x1-R;x<=x1+R;x++)
     {  
        for(y=0;y<=64;y++)
          {  a=(abs(x-x1))*(abs(x-x1));
             b=(abs(y-y1))*(abs(y-y1));
             if( ((a+b)<=R*R) && ((a+b)>=(R-1)*(R-1))){ 
             Locat_Dot(x,y); }
          }
      }
}             
         


//读状态==================================
uchar Read_state()
{
     uchar sta;
     Data_Port=0xff;
     CD=1;CE=0;RD=0;WR=1; 
     sta=Data_Port;
     Delay(10,5);
     RD=1;CE=1;RD=1;CD=1;
     return(sta);
}
//发指令-----------------------------------					          



//2字节数据--------------------------
//
void Send_cmd2(uchar d1,uchar c)
{
     Send_data(d1);
     Send_cmd1(c);
}


//3字节数据--------------------------
//设置光标指针,CGRAM偏置地址,地址指针,
//显示区域设置
void Send_cmd3(uchar d1,uchar d2,uchar c)  
{
     Send_data(d1);
     Send_data(d2);
     Send_cmd1(c);
}

//发数据--------------------

void Send_data(uchar d)
{
     uchar s1,D1;
     D1=d;
     do
     {s1=Read_state();}
     while((s1)&0x03!=0x03);//R_sta check;
	 Data_Port=D1;
     CD=0; CE=0; WR=0;
     Delay(10,5);   	   
     CE=1; WR=1;RD=1;CD=1;
     Data_Port=0XFF;
}

void Send_cmd1(uchar c)
{
     uchar s0,c1;
     c1=c;
     do
     {s0=Read_state();}
     while(((s0)&0x03)!=0x03);//r_cmd check;
	 Data_Port=c1;
     CD=1; CE=0;  WR=0;RD=1;
     
     Delay(10,5);
     CE=1;RD=1; WR=1;CD=1;
     Data_Port=0XFF;
}
/*
void PORT_Init ()
{
      XBR2=0X40;
      P1MDOUT=0XFF; 
      P2MDOUT=0XFF;
      P74OUT=0X00;  //读端口数据时,要把端口配为漏极,且向端口写“1”Data_Port=0XFF;
}*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -