📄 smc1602.c
字号:
#include <Intrins.h>
#include <At89x51.h>
//定义LCD的连接端口
#define LCD_RS P2_5
#define LCD_RW P2_6
#define LCD_EN P2_7
#define BUSY P0_7
#define LCD_DATA_PORT P0
#define LOW 0
#define HIGH 1
//函数原型声明
unsigned char Lcd1602_Check_Busy(void);
void Lcd1602_Write_Command(unsigned char Command_Code);
void Lcd1602_Write_Command_Nocheck(unsigned char Command_Code);
void Lcd1602_Write_Data(unsigned char Data);
unsigned char Lcd1602_Read_Data(void);
void Lcd1602_Ini(void);
void Lcd1602_Write_String(unsigned char row,unsigned char column,unsigned char *dis_buffer);
void Lcd1602_Clear_Char(unsigned char row,unsigned char column);
void Lcd1602_Clear_Line(unsigned char line);
void Lcd1602_Clear_All(void);
void Lcd1602_Demo1(void);
void Lcd1602_Demo2(void);
void Delay_ms(unsigned char second);
void Delay_1s(void);
static unsigned char char1[]="Welcome to WWW.MCUEDU.COM";
static unsigned char char2[]="Tel:27529998";
void main(void)
{
while(1)
{
Lcd1602_Demo1();
// Lcd1602_Demo2();
}
}
void Lcd1602_Ini(void)
{
Delay_ms(20);
Lcd1602_Write_Command_Nocheck(0x38);//设定LCD为16*2显示,5*7点阵,8位数据接口
Delay_ms(10);
Lcd1602_Write_Command_Nocheck(0x38);
Delay_ms(10);
Lcd1602_Write_Command_Nocheck(0x38);
Lcd1602_Write_Command(0x38);
Lcd1602_Write_Command(0x01);//显示清屏。
Lcd1602_Write_Command(0x80);//将数据指针设置到第一行的第一个字符。
Lcd1602_Write_Command(0x06);//显示光标自动右移,整屏不移动。
Lcd1602_Write_Command(0x0c);//开显示,不显示光标
}
void Lcd1602_Clear_All(void)
{
Lcd1602_Write_Command(0x01);//显示清屏。
Lcd1602_Write_Command(0x80);//将数据指针设置到第一行的第一个字符。
}
//==========================================
//清除指定的行,光标返回最左边第一个字符位置
//==========================================
void Lcd1602_Clear_Line(unsigned char line)
{
Lcd1602_Write_String(line,1," ");
switch(line)//这种结构保持以后升级到多行显示液晶
{
case 1:Lcd1602_Write_Command(0x80);break; //将数据地址指针定位到第一行
case 2:Lcd1602_Write_Command(0x80+0x40);break; //将数据地址指针定位到第二行
default: break;
}
}
//==================================================
//清除指定的位置的字符,光标返回最左边第一个字符位置
//==================================================
void Lcd1602_Clear_Char(unsigned char row,unsigned char column)
{
Lcd1602_Write_String(row,column," ");
}
//===========================================
//写字符串到LCD,如果一行写不下,则写到下一行,
//如果一屏写不下,则只写一屏
//row的值从1-2,column的值从1-16,不进行值的
//有效性检查,有调用者自己保证
//===========================================
void Lcd1602_Write_String(unsigned char row,unsigned char column,unsigned char *dis_buffer)
{
unsigned char i=0;
switch(row)//这种结构保持以后升级到多行显示液晶
{
case 1:Lcd1602_Write_Command(0x80+column-1);break; //将数据地址指针定位到第一行
case 2:Lcd1602_Write_Command(0x80+0x40+column-1);break; //将数据地址指针定位到第二行
default: break;
}
while(dis_buffer[i]!='\0')
{
Lcd1602_Write_Data(dis_buffer[i]);
i++;
if(++column==17)
{
column=1;
if(++row==3)
return;
else
{
switch(row)//这种结构保持以后升级到多行显示液晶
{
case 1:Lcd1602_Write_Command(0x80);break;
case 2:Lcd1602_Write_Command(0x80+0x40);break;//重新调整数据地址指针
default:break;
}
}
}
}
}
//*************************************
//以下几个函数为支持LCD数据传送和控制的底层函数
//*************************************
//===========================
//写一个命令字节
//===========================
void Lcd1602_Write_Command(unsigned char Command_Code)
{
Lcd1602_Check_Busy();
LCD_RS=LOW;
LCD_RW=LOW;
LCD_DATA_PORT=Command_Code;
_nop_();
LCD_EN=HIGH ;
_nop_();
LCD_EN=LOW;
LCD_DATA_PORT=0xFF; //prevent port is 0.
}
//===========================
//写一个命令字节,不进行忙检测
//===========================
void Lcd1602_Write_Command_Nocheck(unsigned char Command_Code)
{
LCD_RS=LOW;
LCD_RW=LOW;
LCD_DATA_PORT=Command_Code;
_nop_();
LCD_EN=HIGH ;
_nop_();
LCD_EN=LOW;
LCD_DATA_PORT=0xFF; //prevent port is 0.
}
//===========================
//写一个字节数据
//===========================
void Lcd1602_Write_Data(unsigned char Data)
{
Lcd1602_Check_Busy();//没有使用返回值,如果需要可以根据返回值进行处理。
LCD_RS=HIGH;
LCD_RW=LOW;
LCD_DATA_PORT=Data;
_nop_();
LCD_EN=HIGH;
_nop_();
LCD_EN=LOW;
LCD_DATA_PORT=0xFF; //prevent port is 0
}
//===========================
//读一个字节数据
//===========================
unsigned char Lcd1602_Read_Data(void)
{
unsigned char ram_data;
LCD_RS=HIGH;
LCD_RW=HIGH;
LCD_EN=HIGH;
_nop_();
ram_data=LCD_DATA_PORT;
LCD_EN=LOW;
return ram_data;
}
//===========================
//LCD状态检测
//===========================
unsigned char Lcd1602_Check_Busy(void)
{
//Delay_ms(2);
unsigned char i;
LCD_DATA_PORT=0xFF;
LCD_RS=LOW;
LCD_RW=HIGH;
LCD_EN=HIGH;
for(i=0;i<5;i++) //防止器件损坏时的死循环.
{
if(BUSY==0)
{
LCD_EN=LOW;
return (0); //不忙,跳出循环并且结束函数,返回ok信号。
}
Delay_ms(1);//该函数位于另外一个文件中。
}
LCD_EN=LOW;
return (1); //忙,跳出循环并且结束函数,返回出错信号。
}
//***************************************************
//以下是一些特殊效果显示程序
//***************************************************
//==================================================
//演示程序1
//==================================================
void Lcd1602_Demo1(void)
{
unsigned char i,j=0,k=0;
for(i=0;i<5;i++)
{
Lcd1602_Write_String(1,1,char1);
Delay_1s();
// Delay_1s();
Lcd1602_Clear_All();
Lcd1602_Write_String(1,1,char2);
Delay_1s();
// Delay_1s();
Lcd1602_Clear_All();
}
for(i=0;i<3;i++)
{
while(char1[j]!='\0')
{
Lcd1602_Write_Data(char1[j]);
j++;
if(++k==16)
{
Lcd1602_Write_Command(0x80+0x40);
k=0;
}
Delay_1s();
}
Lcd1602_Clear_All();
}
}
//==================================================
//演示程序2
//==================================================
void Lcd1602_Demo2(void)
{
Lcd1602_Write_Command(0x80);
Lcd1602_Write_Data('A');
Lcd1602_Write_Data('B');
Lcd1602_Write_Data('C');
}
//==================================================
//延时最大255毫秒
//==================================================
void Delay_ms(unsigned char second)
{
unsigned char i,j;
for(j=0;j<second;j++)
for (i=0;i<124;i++)
_nop_();
}
//==================================================
//延时1秒
//==================================================
void Delay_1s(void)
{
Delay_ms(250);
Delay_ms(250);
Delay_ms(250);
Delay_ms(250);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -