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

📄 lcd12864点.c

📁 ST7920proteus仿真12864
💻 C
字号:
/***************************************************************************
标题:	LCD12864程序
效果:	本程序在LCD12864液晶屏显示图形内容

******************************************************************************/
#include "AT89X52.H"

/********IO引脚定义***********************************************************/
sbit LCD_RS=P1^0;
sbit LCD_RW=P1^1;
sbit LCD_E=P1^2;
sbit PSB =P1^6;		//PSB脚为12864-12系列的串、并通讯功能切换,我们使用8位并行接口,PSB=1

/********宏定义***********************************************************/
#define LCD_Data P0


/********函数声明*************************************************************/
void WriteDataLCD(unsigned char WDLCD);         //写数据
void WriteCommandLCD(unsigned char WCLCD);       //写指令
unsigned char ReadDataLCD(void);               //读数据
void LCDInit(void);                          //初始化
void LCDClear(void);                         //清屏

void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);
void DisplayImage (unsigned char DData);     //输出128*64点阵数据
void Delay100us(void);
void Delay1ms(unsigned int c);             //延时1毫秒
void LCDhuadian( unsigned char X, unsigned char Y,unsigned char color); //画点   color=1,点亮;color=0,擦除
void LCDshuipin( unsigned char X0, unsigned char X1, unsigned char Y,unsigned char color); //画水平线:
void LCDchuizhi( unsigned char X, unsigned char Y0, unsigned char Y1,unsigned char color);  //画垂直线:
void LCDhuaxian(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char color);

/********数据定义*************************************************************/
code unsigned char  uctech[] = {"我的单片机实验板"};


/***********主函数开始********************************************************/
void main(void)
{
 	Delay1ms(400); 	//启动等待,等LCD讲入工作状态
 	LCDInit(); 		//LCD初始化
 	while(1)
 	{
 	    LCDClear();    //清屏
	 //	Delay1ms(1000);
	 	DisplayImage(255);				//显示满屏点阵
		Delay1ms(1000);        //延时2000毫秒
		
		LCDClear();
		DisplayListChar(0,1,uctech);	//显示字库中的中文数字	
		Delay1ms(1000);

		LCDClear();
//		LCDhuadian(6,10);         //X坐标(0--127),Y坐标(0--63)

		LCDshuipin( 0, 127 , 0 , 1 );       ; //画水平线:
	    LCDshuipin( 0, 127 , 15 ,1 ) ;	    
	    LCDshuipin( 0, 127 , 31 ,1 ) ;	    
	    LCDshuipin( 0, 127 , 47 ,1 ) ;
	    LCDshuipin( 0, 127 , 63 ,1 ) ;

	    LCDchuizhi( 0,   0 , 63 ,1 ) ;       //画垂直线:
	    LCDchuizhi( 31,  0 , 63 ,1 ) ;
	    LCDchuizhi( 64,  0 , 63, 1 ) ;
	    LCDchuizhi( 96,  0 , 63 ,1 ) ;
		LCDchuizhi( 127, 0 , 63 ,1 );
		Delay1ms(2000);


        LCDClear();
		LCDhuaxian( 0,  0, 127, 63 , 1 ) ;
       	LCDhuaxian( 0,  0, 32,  63 , 1 ) ;
        LCDhuaxian( 32, 0, 127, 63 , 1 ) ;
        Delay1ms(2000);

	}
}

/***********写数据********************************************************/
void WriteDataLCD(unsigned char WDLCD)
{
    Delay100us(); //延时100微秒,检测忙 
 	LCD_RS = 1;
 	LCD_RW = 0;
 	LCD_Data = WDLCD;
 	LCD_E = 1;
 	LCD_E = 1;
 	LCD_E = 1;
 	LCD_E = 0;
}

/***********写指令********************************************************/
void WriteCommandLCD(unsigned char WCLCD) 
{
    Delay100us(); //延时100微秒,检测忙  
 	LCD_RS = 0;
 	LCD_RW = 0; 
 	LCD_Data = WCLCD;
 	LCD_E = 1; 
 	LCD_E = 1;
 	LCD_E = 1;
 	LCD_E = 0;  
}


/***********读数据********************************************************/
unsigned char ReadDataLCD(void)
{
	unsigned char LCDDA;
	LCD_Data=0xff;
    Delay100us(); //延时100微秒,检测忙  
 	LCD_RS = 1; 
 	LCD_RW = 1;
 	LCD_E = 1;
 	LCD_E = 1;
	LCDDA=LCD_Data;
 	LCD_E = 0;
 	return(LCDDA);
}


