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

📄 lcd_1602_driver._c

📁 LCD1602四线接口应用范例(AVR_GCC)
💻 _C
字号:
#include <iom8v.h>
#include <macros.h>
#include "LCD_1602.h"
#include "test.h"
void delay_nms(unsigned int n);
void delay_nus(unsigned int n);
unsigned char lcd_data[32];//32字节显存,记录LCD上显示的数据
unsigned char data[32];//32字节缓存,保存将要写入LCD的数据
unsigned char add;//显存地址标号
unsigned char new=32;//显存标号 
unsigned int num=0;
/**********************************************************
TC1602B LCD DISPLAY
建立时间:2005年12月12号
修改日期:2005年12月12号
LCD_write函数功能:当command=0时,向LCD写入数据,否则向LCD写
                   入命令
LCD第一行显示寄存器地址:0X80-0X8F
LCD第二行显示寄存器地址:0XC0-0XCF
**********************************************************/
void LCD_init(void)
  { 
     LCD_EN_DDR|=LCD_EN;//设定该引脚方向为输出
	 LCD_RS_DDR|=LCD_RS;//设定该引脚方向为输出
	 LCD_D4_DDR|=LCD_D4;//设定数据口为输出 
	 LCD_D5_DDR|=LCD_D5;//设定数据口为输出  
	 LCD_D6_DDR|=LCD_D6;//设定数据口为输出  
	 LCD_D7_DDR|=LCD_D7;//设定数据口为输出
	 
	  LCD_EN_PORT&=~LCD_EN;//EN设为低电平
	  LCD_RS_PORT&=~LCD_RS;//RS设为低电平
	  LCD_D4_PORT&=~LCD_D4;//数据口置低电平
	  LCD_D5_PORT&=~LCD_D5;//数据口置低电平
	  LCD_D6_PORT&=~LCD_D6;//数据口置低电平
	  LCD_D7_PORT&=~LCD_D7;//数据口置低电平
	  
    LCD_write_char(0,0x33);      //4bit test
	delay_nms(25);
	LCD_write_char(0,0x32);
	delay_nms(15);
	LCD_write_char(0,0x28);
	delay_nms(15);
    LCD_write_char(0,0x0C);      //显示开
	delay_nms(15);
    LCD_write_char(0,0x01);      //显示清屏
	delay_nms(15);
    LCD_write_char(0,0x06);      //显示光标移动设置	
	LCD_clear();
	delay_nms(10);
	LCD_init_CGRAM(); 
  }
/*-----------------------------------------------------------------------
LCD_write_char    : 写一个字节到LCD的函数
编写日期             :2005-12-12 
最后修改日期      :2005-12-12 		
-----------------------------------------------------------------------*/
void LCD_write_char(unsigned command,unsigned data)
  { 
    if (command == 0)
   	LCD_RS_PORT &= ~LCD_RS;   //RS=0  写地址
	else
    LCD_RS_PORT |= LCD_RS;    //RS=1 写数据
	
    LCD_write_DATA_PORT(data);//写高4位
    LCD_write_DATA_PORT(data<<4);//写低4位
	delay_nus(250);
	num++;//统计向LCD发送的字节数
  }
/*-----------------------------------------------------------------------
LCD_write_DATA_PORT : 写数据到LCD数据口函数

输入参数data   :要写入的数据(仅高4位)
编写日期          :2005-12-12
最后修改日期   :2005-12-12 		
-----------------------------------------------------------------------*/
void LCD_write_DATA_PORT(unsigned char data)
{   
    if((data>>4)%2)
	  LCD_D4_PORT |=LCD_D4;
	else
	  LCD_D4_PORT &=~LCD_D4;
	
	if((data>>5)%2)
	  LCD_D5_PORT |=LCD_D5;
	else
	  LCD_D5_PORT &=~LCD_D5;
	  
	if((data>>6)%2)
	  LCD_D6_PORT |=LCD_D6;
	else
	  LCD_D6_PORT &=~LCD_D6;
	  
	if((data>>7)%2)
	  LCD_D7_PORT |=LCD_D7;
	else
	  LCD_D7_PORT &=~LCD_D7;
	  
	  LCD_EN_PORT |= LCD_EN; //EN端产生一个由低电平变高电平,写LCD
	  delay_nus(25);
      LCD_EN_PORT &= ~LCD_EN; //EN端产生一个由高电平变低电平,写LCD
	  delay_nus(25);
}
/*-----------------------------------------------------------------------
LCD_clear    : 清除屏幕的函数

输入参数      :无
编写日期      :2005/10/18	
       说明      :	lcd_data[]也会被清0
-----------------------------------------------------------------------*/
void LCD_clear(void)
  {  
     unsigned char i;
     LCD_write_char(0,0x01);//显示清屏
	 for(i=0;i<32;i++)
	   {
	      lcd_data[i]=0;
	   }
	   delay_nus(500);
  }
