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

📄 lcd1602.c

📁 用ATmega32写的采用四线接法的LCD1602驱动程序
💻 C
字号:
/***************************************************
* LCM1602驱动函数
* 文件名;LCD1602.c
* 硬 件:LCM1602
* 时 钟:16MHz
* 2008-3-10
* WeiJ
* 主要功能 驱动LCM1602 
* 1602LCM接口
   PC7-D7(BF)
   PC6-D6
   PC5-D5
   PC4-D4
   PC3-e
   PC2-rw
   PC1-rs
***************************************************/
//定义MCU与LCD的接口
#define LCD_EN_PORT    PORTC
#define LCD_RS_PORT    PORTC
#define LCD_RW_PORT    PORTC
#define LCD_DATA_PORT  PORTC

#define LCD_DDR        DDRC
#define LCD_CTR_DDR    DDRC
#define LCD_DATA_DDR   DDRC
#define LCD_DATA_PIN   PINC

#define LCD_EN         (1<<PC3)   //portc3         out
#define LCD_RW         (1<<PC2)   //portc2         out
#define LCD_RS         (1<<PC1)   //portc1         out
#define LCD_DATA       0xF0   //portc4/5/6/7   out

const unsigned char num[16]="0123456789ABCDEF";

/************************************************************************
* 名称          :void lcm_delay(unsigned long i)
* 功能          :为LCD设定一个延时
* 输入          :NULL
* 全局变量      :NULL  
* 返回值        :无
* 调用          :NULL
* 编写日期      :2008-2-29 
* 最后修改日期  :2008-2-29 
************************************************************************/
void lcm_delay(volatile unsigned long i)
{
  unsigned int a;
  for(a=0;a<i;a++)
  ;
}
 

/************************************************************************
* 名称          :void LCD_PORT_init(void)
* 功能          :设置LCD的端口的输入输出
* 输入          :NULL
* 全局变量      :NULL  
* 返回值        :无
* 调用          :NULL
* 编写日期      :2008-2-29 
* 最后修改日期  :2008-2-29 
************************************************************************/
void LCD_PORT_init(void)
{
  LCD_DATA_DDR |= LCD_DATA;
  LCD_CTR_DDR  |= LCD_RS | LCD_RW | LCD_EN;
  LCD_EN_PORT  &= ~LCD_EN;      //EN=0
}


/************************************************************************
* 名称          :uchar readBusy
* 功能          :读忙,检查LCD1602内部是否正在执行操作
* 输入          :NULL
* 全局变量      :NULL  
* 返回值        :NULL
* 调用          :NULL
* 编写日期      :2008-2-29 
* 最后修改日期  :2008-2-29 
************************************************************************/
void read_busy(void)
{ 
  //_delay_ms(1000);//直接用延时代替读忙以防LCM出错导致的死机
  //return;

  lcm_delay(100);
  LCD_CTR_DDR  |= LCD_EN | LCD_RW | LCD_RS;
  LCD_DATA_DDR &= ~(1<<7);
  
  lcm_delay(20);
  LCD_RS_PORT &=  ~LCD_RS;    //RS=0
  lcm_delay(20);
  LCD_RW_PORT |=  LCD_RW;     //RW=1 
  lcm_delay(20);
  LCD_EN_PORT |=  LCD_EN;     //EN=1 

  lcm_delay(20);
  while(LCD_DATA_PIN & 0x80) lcm_delay(20);
  
  LCD_EN_PORT &=  ~LCD_EN;     //EN=0
}

/*********************************************************
* 名称          :void write_byte_to_LCD(uchar data;uchar dataOrCmd)
* 功能          :写命令到LCD,指令格式:EN=1 RS=0 RW=0
                  写数据到LCD,数据格式:EN=1 RS=1 RW=0
                  data = 1:写数据  data = 0:兄指令
* 输入          :uchar dataOrCmd,要显示的数据或要控制LCD的命令
* 全局变量      :NULL  
* 返回值        :NULL
* 调用          :NULL
* 编写日期      :2008-2-29 
* 最后修改日期  :2008-2-29 
*********************************************************/
void write_byte_to_LCD(uchar data,uchar dataOrCmd)
{
   //_delay_us(500);             //用延时代替读忙 
   read_busy();
   
   lcm_delay(20);
   if( data )
   {
     LCD_RS_PORT |= LCD_RS;     //RS=1,写数据
   }
   else
   {
     LCD_RS_PORT &= ~LCD_RS;    //RS=0,写命令  
   }
   lcm_delay(20);
   LCD_EN_PORT &= ~LCD_EN;     //EN=0 
   lcm_delay(20);  
   LCD_RW_PORT &= ~LCD_RW;     //RW=0  
   
   LCD_DDR |= 0xFF;

   lcm_delay(20);
   LCD_DATA_PORT &= 0X0F;           //portc4~7=0,先清零数据口
   LCD_DATA_PORT |= dataOrCmd&0xF0; //send high 4bit
   LCD_EN_PORT   |= LCD_EN;         //EN端产生一个由低电平变高电平,写LCD
 
   lcm_delay(20);
   LCD_EN_PORT   &= ~LCD_EN;        //EN端产生一个由高电平变低电平,为写低四位数据做准备
   
   lcm_delay(20); 
   LCD_DATA_PORT &= 0X0F;                //portc4~7=0,先清零数据口
   LCD_DATA_PORT |= (dataOrCmd<<4)&0xF0; //send low 4bit
   LCD_EN_PORT   |= LCD_EN;              //EN端产生一个由低电平变高电平,写LCD
   LCD_EN_PORT   &= ~LCD_EN;             //关闭使能信号,以免写入错误数据
}

