爱点网

I Click Web.Com

51单片机 LCD1602液晶屏 范例代码 可用

LCD1602液晶显示原理:点击此处

为方便使用,我的范例代码是只提供 .h .c ,使用这种方式也方便进行代码替换,使你得主代码区域不会太过于复杂。我只会简单在最后写一个使用的范例,我不会将整个功能的代码放上来,因为你的作品功能只有自己知道,我如果整个实现都写出来,只会误导到你。

所有我发布上来的代码,都是我在实际项目中使用过,并确保没有问题的。

注意:我所使用的LCD1602液晶显示代码,必须将RS/RW/EN都接在单片机上,因为严谨性,代码中有检测LCD是否在忙的状态,如果三根线不接在对应的单片机接口上,会导致代码卡死!

这份LCD1602液晶显示代码是我最喜欢用的一个,相较于其他范例代码,这份更加人性化。

=========================delay.h =========================

#ifndef __DELAY_H__
#define __DELAY_H__
/*------------------------------------------------
us延时函数,含有输入参数 unsigned char t,无返回值
unsigned char 是定义无符号字符变量,其值的范围是
0~255  延时函数会有误差,但是也可以使用,如需精准
计时还请使用定时器
------------------------------------------------*/
void DelayUs2x(unsigned char t);
/*------------------------------------------------
ms延时函数,含有输入参数 unsigned char t,无返回值
unsigned char 是定义无符号字符变量,其值的范围是
0~255  延时函数会有误差,但是也可以使用,如需精准
计时还请使用定时器
------------------------------------------------*/
void DelayMs(unsigned char t);

#endif

=========================delay.c =========================

#include "delay.h"
/*------------------------------------------------
us延时函数,含有输入参数 unsigned char t,无返回值
unsigned char 是定义无符号字符变量,其值的范围是
0~255  延时函数会有误差,但是也可以使用,如需精准
计时还请使用定时器
------------------------------------------------*/
void DelayUs2x(unsigned char t)
{   
 while(--t);
}
/*------------------------------------------------
ms延时函数,含有输入参数 unsigned char t,无返回值
unsigned char 是定义无符号字符变量,其值的范围是
0~255  延时函数会有误差,但是也可以使用,如需精准
计时还请使用定时器
------------------------------------------------*/
void DelayMs(unsigned char t)
{
     
 while(t--)
 {
     //大致延时1mS
     DelayUs2x(245);
	 DelayUs2x(245);
 }
}

=========================lcd1602.c =========================

#include "lcd1602.h"
#include "delay.h"
#include <intrins.h>

#define uchar unsigned char
#define uint unsigned int

#define _NOP() _nop_()
sbit RS = P2^6;   //定义端口
sbit RW = P2^5;
sbit EN = P2^7;


#define DataPort    P0				
#define DataPIN     P0

#define CLR_RS (RS=0) 
#define SET_RS (RS=1)	
#define CLR_RW (RW=0)	
#define SET_RW (RW=1)
#define CLR_EN (EN=0)
#define SET_EN (EN=1)	

/*
	LcdReset();               //LCD1602初始化
	DelayMs(10);	
	sprintf(temp,"1111111111111111");//更新显示
	DispStr(0,0,(unsigned char *)temp);//打印显示
	sprintf(temp,"1111111111111111");//¸更新显示
	DispStr(0,1,(unsigned char *)temp);//打印显示
*/
/***********************************************
函数名称:DispStr
功    能:让液晶从某个位置起连续显示一个字符串
参    数:x--位置的列坐标
          y--位置的行坐标
          ptr--指向字符串存放位置的指针
返回值  :无
***********************************************/
void DispStr(uchar x,uchar y,uchar *ptr) 
{
    uchar *temp;
    uchar i,n = 0;
    
    temp = ptr;
    while(*ptr++ != '\0')   n++;    //计算字符串有效字符的个数
    
    for (i=0;i<n;i++)
    {
        Disp1Char(x++,y,temp[i]);
        if (x == 0x10)
        {
            break;
        }
    }
}

/*******************************************
函数名称:DispNChar
功    能:让液晶从某个位置起连续显示N个字符
参    数:x--位置的列坐标
          y--位置的行坐标
          n--字符个数
          ptr--指向字符串存放位置的指针
返回值  :无

注意:这个函数是屏蔽起来的,因为不是经常使用
如果你想使用,那么可以打开屏蔽
*******************************************
/*void DispNChar(uchar x,uchar y, uchar n,uchar *ptr) 
{
    uchar i;
    
    for (i=0;i<n;i++)
    {
        Disp1Char(x++,y,ptr[i]);
        if (x == 0x10)
        {
           x = 0; 
            y ^= 1;
        }
    }
}
*/
/*******************************************
函数名称:LocateXY
功    能:让液晶从某个位置起连续显示N个字符
参    数:x--位置的列坐标
          y--位置的行坐标
返回值  :无
********************************************/
void LocateXY(uchar x,uchar y) 
{
    uchar temp;

    temp = x&0x0f;
    y &amp;= 0x01;
    if(y)   temp |= 0x40;  //如果在第2行
    temp |= 0x80;

    LcdWriteCommand(temp,1);
}

/*******************************************
函数名称:Disp1Char
功    能:在某个位置显示一个字符
参    数:x--位置的列坐标
          y--位置的行坐标
          data1--显示的字符数据
返回值  :无
********************************************/
void Disp1Char(uchar x,uchar y,uchar data1) 
{
    LocateXY( x, y );			
    LcdWriteData( data1 );		
}

