1602A液晶屏的驱动程序
2012-08-09

C程序:

/******************************************************************
** 1602A液晶屏驱动程序
** 晶 振 频 率:11.0592M
** 线路->单片机实验开发板A
******************************************************************/
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit LCM_E = P3 ^ 5; //定义接口
sbit LCM_RW = P3 ^ 6;
sbit LCM_RS = P3 ^ 7;
#define LCM_Data P1//数据接口
void LCM_WriteData(uchar WDLCM);
void LCM_WriteCommand(uchar WCLCM, BuysC);
uchar LCM_ReadData(void);
uchar LCM_ReadStatus(void);
void LCM_Init(void);
void DisplayOneChar(uchar X, uchar Y, uchar DData);
void DisplayListChar(uchar X, uchar Y, uchar code *DData);
void Delay5Ms(void);
void Delay400Ms(void);
uchar code uctech[] = {"1602A"};
uchar code net[] = {"www.52c51.com"};

void main(void)
{
    Delay400Ms();//启动等待,等LCM讲入工作状态
    LCM_Init();//LCM初始化
    Delay5Ms();//延时片刻(可不要)

    DisplayListChar(6, 1, uctech);
    DisplayListChar(0, 0, net);
    LCM_ReadData();//测试用句无意义
    LCM_Data = 255;
    while (1);
}

/****************************1602A写数据函数**************************/
/*函数原型:void LCM_WriteData(uchar WDLCM)
/*函数功能:1602A写数据
/*输入参数:要写入的数据
/*输出参数:无
/*调用模块:
/*建立时间:2005/11/14
/*作者:站长
/**********************************************************************/
void LCM_WriteData(uchar WDLCM)
{
    LCM_ReadStatus();//检测忙
    LCM_Data = WDLCM;
    LCM_RS = 1;
    LCM_RW = 0;
    LCM_E = 0;//若晶振速度太高可以在这后加小的延时
    LCM_E = 0;//延时
    LCM_E = 1;
}

/****************************1602A写指令函数**************************/
/*函数原型:void LCM_WriteCommand(uchar WCLCM,BuysC)
/*函数功能:1602A写指令
/*输入参数:要写入的指令
/*输出参数:无
/*调用模块:
/*建立时间:2005/11/14
/*作者:站长
/**********************************************************************/
void LCM_WriteCommand(uchar WCLCM, BuysC) //BuysC为0时忽略忙检测
{
    if (BuysC) {
        LCM_ReadStatus();    //根据需要检测忙
    }
    LCM_Data = WCLCM;
    LCM_RS = 0;
    LCM_RW = 0;
    LCM_E = 0;
    LCM_E = 0;
    LCM_E = 1;
}

/****************************1602A读数据函数**************************/
/*函数原型:uchar LCM_ReadData(void)
/*函数功能:1602A读数据
/*输入参数:无
/*输出参数:1602A返回的数据
/*调用模块:
/*建立时间:2005/11/14
/*作者:站长
/**********************************************************************/
uchar LCM_ReadData(void)
{
    LCM_RS = 1;
    LCM_RW = 1;
    LCM_E = 0;
    LCM_E = 0;
    LCM_E = 1;
    return (LCM_Data);
}

/****************************1602A读状态函数**************************/
/*函数原型:uchar LCM_ReadData(void)
/*函数功能:1602A读状态
/*输入参数:无
/*输出参数:1602A返回的状态
/*调用模块:
/*建立时间:2005/11/14
/*作者:站长
/**********************************************************************/
uchar LCM_ReadStatus(void)
{
    LCM_Data = 0xFF;
    LCM_RS = 0;
    LCM_RW = 1;
    LCM_E = 0;
    LCM_E = 0;
    LCM_E = 1;
    while (LCM_Data & 0x80);//检测忙信号
    return (LCM_Data);
}

/****************************1602A初始化函数**************************/
/*函数原型:void LCM_Init(void)
/*函数功能:1602A初始化
/*输入参数:无
/*输出参数:无
/*调用模块:
/*建立时间:2005/11/14
/*作者:站长
/**********************************************************************/
void LCM_Init(void)
{
    LCM_Data = 0;
    LCM_WriteCommand(0x38, 0); //三次显示模式设置,不检测忙信号
    Delay5Ms();
    LCM_WriteCommand(0x38, 0);
    Delay5Ms();
    LCM_WriteCommand(0x38, 0);
    Delay5Ms();

    LCM_WriteCommand(0x38, 1); //显示模式设置,开始要求每次检测忙信号
    LCM_WriteCommand(0x08, 1); //关闭显示
    LCM_WriteCommand(0x01, 1); //显示清屏
    LCM_WriteCommand(0x06, 1); // 显示光标移动设置
    LCM_WriteCommand(0x0C, 1); // 显示开及光标设置
}

/******************1602A按指定位置显示一个字符函数**********************/
/*函数原型:void DisplayOneChar(uchar X, uchar Y, uchar DData)
/*函数功能:1602A按指定位置显示一个字符
/*输入参数:X坐标 Y坐标 要显示的字符
/*输出参数:无
/*调用模块:
/*建立时间:2005/11/14
/*作者:站长
/**********************************************************************/
void DisplayOneChar(uchar X, uchar Y, uchar DData)
{
    Y &= 0x1;
    X &= 0xF;//限制X不能大于15,Y不能大于1
    if (Y) {
        X |= 0x40;    //当要显示第二行时地址码+0x40;
    }
    X |= 0x80;// 算出指令码
    LCM_WriteCommand(X, 0);//这里不检测忙信号,发送地址码
    LCM_WriteData(DData);
}