/***********初始化********************************************************/
void LCDInit(void)
{
	WriteCommandLCD(0x34);
 	WriteCommandLCD(0x30); //显示模式设置,开始要求每次检测忙信号
 	WriteCommandLCD(0x01); //显示清屏
 	WriteCommandLCD(0x06); // 显示光标移动设置
 	WriteCommandLCD(0x0C); // 显示开及光标设置
}

/***********清屏********************************************************/	
void LCDClear(void) 
{
 	WriteCommandLCD(0x01); //显示清屏
 	WriteCommandLCD(0x34); // 显示光标移动设置
 	WriteCommandLCD(0x30); // 显示开及光标设置
}



//**************画点函数**************//X坐标(0--127),Y坐标(0--63)color=1,点亮;color=0,擦除
void LCDhuadian( unsigned char X, unsigned char Y ,unsigned char color)
{
	unsigned char x_1, lcd_x , lcd_y, yushu;
    unsigned char  Read_H, Read_L  ;
    WriteCommandLCD( 0x34 ) ;               //设置扩充指令集,关闭绘图
    WriteCommandLCD( 0x36 ) ;             // 扩充指令集,打开绘图
		lcd_x=X/16;
	    yushu=X % 16;

    if( Y < 32 )
      {
        lcd_y=Y ;
		x_1=0x80;
      }
    else
      {
		lcd_y = Y - 32;
		x_1=0x88;
      }

    WriteCommandLCD( 0x80+lcd_y) ;
    WriteCommandLCD( x_1+lcd_x) ;

 //  WriteCommandLCD( 0x30 ) ;              

    ReadDataLCD() ;
    Read_H = ReadDataLCD() ; 
    Read_L = ReadDataLCD() ; 
		

      if (color)

	       {
					if( yushu < 8 )
			       
				   {
				    Read_H|=(1<<(7-yushu));
				   }
				else
				   {
			        Read_L|=(1<<(15-yushu));
				   }
         	}
       else		
	        {	
		        if( yushu < 8 )
			       
				   {
				    Read_H&=~(1<<(7-yushu));
				   }
				else
				   {
		         	Read_L&=~(1<<(15-yushu));
				   }
	         }

//		WriteCommandLCD( 0x34 ) ;               //设置扩充指令集,关闭绘图  
	         
		WriteCommandLCD( 0x80+lcd_y) ;
        WriteCommandLCD( x_1+lcd_x) ;  

//      WriteCommandLCD( 0x30 ) ;               
        WriteDataLCD( Read_H ) ;

        WriteDataLCD( Read_L ) ;
	 
 //    WriteCommandLCD( 0x36 ) ;               //设置扩充指令集,打开绘图 

    WriteCommandLCD( 0x30 )    ;
}



//*********画水平线:X0起始X1结束坐标(0--127),Y坐标(0--63)
void LCDshuipin( unsigned char X0, unsigned char X1, unsigned char Y,unsigned char color )
{    unsigned char Temp ;
    if( X0 > X1 )
    {
        Temp = X1 ;
        X1  = X0 ;
        X0  = Temp ;
    }
	for( ; X0 <= X1 ; X0++ )
    LCDhuadian( X0, Y,color) ;    
}



//*********画垂直线:X坐标(0--127),Y0起始Y1结束坐标(0--63)
void LCDchuizhi( unsigned char X, unsigned char Y0, unsigned char Y1,unsigned char color)
{
    unsigned char Temp ;
    if( Y0 > Y1 )
    {
        Temp = Y1 ;
        Y1  = Y0 ;
        Y0  = Temp ;
    }
    for( ; Y0 <= Y1 ; Y0++)
    LCDhuadian( X, Y0,color) ;
}


//************Bresenham画线算法画线