/*******************************************
函数名称:LcdReset
功    能:对1602液晶模块进行复位操作
参    数:无
返回值  :无
********************************************/
void LcdReset(void) 
{
//    DataDir  = 0xFF;                 //数据端口设为输出状态
    LcdWriteCommand(0x38, 0);	    //规定的复位操作
    DelayMs(5);
    LcdWriteCommand(0x38, 0);		
    DelayMs(5);
    LcdWriteCommand(0x38, 0);
    DelayMs(5);

    LcdWriteCommand(0x38, 1);		//显示模式设置
    LcdWriteCommand(0x08, 1);		//显示关闭
    LcdWriteCommand(0x01, 1);	    //显示清屏
    LcdWriteCommand(0x06, 1);		//写字符时整体不移动
    LcdWriteCommand(0x0c, 1);		//显示开,不开游标,不闪烁
}

/*------------------------------------------------
                清屏函数
------------------------------------------------*/
void LcdClear(void) 
{ 
	LcdWriteCommand(0x01,1); 
	DelayMs(5);
}

/*******************************************
函数名称:LcdWriteCommand
功    能:向液晶模块写入命令
参    数:cmd--命令
          cnk--是否判断忙的标志,1:判忙 0:不判
返回值  :无
********************************************/
void LcdWriteCommand(uchar cmd,uchar chk) 
{

    if (chk) WaitForEnable();   //检测忙信号
    
    CLR_RS;	
    CLR_RW; 
    _NOP();

    DataPort = cmd;             //将命令字写入数据端口
    _NOP();					
    
    SET_EN;                     //产生使能脉冲信号
    _NOP();
    _NOP();
    CLR_EN;			
}

/*******************************************
函数名称:LcdWriteData
功    能:向液晶显示的当前地址写入显示数据
参    数:data1--显示字符数据
返回值  :无
********************************************/
void LcdWriteData( uchar data1 ) 
{
    WaitForEnable();        //等待液晶不忙
    SET_RS;
    CLR_RW; 

    SET_EN;
	
	_NOP();
    DataPort = data1;        //将显示数据写入数据端口
    _NOP();
                //产生使能脉冲信号
    _NOP(); 
    _NOP(); 
    CLR_EN;		
}

/*******************************************
函数名称:WaitForEnable
功    能:等待1602液晶完成内部操作
参    数:无
返回值  :无
********************************************/
void WaitForEnable(void) 
{
  	unsigned int later=0;
	DataPort=0xff;
    CLR_RS;
    SET_RW;
    _NOP();
    SET_EN; 
    _NOP();
    _NOP();
//    while((DataPIN&amp;Busy)!=0);    
    while(((DataPIN&amp;0x80)!=0)&amp;&amp;(later<1000))  //检测忙标志
    {
      DelayUs2x(2);
      later++;        
    }
    CLR_EN;
//    DataDir|=0xFF;  
}		


=========================lcd1602.h =========================

/*-----------------------------------------------
  名称:LCD1602.h

引脚定义如下:1-VSS 2-VDD 3-V0 4-RS 5-R/W 6-E 7-14 DB0-DB7 15-BLA 16-BLK
------------------------------------------------*/
#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include<intrins.h>

#ifndef __LCD1602_H__
#define __LCD1602_H__

void DispStr(unsigned char x,unsigned char y,unsigned char *ptr);
void DispNChar(unsigned char x,unsigned char y, unsigned char n,unsigned char *ptr);
void LocateXY(unsigned char x,unsigned char y);
void Disp1Char(unsigned char x,unsigned char y,unsigned char data1);
void LcdReset(void);
void LcdWriteCommand(unsigned char cmd,unsigned char chk);
void LcdWriteData( unsigned char data1 );
void WaitForEnable(void);
void LcdClear(void);

#define LCD_Init          LcdReset
#define LCD_Write_Char    Disp1Char
#define LCD_Write_String  DispStr
#define LCD_Clear         LcdClear
   
#endif

=========================main.c =========================

#include "reg52.h"
#include "lcd1602.h"
//因为lcd1602.h中已经包含了delay.h所以这里可以不用包含
/*******************************************
在lcd1602.h中有这样一段定义
#define LCD_Init          LcdReset
#define LCD_Write_Char    Disp1Char
#define LCD_Write_String  DispStr
#define LCD_Clear         LcdClear

所以,LCD_Init 可以代表 LcdReset
********************************************/

void main()
{
  int dat = 123;//data在这种语言中属于专有名词,所以最好不要用这个命名
  LCD_Init();
  while(1)
  {
    LCD_Write_String(0,0,"hello world!!   ");
    LCD_Write_Char(0,1,'D');
    LCD_Write_Char(1,1,'a');
    LCD_Write_Char(2,1,'t');
    LCD_Write_Char(3,1,':');
    LCD_Write_Char(4,1,(dat/100%10)+0x30);//这里+0x30是因为需要将数字转换成
                              //ASCII码,数字1在ASCII码中对应0x30(十进制的48)
    LCD_Write_Char(5,1,(dat/10%10)+48);
    LCD_Write_Char(6,1,(dat%10)+0x30);//个人爱好,比较喜欢写0x30
    //一行LCD1602显示屏有16个格子来显示,尽量补满所有未写入的格子都写入空格
    LCD_Write_String(7,1,"         ")
  }
}

/*
以上代码运行后会显示

hello_world!!    
Data:123


*/

从keil4中复制出来,结果中文全是乱码,我一个一个手打改回来了,当你们在复制这些代码到keil时,也可能出现乱码,你们可以去设置编码格式,或者像我一样一个一个打出来,当然肯定会累很多,后面我回去找一找格式转换的工具,要不然以后代码我就得累死了

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注