/*******************1602A按指定位置显示一串字符函数*********************/
/*函数原型:void DisplayListChar(uchar X, uchar Y, uchar code *DData)
/*函数功能:1602A按指定位置显示一个字符
/*输入参数:X坐标 Y坐标 要显示字符串的首地址
/*输出参数:无
/*调用模块:
/*建立时间:2005/11/14
/*作者:站长
/**********************************************************************/
void DisplayListChar(uchar X, uchar Y, uchar code *DData)
{
    uchar ListLength;
    ListLength = 0;
    Y &= 0x1;
    X &= 0xF;//限制X不能大于15,Y不能大于1
    while (DData[ListLength] > 0x20) { //若到达字串尾则退出
        if (X <= 0xF) { //X坐标应小于0xF
            DisplayOneChar(X, Y, DData[ListLength]);//显示单个字符
            ListLength++;
            X++;
        }
    }
}

/********************5ms延时函数************************/
/*函数原型:void Delay5Ms(void)
/*函数功能:5ms延时
/*输入参数:无
/*输出参数:无
/*调用模块:
/*建立时间:2005/11/14
/*作者:站长
/**********************************************************************/
void Delay5Ms(void)
{
    unsigned int TempCyc = 5552;
    while (TempCyc--);
}

/********************400ms延时延时函数************************/
/*函数原型:void Delay400Ms(void)
/*函数功能:400ms延时延时
/*输入参数:无
/*输出参数:无
/*调用模块:
/*建立时间:2005/11/14
/*作者:站长
/**********************************************************************/
void Delay400Ms(void)
{
    uchar TempCycA = 5;
    unsigned int TempCycB;
    while (TempCycA--) {
        TempCycB = 7269;
        while (TempCycB--);
    };
}


51单片机汇编

        LCM_RS EQU P3.7;//定义接口
        LCM_RW EQU P3.6
        LCM_E EQU P3.5
        
        LCM_DATA EQU P1;数据接口
        
        ORG 0000H      ;从0000H处开始
        SJMP MAIN      ;跳转到MAIN处
        
        ORG 0030H      ;主程序从0030H处开始
MAIN:   MOV SP,#70H    ;堆栈指针指向70H
        LCALL INITIAL  ;调用启动LCM子程序进行初始化
        LCALL CLS      ;调用清除LCM子程序
        MOV A,#80H     ;向A送立即数80H设定显示地址为第一行第一列
        LCALL WRITE_COM;调用写指令到LCM子程序
        MOV DPTR,#LINE1;将第一行字符串的启始地址送如DPTR中
        LCALL DISP     ;调用显示字符串到LCM子程序
        MOV A,#0C0H    ;向A送立即数0C0H设定显示地址为第二行第一列
        LCALL WRITE_COM;调用写指令到LCM子程序
        MOV DPTR,#LINE2;将第二行字符串的启始地址送如DPTR中
        LCALL DISP     ;调用显示字符串到LCM子程序
        SJMP $         ;程序动态停机
        
LINE1:  DB " WWW.52C51.COM ",00H       ;第一行字符串
LINE2:  DB " 1602A ",00H       ;第二行字符串
        
INITIAL:MOV A,#38H     ;启动LCM子程序
        LCALL WRITE_COM
        MOV A,#0EH
        LCALL WRITE_COM
        MOV A,#06H
        LCALL WRITE_COM
        RET
        
CHECK_BUSY:
        PUSH ACC       ;查询忙碌信号子程序
BUSY_LOOP:
        CLR LCM_E
        SETB LCM_RW
        CLR LCM_RS
        SETB LCM_E
        MOV A,LCM_DATA
        CLR LCM_E
        JB ACC.7,BUSY_LOOP
        POP ACC
        LCALL DEL
        RET
        
WRITE_COM:
        LCALL CHECK_BUSY       ;写指令到LCM子程序
        CLR LCM_E
        CLR LCM_RS
        CLR LCM_RW
        SETB LCM_E
        MOV LCM_DATA,A
        CLR LCM_E
        RET
        
WRITE_DATA:
        LCALL CHECK_BUSY       ;写数据到LCM子程序
        CLR LCM_E
        SETB LCM_RS
        CLR LCM_RW
        SETB LCM_E
        MOV LCM_DATA,A
        CLR LCM_E
        RET
        
CLS:    MOV A,#01H     ;清除LCM子程序
        LCALL WRITE_COM
        RET
        
DEL:    MOV R6,#5      ;2.7MS延时子程序
D1:     MOV R7,#248
        DJNZ R7,$
        DJNZ R6,D1
        RET
        
DISP:   PUSH ACC       ;将A的内容压栈
DISP_LOOP:
        CLR A          ;A清零
        MOVC A,@A+DPTR ;查表将字符串内容送入A
        JZ END_DISP    ;若查到的内容为0则终止查表
        LCALL WRITE_DATA       ;调用写数据到LCM子程序
        INC DPTR       ;DPTR加1指向下一个对象
        SJMP DISP_LOOP ;跳转到DISP_LOOP循环执行
END_DISP:
        POP ACC        ;弹出压栈内容至A
        RET
        
        END


可能会用到的工具/仪表
相关文章
推荐文章
热门文章
章节目录
本站简介 | 意见建议 | 免责声明 | 版权声明 | 联系我们
CopyRight@2024-2039 嵌入式资源网
蜀ICP备2021025729号