/*函数说明:使用Bresenham法,画任意两点间的直线
传入参数:(x0,y0),竖直线的起点;(x1,y1)竖直线的终点
				color=1,点亮;color=0,擦除
传出参数:无
返回值:  无
*************************************************************/
void LCDhuaxian(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char color)
{
   int   dx;		// 直线x轴差值变量
   int   dy;        // 直线y轴差值变量
   char   dx_sym;	// x轴增长方向,为-1时减值方向,为1时增值方向
   char   dy_sym;	// y轴增长方向,为-1时减值方向,为1时增值方向
   int   dx_2;		// dx*2值变量,用于加快运算速度
   int   dy_2;		// dy*2值变量,用于加快运算速度
   int   di;		// 决策变量

   dx = x1-x0;		// 求取两点之间的差值
   dy = y1-y0;
   if (dx<0)		dx_sym=-1;
   else
   {
	   if(dx>0)	dx_sym=1; 
	   else				
	   {
	   		(x0,y0,y1,color);
			return;
		}
	}
   if(dy>0)			dy_sym=1;
   else 
   {
	   if(dy<0)	dy_sym=-1;
	   else				
	   {
	   		LCDshuipin(x0,y0,x1,color);
			return;
		}
	}
   dx=dx_sym*dx;
   dy=dy_sym*dy;

   dx_2=dx*2;
   dy_2=dy*2;

   if(dx>=dy)
   {
	di=dy_2-dx;
	while(x0!=x1)
		{
		 LCDhuadian(x0,y0,color);
		 x0+=dx_sym;
		 if(di<0)	di+=dy_2;
		 else	{di+=dy_2-dx_2;y0+=dy_sym;}
		}
	LCDhuadian(x0,y0,color);
	}
   else
   {
   di=dx_2-dy;
   while(y0!=y1)
   		{
		 LCDhuadian(x0,y0,color);
		 y0+=dy_sym;
		 if(di<0)	di+=dx_2;
		 else		{di+=dx_2-dy_2;x0+=dx_sym;}
		}
	LCDhuadian(x0,y0,color);
   }
 
}






/***********按指定位置显示一个字符*******************************************/	
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
{
	if(Y<1)
 		Y=1;
	if(Y>4)
 		Y=4;
	X &= 0x0F; 			//限制X不能大于16,Y不能大于1
	switch(Y)
	{
	   case 1:X|=0X80;break;
	   case 2:X|=0X90;break;
	   case 3:X|=0X88;break;
       case 4:X|=0X98;break;
	}
	WriteCommandLCD(X); //发送地址码
	WriteDataLCD(DData);
}

/***********按指定位置显示一串字符*****************************************/
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
{
	unsigned char ListLength,X2;
	ListLength = 0;
	X2=X;
	if(Y<1)
 		Y=1;
	if(Y>4)
 		Y=4;
 	X &= 0x0F; 				//限制X不能大于16,Y在1-4之内
 	switch(Y)
 	  {
		case 1:X2|=0X80;break;	//根据行数来选择相应地址
		case 2:X2|=0X90;break;
		case 3:X2|=0X88;break;
		case 4:X2|=0X98;break;
	  }
 	WriteCommandLCD(X2); 	//发送地址码
  	while (DData[ListLength]>=0x20){ //若到达字串尾则退出
   		if (X <= 0x0F) 
   		{ 			//X坐标应小于0xF
     		WriteDataLCD(DData[ListLength]);
    	 	ListLength++;
	 		X++;
	 		Delay1ms(5);
    	}
  	}
}

/********输出128*64点阵数据************************************************/
void DisplayImage (unsigned char DData)
{
	unsigned char x,y,i;
   	WriteCommandLCD(0x34);
	for(i=0;i<9;)           //分两屏,上半屏和下半屏,因为起始地址不同,需要分开
		{					
	      for(y=0;y<32;y++)   //32行 
	   					   
	//	WriteCommandLCD(0x34);
	//	WriteCommandLCD(0x80+y);	//列地址
	//	WriteCommandLCD(0x80+i);	//行地址,下半屏,即第三行地址0X88
	//	WriteCommandLCD(0x30);
		
		    for(x=0;x<8;x++)
	          { 
		        WriteCommandLCD(0x80+y);	//列地址
		        WriteCommandLCD(0x80+x+i);
			    WriteDataLCD(DData);//读取数据写入LCD
			    WriteDataLCD(DData);//读取数据写入LCD	
		      }	
	      i+=8;
	    }
	WriteCommandLCD(0x36);			//扩充功能设定
	WriteCommandLCD(0x30);
}


//************100微秒延时*******************************************************
void Delay100us(void)   //误差 0us
{
    unsigned char a,b;
    for(b=1;b>0;b--)
        for(a=47;a>0;a--);
}
//****************(i x 1毫秒延时)******************************************
void Delay1ms(unsigned int c)   //延时函数误差 0us
{
    unsigned char a,b;
    for(;c>0;c--)
        for(b=142;b>0;b--)
            for(a=2;a>0;a--);
}













⌨️ 快捷键说明

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