LCD1602驱动程序

文章出处: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();
        }    
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值