/***************************************************************************
* 名称          :void  init_LCD(void)
* 功能          :初始化液晶屏1602
* 调用          :void writeLCDCommand(uchar cmd)
* 全局变量      :NULL  
* 返回值        :NULL
* 调用          :void write_byte_to_LCD(uchar data,uchar dataOrCmd)
* 编写日期      :2008-2-29 
* 最后修改日期  :2008-2-29 
***************************************************************************/
void  init_LCD(void)
{
  LCD_PORT_init();      //设定LCD接口为输出
  
  write_byte_to_LCD(0,0x28); //显示模式设置以后都查测忙信号,设置4总线共有16*2字,每字有5*10(5*7)点阵
  write_byte_to_LCD(0,0x01); //显示清屏
  write_byte_to_LCD(0,0x02); //地址归位
  write_byte_to_LCD(0,0x0C); //显示关闭
  write_byte_to_LCD(0,0x14); //显示光标移动设置,光标移动,显示区不移动
}

/***************************************************************************
* 名称          :void LCD_set_xy( uchar X, uchar Y )
* 功能          :定位要显示的数据在液晶屏上的位置       
* 输入          :unsigned char X, unsigned char Y
                  显示字符串的位置,X:0-15,Y:0-1
                  LCD第一行显示寄存器地址:0X80-0X8F
                  LCD第一行显示寄存器地址:0XC0-0XCF
* 全局变量      :NULL  
* 返回值        :NULL
* 调用          :void write_byte_to_LCD(uchar data,uchar dataOrCmd)
* 编写日期      :2008-2-29 
* 最后修改日期  :2008-2-29
***************************************************************************/
void LCD_set_xy( unsigned char X, unsigned char Y )
{
  if ( Y == 0) 
  {
	write_byte_to_LCD(0,0x80+X);   
  }
  else 
  {	  
    write_byte_to_LCD(0,0xC0+X); 	   
  } 
}

/***************************************************************************
* 名称          :void LCD_dis_char(uchar X,uchar Y,uchar data)
* 功能          :显示单个英文字符       
* 输入          :uchar X, uchar Y,char data
                  显示字符串的位置,X:0-15,Y:0-1
                  LCD第一行显示寄存器地址:0X80-0X8F
                  LCD第一行显示寄存器地址:0XC0-0XCF
				  data:要显示的字符的ACSI码
* 全局变量      :NULL  
* 返回值        :NULL
* 调用          :void LCD_set_xy( unsigned char X, unsigned char Y )
                  void write_byte_to_LCD(uchar data,uchar dataOrCmd)
* 编写日期      :2008-2-29 
* 最后修改日期  :2008-2-29		
***************************************************************************/
void LCD_dis_char(uchar X,uchar Y,char data)
{
  if (X>15)     //显示超出一行时进行处理
  {
    Y ^= 0x01;  //换行显示
	X -= 16;
  }
  LCD_set_xy( X, Y );
  write_byte_to_LCD(1,data);
}

/***************************************************************************
* 名称          :void LCDDisString(unsigned char X,unsigned char Y,char *s)
* 功能          :显示英文字符串       
* 输入          :unsigned char X, unsigned char Y,char *s
                  显示字符串的位置,X:0-15,Y:0-1
                  LCD第一行显示寄存器地址:0X80-0X8F
                  LCD第一行显示寄存器地址:0XC0-0XCF
				  *s:英文字符串指针;
* 全局变量      :NULL  
* 返回值        :NULL
* 调用          :void LCD_set_xy( unsigned char X, unsigned char Y )
                  void write_byte_to_LCD(uchar data,uchar dataOrCmd)
* 编写日期      :2008-2-29 
* 最后修改日期  :2008-2-29
***************************************************************************/
void LCD_dis_string(unsigned char X,unsigned char Y,char *s)
{ 

  while ( *s ) 
  {
	LCD_dis_char( X++, Y,*s++);
	
	if (16 == X)  //显示超出一行时进行处理
	{
	  Y ^= 0x01;  //换行显示
	  X  = 0;
	} 
   }
}

⌨️ 快捷键说明

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