/*-----------------------------------------------------------------------
LCD_check   : 统计发送数据到LCD次数的函数

输入参数      :x,y 显示结果的座标
编写日期      :2005/10/18	
       说明      :如果每秒调用一次,就是统计每秒的次数
-----------------------------------------------------------------------*/ 
void LCD_check(unsigned char x,unsigned char y) //检测每秒钟写LCD
                                                                      //次数的函数
  {  
    unsigned char  i;
	unsigned char  lcd[2]={0};
	add=y*16+x;//设置起始座标
        lcd[0]=num/10+48;
		lcd[1]=num%10+48;
	num=0;  
   for (i=0;i<2;i++) 
      {
              if(lcd_data[add]==lcd[i]){}
			  else
			     {data[add]=lcd[i];}
		          add++;
      }
	LCD_updata;
  }
/*-----------------------------------------------------------------------
LCD_write_string  : 英文字符串显示函数

输入参数:*s       :英文字符串指针;
                 X、Y    : 显示字符串的位置
				 e          : 把从最后一个字符到x=e之间的内容删除
编写日期          :2005/10/18		
-----------------------------------------------------------------------*/
void LCD_write_string(unsigned char x,unsigned char y, const unsigned char *s,unsigned char e)
  { 
    if(y<2)
	add=y*16+x;//设置起始座标
    while (*s) 
      { 
	    if(lcd_data[add]==*s)//如果LCD上显示的数和
		   {}                             //待写入的数相同的话
		else{data[add]=*s;}//要显示的数据存入显存
	       s ++;//指针加1
	       add++;//显存地址加1
      }
	  if(y==1)
	    e+=16;
	  for(;e>=add;add++)
	   {data[add]=' ';}
	LCD_updata;
  }
/*-----------------------------------------------------------------------
LCD_write_number  : 数字显示函数

输入参数:
          X、Y    : 显示字符串的位置
               d     :在第d位插入小数点
		 data      :要显示的数据 长整形
		     *s     :数据的单位
	         e       : 把从最后一个字符到x=e之间的内容删除
编写日期       :2005/10/18	 		
-----------------------------------------------------------------------*/ 
void LCD_write_number(unsigned char x,unsigned char y,unsigned char d,unsigned long dat,const unsigned char *s,unsigned char e)
  { 
    unsigned char  i;
	unsigned char b=0;
	unsigned char c='.';
	unsigned char lcd[10]={0};
	if(y<2)//如果Y>1则不重新计算地址
    add=y*16+x;//设置起始座标
    
   for (i=10;i>0;i--) 
      {
        lcd[i]=dat%10+48;
		dat=dat/10;
      }
	  
	for(i=1;i<11;i++)
	   { 
	     if(i==11-d)
		   {  
		      if(lcd_data[add]==c)
			     {}
			  else
			     {data[add]=c;}     
		          add++;
			}   
	     if((lcd[i]-48+b)==0)
	     {
		   if(i>=(10-d))
		   { 
		      if(lcd_data[add]==lcd[i])
			     {}
			  else
			     {data[add]=lcd[i];}     
		          add++;
			} 	 
		   else
		   {}  	   
		 }
		 else
		 {
		      if(lcd_data[add]==lcd[i])
			     {}
			  else
			     {data[add]=lcd[i];}      
		          add++;
		 b=1;
		 }
	   }
	   while (*s) 
      {
        if(lcd_data[add]==*s)//如果LCD上显示的数和
		   {}                             //待写入的数相同的话
		else{data[add]=*s;}//要显示的数据存入显存
	       s ++;//指针加1
	       add++;//显存地址加1
      } 
	  if(y==1)
	    e+=16;
	  for(;e>=add;add++)
	   {data[add]=' ';}
	    LCD_updata;
  }
