⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 12864a.c

📁 128*64点阵单色液晶屏控制C代码
💻 C
字号:
/*============================================
液晶模块:12864A
端口分配:
A15 --->EA;      A11--->CS2;       A10--->CS1
A9  --->D/I;     A8 --->R/W;
**********************************************

指令代码:
1. 开显示:0x3f
2. 关显示:0x3e
3. 设置X值(页地址):0xb8+X(X=0---7)
4. 设置Y值(列地址):0x40+Y(Y=0---63)
5. 设置Z值(显示起始行):0xc0+Z(Z=0---63)
2007-3-7 21:37
==============================================*/

//#ifndef _12864A_H_
//#define _12864A_H_


#include <reg52.h>
#include <absacc.h>
#include <intrins.h>

#define uchar unsigned char
#define uint unsigned int
#define PAGE 0xb8    //X基值
#define ROW 0x40     //Y基值
#define STRTLINE 0xc0  //Z基值


//定义外部数据端口
#define LcdAddr_wril XBYTE [0x8800]        //LCD 写左半屏指令寄存器端口
#define LcdAddr_rdil XBYTE [0x8900]        //LCD 读左半屏指令寄存器端口
#define LcdAddr_wrdl XBYTE [0x8a00]        //LCD 写左半屏数据寄存器端口
#define LcdAddr_rddl XBYTE [0x8b00]        //LCD 读左半屏数据寄存器端口
#define LcdAddr_wrir XBYTE [0x8400]        //LCD 写右半屏指令寄存器端口
#define LcdAddr_rdir XBYTE [0x8500]        //LCD 读右半屏指令寄存器端口
#define LcdAddr_wrdr XBYTE [0x8600]        //LCD 写右半屏数据寄存器端口
#define LcdAddr_rddr XBYTE [0x8700]        //LCD 读右半屏数据寄存器端口
#define LcdAddr_wri  XBYTE [0x8c00]        //LCD 写指令寄存器端口
#define LcdAddr_rdi  XBYTE [0x8d00]        //LCD 读指令寄存器端口
#define LcdAddr_wrd  XBYTE [0x8e00]        //LCD 写数据寄存器端口
#define LcdAddr_rdd  XBYTE [0x8f00]        //LCD 读数据寄存器端口


//#define LcdWaitIdle() while (LcdAddr_rdi & 0x80)


//函数声明
static void LcdWaitIdle ( void );
extern void LcdSwitch ( bit );
extern void LcdReset ( void );
extern void LcdCls ( void );
extern void LcdClrLine ( uchar );
extern void LcdPutchar ( char *dat, uchar, uchar, bit, bit );


//函数定义
//读LCD状态,等待空闲
static void LcdWaitIdle ( void )
{
    while ( LcdAddr_rdi & 0x80 );    //提取并判断忙标志位
}


//LCD显示开关,0为关显示(0x3e),1为开显示(0x3f)
void LcdSwitch ( bit mode )
{
    LcdWaitIdle ();
    LcdAddr_wri =mode ? 0x3f : 0x3e;
}


//LCD复位
void LcdReset ( void )
{
    LcdSwitch (0);       //关显示
    LcdWaitIdle ();
    LcdAddr_wri = 0xc0;  //设置Z=0
    LcdWaitIdle ();
    LcdAddr_wri = 0xb8;  //设置X=0
    LcdWaitIdle ();
    LcdAddr_wri = 0x40;  //设置Y=0
    LcdWaitIdle ();
    LcdSwitch (1);        //开显示
    LcdWaitIdle ();
    LcdCls ();           //清屏
}


//LCD清屏
void LcdCls ( void )
{
    uchar idata page, row;
    for ( page =0; page<8; page++ )
    {
        LcdWaitIdle ();
        LcdAddr_wri = PAGE +page;
        LcdWaitIdle ();
        LcdAddr_wri = ROW;
        for ( row = 0; row<64; row++ )
        {
            LcdWaitIdle ();
            LcdAddr_wrd = 0x00;
        }
    }
}

