文章出处:http://blog.csdn.net/lczdk/article/details/53224714
LCD1602driver_inside.c
/*本驱动依赖reg51.h头文件*/
#include<reg51.h>
/*根据实际电路连接修改宏定义和sbit语句*/
#define D0_D7 P3 //数据通讯总线,用于写或读指令、显示地址和显示数据
sbit RS = P2^5; //寄存器选择引脚,设0选择指令和显示地址寄存器,设1选择显示数据寄存器
sbit RW = P2^6; //读写引脚,设0为写,设1为读
sbit E = P2^7; //信号使能引脚,设0允许写,设1允许读
sbit BF = P3^7; //忙信号,忙为1,不忙为0
/*根据实际电路连接修改宏定义和sbit语句*/
/*内部函数声明*/
bit Busy_Check(); //1602忙信号检测,忙返回1,不忙返回0(所有写操作前均需要调用此函数
void Data_Write(char Data); //写入8位显示数据(支持直接接收1602字库内字符或对应ASCII码)
void Addr_Write(unsigned char Addr); //写入8位显示地址
void Command_Write(unsigned char Command); //写入1602的各种命令
void Cursor_Reset(); //光标位置重置为左上角
unsigned char Coordinate_To_Addr(unsigned char X_Intercept,unsigned char Y_Intercept); //将输入的显示坐标转换为相应显示地址并返回
/*单行显示时,0 <= X_Intercept <= 79,Y_Interce == 0;双行显示时,0 <= X_Intercept <= 39,0 <= Y_Interce <= 1;*/
void DelayMS(unsigned int MS_Num); //延时函数MS
void Open_Screen_Inside(); //屏幕显示开启函数
void Close_Screen_Inside(); //屏幕显示关闭函数
void Move_Screen_Left_Inside(); //屏幕左移动函数
void Move_Screen_Right_Inside(); //屏幕右移动函数
void Reset_D0_D7(); //设置通讯总线为低电平
/*内部函数声明*/
/*void main() //语法测试用,使用时取消语句注释
{
Reset_D0_D7();
Command_Write(0x38);
DelayMS(5);
Command_Write(0x06);
Open_Screen_Inside();
DelayMS(5);
Command_Write(0x01);
DelayMS(5);
Addr_Write(Coordinate_To_Addr(0,0));
DelayMS(1);
Data_Write('5');
P3 = 0;
Close_Screen_Inside();
Open_Screen_Inside();
Data_Write('6');
Data_Write('7');
Data_Write('7');
Move_Screen_Inside(1);
Move_Screen_Inside(1);
Cursor_Reset();
Data_Write('7');
Data_Write('7');
Move_Screen_Inside(1);
while(1){P1 = 0;}
} */
/*内部函数定义*/
void Reset_D0_D7()
{
D0_D7 = 0;
}
void DelayMS(unsigned int MS_Num)
{
unsigned char a,b;
for(;MS_Num>0;MS_Num--)
for(b=142;b>0;b--)
for(a=2;a>0;a--);
}
bit Busy_Check()
{
// bit result;
// RS = 0;
// RW = 1;
// E = 1;
DelayMS(1); //伪忙检查
// result = (bit)(P2&0x80);
// return result;
}
void Data_Write(char Data)
{
RS = 1;
RW = 0;
E = 0;
DelayMS(1);
D0_D7 = Data;
E = 1;
DelayMS(1);
E = 0;
}
void Addr_Write(unsigned char Addr)
{
RS = 0;
RW = 0;
E = 0;
DelayMS(1);
D0_D7 = Addr;
E = 1;
DelayMS(1);
E = 0;
}
void Command_Write(unsigned char Command)
{
RS = 0;
RW = 0;
E = 0;
DelayMS(1);
D0_D7 = Command;
E = 1;
DelayMS(1);
E = 0;
}
void Cursor_Reset()
{
RS = 0;
RW = 0;
E = 0;
DelayMS(1);
D0_D7 = 0x02;
E = 1;
DelayMS(1);
E = 0;
}
unsigned char Coordinate_To_Addr(unsigned char X_Intercept,unsigned char Y_Intercept)
{
unsigned char Addr;
if(Y_Intercept == 0)
{
Addr = 0x80 + X_Intercept;
}
if(Y_Intercept == 1)
{
Addr = 0xC0 + X_Intercept;
}
return Addr;
}
void Open_Screen_Inside()
{
RS = 0;
RW = 0;
E = 0;
Command_Write(0x0C);
E = 1;
DelayMS(1);
E = 0;
}
void Close_Screen_Inside()
{
RS = 0;
RW = 0;
E = 0;
Command_Write(0x08);
E = 1;
DelayMS(1);
E = 0;
}
void Move_Screen_Left_Inside()
{
RS = 0;
RW = 0;
E = 0;
Command_Write(0x18);
E = 1;
DelayMS(1);
E = 0;
}
void Move_Screen_Right_Inside()
{
RS = 0;
RW = 0;
E = 0;
Command_Write(0x1C);
E = 1;
DelayMS(1);
E = 0;
}
LCD1602driver_inside.h
#ifndef _LCD1602DRIVER_INSIDE_H_
#define _LCD1602DRIVER_INSIDE_H_
unsigned char Busy_Check(); //1602忙信号检测,忙返回1,不忙返回0(所有写操作前均需要调用此函数
void Data_Write(char Data); //写入8位显示数据(支持直接接收1602字库内字符或对应ASCII码)
void Addr_Write(unsigned char Addr); //写入8位显示地址
void Command_Write(unsigned char Command); //写入1602的各种命令
void Cursor_Reset(); //光标位置重置为左上角
unsigned char Coordinate_To_Addr(unsigned char X_Intercept,unsigned char Y_Intercept); //将输入的显示坐标转换为相应显示地址并返回
/*单行显示时,0 <= X_Intercept <= 79,Y_Interce == 0;双行显示时,0 <= X_Intercept <= 39,0 <= Y_Interce <= 1;*/
void DelayMS(unsigned int MS_Num);
void Open_Screen_Inside(); //屏幕显示开启函数
void Close_Screen_Inside(); //屏幕显示关闭函数
void Move_Screen_Left_Inside(); //屏幕左移动函数
void Move_Screen_Right_Inside(); //屏幕右移动函数
void Reset_D0_D7(); //设置通讯总线为低电平
#endif
LCD1602.c
/*
unsigned char Busy_Check(); //1602忙信号检测,忙返回1,不忙返回0(所有写操作前均需要调用此函数
void Data_Write(unsigned char Data); //写入8位显示数据(支持直接接收1602字库内字符或对应ASCII码)
void Addr_Write(unsigned char Addr); //写入8位显示地址
void Command_Write(unsigned char Command); //写入1602的各种命令
void Cursor_Reset(); //光标位置重置为左上角
unsigned char Coordinate_To_Addr(unsigned char X_Intercept,unsigned char Y_Intercept); //将输入的显示坐标转换为相应显示地址并返回
/双行显示时,0 <= X_Intercept <= 47,Y_Interce == 0;单行显示时,0 <= X_Intercept <= 79,0 <= Y_Interce <= 1;/
void DelayMS(unsigned int MS_Num);
void Open_Screen_Inside(); //屏幕显示开启函数
void Close_Screen_Inside(); //屏幕显示关闭函数
void Move_Screen_Left_Inside(); //屏幕左移动函数
void Move_Screen_Right_Inside(); //屏幕右移动函数
void Reset_D0_D7(); //设置通讯总线为低电平
*/
#include"LCD1602driver_inside.h"
#include<reg51.h>
//包含内部函数,具体包含内容查阅LCD1602driver_inside.h和LCD1602driver内部函数.c,要了解函数功能也可以查看本文件开头的大段注释
/*可调用函数声明*/
void LCD1602_Init(unsigned char Line_Num,unsigned char Char_Type); //初始化函数,接收行数(1或2)和点阵字符类型(1或2,对应5x7和5x10点阵字符)
void LCD1602_Clear_Screen();
void LCD1602_Write_Char_Screen(char ASCII_Data,unsigned char X_Intercept,unsigned char Y_Intercept); //单字符输出函数;单行显示时,0 <= X_Intercept <= 79,Y_Interce == 0;双行显示时,0 <= X_Intercept <= 39,0 <= Y_Interce <= 1;; 屏幕会显示X坐标在15之前的字符,其他字符通过光标移动显示
void LCD1602_Write_Line_Screen(char Line_Data[28],unsigned char Y_Intercept); //整行输出函数;需接收16个字符到28个字符,0 <= Y_Interce <= 1;屏幕会显示前16个字符,其他字符通过光标移动显示
void LCD1602_Open_Screen(); //屏幕显示开启函数
void LCD1602_Close_Screen(); //屏幕显示关闭函数
void LCD1602_Move_Left_Screen(); //屏幕左移一位
void LCD1602_Move_Right_Screen(); //屏幕右移一位
/*可调用函数声明*/
/*void main() //语法测试用,使用时取消语句注释
{
LCD1602_Init(2,1);
LCD1602_Write_Line_Screen("123456",0);
LCD1602_Write_Line_Screen("123456",1);
LCD1602_Move_Screen(1);
LCD1602_Move_Screen(0);
LCD1602_Move_Screen(1);
LCD1602_Move_Screen(1);
while(1);
} */
/*可调用函数定义*/
void LCD1602_Init(unsigned char Line_Num,unsigned char Char_Type)
{
Reset_D0_D7();
Command_Write(0x06);
if(Line_Num == 1)
{
if(Char_Type == 2)
{
Command_Write(0x34);
}
else
{
Command_Write(0x30);
}
}
else
{
if(Char_Type == 2)
{
Command_Write(0x3C);
}
else
{
Command_Write(0x38);
}
}
DelayMS(5);
LCD1602_Open_Screen();
DelayMS(5);
LCD1602_Clear_Screen();
DelayMS(5);
}
void LCD1602_Clear_Screen()
{
while(Busy_Check());
Command_Write(0x01);
}
void LCD1602_Write_Char_Screen(char ASCII_Data,unsigned char X_Intercept,unsigned char Y_Intercept)
{
while(Busy_Check());
Addr_Write(Coordinate_To_Addr(X_Intercept,Y_Intercept));
DelayMS(1);
Data_Write(ASCII_Data);
}
void LCD1602_Write_Line_Screen(char Line_Data[28],unsigned char Y_Intercept)
{
char Count;
while(Busy_Check());
Addr_Write(Coordinate_To_Addr(0,Y_Intercept));
for(Count = 0;Line_Data[Count] != '\0';Count++) //读到字符串结束标志后停止
{
Data_Write(Line_Data[Count]);
}
}
void LCD1602_Open_Screen()
{
Open_Screen_Inside();
}
void LCD1602_Close_Screen()
{
Close_Screen_Inside();
}
void LCD1602_Move_Left_Screen()
{
Move_Screen_Left_Inside();
}
void LCD1602_Move_Right_Screen()
{
Move_Screen_Right_Inside();
}
/*可调用函数定义*/
LCD1602.H
#ifndef _LCD1602_H_
#define _LCD1602_H_
void LCD1602_Init(unsigned char Line_Num,unsigned char Char_Type); //初始化函数,接收行数(1或2)和点阵字符类型(1或2,对应5x7和5x10点阵字符)
void LCD1602_Clear_Screen();
void LCD1602_Write_Char_Screen(char ASCII_Data,unsigned char X_Intercept,unsigned char Y_Intercept); //单字符输出函数;单行显示时,0 <= X_Intercept <= 79,Y_Interce == 0;双行显示时,0 <= X_Intercept <= 39,0 <= Y_Interce <= 1;; 屏幕会显示X坐标在15之前的字符,其他字符通过光标移动显示
void LCD1602_Write_Line_Screen(char Line_Data[16],unsigned char Y_Intercept); //整行输出函数;最多接收28个字符,0 <= Y_Interce <= 1;屏幕会显示前16个字符,其他字符通过屏幕移动显示
void LCD1602_Open_Screen(); //屏幕显示开启函数
void LCD1602_Close_Screen(); //屏幕显示关闭函数
void LCD1602_Move_Left_Screen(); //屏幕左移一位
void LCD1602_Move_Right_Screen(); //屏幕右移一位
#endif
driver_test.c
#include<LCD1602.h>
#include"LCD1602driver_inside.h"
#include<reg51.h>
#include<intrins.h>
/*头文件包含函数
void LCD1602_Init(unsigned char Line_Num,unsigned char Char_Type); //初始化函数,接收行数(1或2)和点阵字符类型(1或2,对应5x7和5x10点阵字符)
void LCD1602_Clear_Screen();
void LCD1602_Write_Char_Screen(char ASCII_Data,unsigned char X_Intercept,unsigned char Y_Intercept); //单字符输出函数;单行显示时,0 <= X_Intercept <= 79,Y_Interce == 0;双行显示时,0 <= X_Intercept <= 39,0 <= Y_Interce <= 1;; 屏幕会显示X坐标在15之前的字符,其他字符通过光标移动显示
void LCD1602_Write_Line_Screen(char Line_Data[16],unsigned char Y_Intercept); //整行输出函数;最多接收16个字符,0 <= Y_Interce <= 1;屏幕会显示前16个字符,其他字符通过光标移动显示
void LCD1602_Open_Screen(); //屏幕显示开启函数
void LCD1602_Close_Screen(); //屏幕显示关闭函数
void LCD1602_Move_Left_Screen(); //屏幕左移一位
void LCD1602_Move_Right_Screen(); //屏幕右移一位
*/
void delay(void) //延时0.25S
{
unsigned char a,b,c;
for(c=3;c>0;c--)
for(b=247;b>0;b--)
for(a=142;a>0;a--);
_nop_;
}
void main()
{
char Count;
LCD1602_Init(2,1);
while(1)
{
LCD1602_Clear_Screen();
LCD1602_Write_Line_Screen(" A1411ZDK",0);
LCD1602_Write_Line_Screen(" 2016*11*18",1);
for(Count = 12;Count>=0;Count--)
{
LCD1602_Move_Right_Screen();
delay();
}
}
}