/*-----------------------------------------------------------------------
LCD_write_time  : 数字显示函数

输入参数:
          X、Y    : 显示数据的起始的位置
		  h,m,s   :时,分,秒
编写日期          :2005-10-19 		
-----------------------------------------------------------------------*/ 
void LCD_write_time(unsigned char x,unsigned char y,unsigned char h,unsigned char m,unsigned char s)
  { 
    unsigned char  i;
	unsigned char  lcd[8]={0};
	if(y<2)
	add=y*16+x;//设置起始座标LCD_set_xy( X, Y );  
	lcd[0]=h/10+48;
	lcd[1]=h%10+48;
	lcd[2]=':';
	lcd[3]=m/10+48;
	lcd[4]=m%10+48;
	lcd[5]=':';  
	lcd[6]=s/10+48;
	lcd[7]=s%10+48;
/*时和分之间的:的闪动效果
	if(lcd[7]%2)
	   lcd[2]=':';
	   else
	   lcd[2]=' ';*/
   for (i=0;i<8;i++) 
      {
              if(lcd_data[add]==lcd[i])
			     {}
			  else
			     {data[add]=lcd[i];}    
		          add++;
      }
	LCD_updata;
  }
/*----------------------------------------------------
    LCD_write_new:写显存函数
	data[]:32字节的显存
	new:显存标号
	编写日期:2005/10/18
-----------------------------------------------------*/  
void  LCD_write_new(void)
  {   
    unsigned char address;
	unsigned char new_add=1;//1表示要更新地址
	while(new<32)//显存共32个字节,标号从0--31 
      {    
		 if(new==16)//换行
		    new_add=1;	   
	     if(data[new])//跳过为0的显存
            {  
			if(new_add)//当new_add=0时表示无需更新地址
		      {
		         if(new>15)
			       address=0xb0+new;
				 else
			       address=0x80+new;
			       LCD_write_char(0,address);//设置起始地址
		       }  			  
			  LCD_write_char(1,data[new]);//写数据
			  lcd_data[new]=data[new];
			  data[new]=0;//写完数据后,显存清0
			  new_add=0;
			}
		else
		   new_add=1;
		   new++;//
      }
  } 
/*----------------------------------------------------
    LCD_write_CGRAM:写CGRAM的函数
	输入参数:
          X、Y    : 显示数据的起始的位置
		        n    : 存入LCD的图案的编号
	编写日期:2005/10/18
-----------------------------------------------------*/ 
void LCD_write_CGRAM(unsigned char x,unsigned char y,unsigned char n) 
{  
   if(y<2)
   add=y*16+x;//设置起始座标
    if(n==0)//0表示空数据
	n+=8;//所以要加上8  (0>8/1>9/2>10...7>15)  
	data[add]=n;      
	LCD_updata;
}
/*----------------------------------------------------
    LCD_init_CGRAM:初始化CGRAM的函数
	
	编写日期:2005/10/18
-----------------------------------------------------*/ 
void LCD_init_CGRAM(void)
  {
     unsigned char CGRAM[8][8]=//CGRAM图案的定义
	 {  //1     2      3       4       5      6        7      x
	   {0x3F,0x01,0x01,0x01,0x01,0x01,0x3F,0x00},//0
	   {0x00,0x04,0x02,0x1F,0x02,0x04,0x00,0x00},//1
	   {0x00,0x04,0x0E,0x15,0x04,0x04,0x04,0x00},//2
	   {0x00,0x1F,0x15,0x0E,0x04,0x04,0x04,0x00},//3
	   {0x00,0x1F,0x15,0x0A,0x04,0x04,0x04,0x00},//4
	   {0x00,0x00,0x02,0x06,0x0E,0x1E,0x1E,0x00},//5
	   {0x08,0x0C,0x0A,0x09,0x0A,0x0C,0x08,0x00},//6		
	   {0x08,0x0C,0x0E,0x0F,0x0E,0x0C,0x08,0x00},//7
	 };
	   unsigned char ads=0x40;
	   unsigned char x,y;
	   
	   LCD_write_char(0,ads);//写地址
	   for(y=0;y<8;y++)
	     { 
		   for(x=0;x<8;x++)
		     {
			    LCD_write_char(1,CGRAM[y][x]);
			 }	  
		 }     
  }	   

  

⌨️ 快捷键说明

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