/*
LCD清除某一行
参数:line ,范围:1-4
*/
void LcdClrLine ( uchar line )
{
    uchar idata page, row;
    line =(line-1) & 0x03;
    for ( page=line*2; page<line*2+2; page++)
    {
        LcdWaitIdle ();
        LcdAddr_wri = PAGE +page;
        LcdWaitIdle ();
        LcdAddr_wri = ROW;
        for ( row = 0; row<64; row++ )
        {
            LcdWaitIdle ();
            LcdAddr_wrd = 0x00;
        }
    }
}


/*显示字符
第一个参数为要显示的数据的首地址
第二个参数为行地址, 1---4
第三个参数为列地址, 1---16(两屏统一编制)
第四个参数为全/半角选择,1为全角,0为半角
第五个参数为反显开关,1为反显,0不反显
*/
void LcdPutchar ( char *dat, uchar page, uchar row, bit quanjiao, bit reverse )
{
    uchar idata count, temp;
    uchar idata x, y;
    page -= 1, row -= 1;
    x = PAGE + (page << 1);       //页初始值
    y = ROW + ((row & 0x07) * 8);          //列初始值
    if ( quanjiao )        //全角字符
    {
        if ( row < 7 )     //完全在左半屏显示
        {
            for ( temp = 0; temp < 2; temp++ )
            {
                LcdWaitIdle ();
                LcdAddr_wril = x + temp;  //写入地址
                LcdWaitIdle ();
                LcdAddr_wril = y;
                for ( count = 0; count < 16; count++ )  //写入数据
                {
                    LcdWaitIdle ();
                    LcdAddr_wrdl = reverse ? ~dat[count + (temp * 16)] : dat[count + (temp * 16)];
                }
            }
        }
        else if ( row > 7 )    //完全在右半屏显示
        {
            for ( temp = 0; temp < 2; temp++ )
            {
                LcdWaitIdle ();
                LcdAddr_wrir = x + temp;   //写入地址
                LcdWaitIdle ();
                LcdAddr_wrir = y;
                for ( count = 0; count < 16; count++ )    //写入数据
                {
                    LcdWaitIdle ();
                    LcdAddr_wrdr = reverse ? ~dat[count + (temp * 16)] : dat[count + (temp * 16)];
                }
            }
        }
        else        //左右半屏各半个字符
        {
            for ( temp = 0; temp < 2; temp++ )
            {
                LcdWaitIdle ();
                LcdAddr_wril = x + temp;    //写入地址
                LcdWaitIdle ();
                LcdAddr_wril = y;
                for ( count = 0; count < 8; count++ )   //写入数据
                {
                    LcdWaitIdle ();
                    LcdAddr_wrdl = reverse ? ~dat[count + (temp * 16)] : dat[count + (temp * 16)];
                }
                LcdWaitIdle ();
                LcdAddr_wrir = x + temp;    //写入地址
                LcdWaitIdle ();
                LcdAddr_wrir = ROW;
                for ( count = 8; count < 16; count++ )    //写入数据
                {
                    LcdWaitIdle ();
                    LcdAddr_wrdr = reverse ? ~dat[count + (temp * 16)] : dat[count + (temp * 16)];
                }
            }
        }
    }
    else     //半角字符
    {
        if ( row < 8 )  //左半屏显示
        {
            for ( temp = 0; temp < 2; temp++ )
            {
                LcdWaitIdle ();
                LcdAddr_wril = x + temp;    //写入地址
                LcdWaitIdle ();
                LcdAddr_wril = y;
                for ( count = 0; count < 8; count++ )   //写入数据
                {
                    LcdWaitIdle ();
                    LcdAddr_wrdl = reverse ? ~dat[count + (temp * 8)] : dat[count + (temp * 8)];
                }
            }
        }
        else        //右半屏显示
        {
            for ( temp = 0; temp < 2; temp++ )
            {
                LcdWaitIdle ();
                LcdAddr_wrir = x + temp;   //写入地址
                LcdWaitIdle ();
                LcdAddr_wrir = y;
                for ( count = 0; count < 8; count++ )    //写入数据
                {
                    LcdWaitIdle ();
                    LcdAddr_wrdr = reverse ? ~dat[count + (temp * 8)] : dat[count + (temp * 8)];
                }
            }
        }
    }
}


//#endif  //_12864A_H_

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -