lcd.c

来自「这个是黑白LCD的一个典型的驱动函数集 原创 请大家多支持下下!如果有什么问题请」· C语言 代码 · 共 1,237 行 · 第 1/4 页

C
1,237
字号

void DispGrhPixel (INT8U x0, INT8U y0, COLORS colors)
{
    INT8U  chTemp;
    INT16U nTemp;


    if ((x0 < DISP_GRH_MAX_X) && (y0 < DISP_GRH_MAX_Y)) {
        DispGrhPosSetCur(x0, y0);                 // 写入显示地址 准备处理数据
        DispCtrlCmdWr(DISP_CMD_BASIC);            // 基本命令集
        nTemp   = DispCtrlDataRd(1) << 8;         // 读显示数据16BIT的高字节
        nTemp  += DispCtrlDataRd(0);              // 读显示数据16BIT的低字节
        chTemp  = 15 - (x0 % 16);                 // 字节里位置
        if (colors == DISP_COLORS_BLACK) {        //
            SETBIT(nTemp, chTemp);                // 根据颜色设置来更新象素信息
        } else {
            CLRBIT(nTemp, chTemp);                // 根据颜色设置来更新象素信息
        }
        DispGrhPosSetCur(x0, y0);                 // 重新写人位置数据
        DispCtrlCmdWr(DISP_CMD_BASIC);            // 基本命令集
        DispCtrlDataWr((INT8U)(nTemp >> 8));      // 写高字节数据
        DispCtrlDataWr((INT8U)(nTemp >> 0));      // 写低字节数据
    }
}
#endif


/********************************************************************************************************
* 功 能 : 图形方式画一个点
* 入 口 : 'x' X坐标
*         'y' Y坐标
* 返 回 : 无
********************************************************************************************************/
#if DISP_GRH_EN > 0 && DISP_GRH_POINT_EN > 0

void  DispGrhPoint    (INT8U x0, INT8U y0, COLORS colors)
{
    DispLock();                                   //
    DispGrhPixel(x0, y0, colors);                 //
    DispUnLock();                                 //
}
#endif


/********************************************************************************************************
* 功 能 : 图形方法设置坐标
* 入 口 : 'x' 显示的X坐标位置  范围0~DispMaxX
*         'y' 显示的Y坐标位置  范围0~DispMaxY
* 返 回 : 无
* 说 明 :
********************************************************************************************************/
#if DISP_GRH_EN > 0

static void DispGrhPosSetCur (INT8U x, INT8U y)
{
    INT8U TempX;
    INT8U TempY;


    TempX = x >> 4;                               // (/16)左右关系 屏分为8个16BIT数据存储 高在前低在后
    TempY = y >> 5;                               // (/32)上下关系 屏分为上下两屏 上下都是0x80~0x80+32
    if (TempY == 0)  {                            // Y=0上半部分
        y = 0x80 + y;                             // Y坐标 0x80~0x87 去掉上半部分的位置从0~32
        x = 0x80 + TempX;                         // X坐标 0x80~0x80+32
    } else {
        y = 0x80 - 32 + y;                        // Y坐标 0x88~0x8f 去掉上半部分的位置从0~32
        x = 0x88 + TempX;                         // X坐标 0x80~0x80+32
    }
    DispCtrlCmdWr(DISP_CMD_EXTEND);               // 扩展命令集
    DispCtrlCmdWr(y);                             // 先写Y坐标
    DispCtrlCmdWr(x);                             // 再写X坐标
}
#endif


/********************************************************************************************************
* 功 能 : 图形方式显示一个字符串
* 入 口 : 'x0'  X起始坐标
*         'y0'  Y起始坐标
*         's'   字符串指针
*         'len' 显示字符串长度
* 返 回 : 无
* 说 明 : 1 strlen >= len时 按照len长度输出字符串
*         2 strlen <  len 输出整个字符串 不足len的部分用' '填满
*         3 这个函数遇到显示边界会换行显示 不足一字符显示的区域会换行
********************************************************************************************************/
#if DISP_GRH_EN > 0 && DISP_GRH_STR_EN > 0

void DispGrhStr (INT8U x0, INT8U y0, const char *s, COLORS colors)
{
    if ((x0 < DISP_GRH_MAX_X) && (y0 < DISP_GRH_MAX_Y)) {
        DispLock();
        for (  ;  ; s++) {
            if (x0 >= DISP_GRH_MAX_X) {           // 这里暂定义为8*8点阵字库
                x0  = 0;                          //
                y0 += 8;                          //
                if (y0 >= DISP_GRH_MAX_Y) {       //
                    DispUnLock();                 //
                    return;                       //
                } else {
                    DispGrhPosSetCur(x0, y0);     //
                }
            }

            switch (*s) {                         // 处理字符
            case '\0'  :                          // 退出 字符串完
                DispUnLock();                     //
                return;                           //

            case '\n'  :                          // 回车换行
            case '\r'  :                          // 回车 这里理解为此行停止 多于字符不输出
                x0  = 0;                          //
                y0 += 8;                          //
                if (y0 < DISP_GRH_MAX_Y) {        //
                    DispGrhPosSetCur(x0, y0);     //
                } else {
                    DispUnLock();                 //
                    return;                       //
                }
                break;

            case '\a'  :                          // 鸣铃
            case '\b'  :                          // 退格
            case '\f'  :                          // 走纸换页
            case '\t'  :                          // 横向跳向下一制表位置
                break;

            case '\\'  :                          // 反斜线符'\\'
            case '\''  :                          // 单引号符
            case '\"'  :                          // 双引号符
            default :                             // 其它暂时为支持
                DispGrhChar(x0, y0, *s, colors);  // 写入数据
                x0 += 6;                          //
                break;
            }
        }
    }
}
#endif


/********************************************************************************************************
* 功 能 : LCM显示初始化
* 入 口 : 无
* 返 回 : 无
* 说 明 : 无
********************************************************************************************************/

void DispInit (void)
{
    DispInitHard();                               // 初始化基本工作环境

    DispSem = OSSemCreate(1);                     //

#if DISP_TXT_EN > 0
    DispTxtInit();                                //
#endif

#if DISP_GRH_EN > 0
    DispGrhInit();                                //
#endif
}


/********************************************************************************************************
* 功 能 : LCM硬件初始化
* 入 口 : 无
* 返 回 : 无
* 说 明 : 无
********************************************************************************************************/

static void DispInitHard (void)
{
//    PINSEL2 = PINSEL2 & 0xFF8FFFCF;               // RW RS 为GPIO
    IO2DIR |= BIT(LCDRS)|BIT(LCDRW)|BIT(LCDE)|BIT(LCDLAMP1)|BIT(LCDLAMP2)|(0xff<<LCDDATA);

    SETBIT(LCDLAMP1_PORT_HIGH, LCDLAMP1);
    SETBIT(LCDLAMP2_PORT_HIGH, LCDLAMP2);

    SETBIT(LCDRS_PORT_HIGH, LCDRS);
    SETBIT(LCDRW_PORT_HIGH, LCDRW);
    SETBIT(LCDE_PORT_LOW,   LCDE);                // 锁定LCD屏

    DelayNMs(40);                                 //
//    OSTimeDly(10);

    DispCtrlCmdWr(DISP_CMD_BASIC);                // 选择基本命令集
    DelayNMs(2);                                  //
//    OSTimeDly(1);
    DispCtrlCmdWr(DISP_CMD_BSMOVE);               // Display no move
    DelayNMs(2);                                  //
//    OSTimeDly(1);
    DispCtrlCmdWr(DISP_CMD_BSCLS);                // 清屏
    DelayNMs(50);                                  //
//    OSTimeDly(30);
    DispCtrlCmdWr(DISP_CMD_BSACR);                // 坐标回到00
    DelayNMs(2);                                  //
//    OSTimeDly(1);
    DispCtrlCmdWr(DISP_CMD_BSON);                 // 显示开
    DelayNMs(2);                                  //
//    OSTimeDly(1);
}


/********************************************************************************************************
* 功 能 : 显示上锁
* 入 口 : 无
* 返 回 : 无
* 说 明 : 无
********************************************************************************************************/
#if DISP_TXT_EN > 0 || DISP_GRH_EN > 0

static void DispLock (void)
{
    INT8U err;
//
//
    OSSemPend(DispSem,  0, &err);
//    OSSemPend(IOMuxSem, 0, &err);
}
#endif


/********************************************************************************************************
* 功 能 : LCM背光控制 与硬件有关 需要根据硬件环境更改
* 入 口 : 'state' 开或关 DISP_CMD_LAMP_ON  DISP_CMD_LAMP_OFF  DISP_CMD_LAMP_HALF
* 返 回 : 无
********************************************************************************************************/

void  DispSetLamp (BOOL state)
{
    switch (state) {
    case DISP_CMD_LAMP_OFF :                      // 全关输出模式
        SETBIT(LCDLAMP1_PORT_HIGH, LCDLAMP1);     //
        SETBIT(LCDLAMP2_PORT_HIGH, LCDLAMP2);     // 1为强输出方式为1
        break;

    case DISP_CMD_LAMP_ON :                       // 全亮输出模式
        SETBIT(LCDLAMP1_PORT_LOW,  LCDLAMP1);     //
        SETBIT(LCDLAMP2_PORT_LOW,  LCDLAMP2);     //
        break;

    case DISP_CMD_LAMP_HALF :                     // 半亮模式
//        CLRBIT(LCDLAMP_DDR,  LCDLAMP);            //
//        CLRBIT(LCDLAMP_PORT, LCDLAMP);            //
        break;

    default :
        break;
    }
}


/********************************************************************************************************
* 功 能 : 显示BCD码
* 入 口 : 'row' 是当前显示行  row 最大是DispMaxRows-1 行
*         'col' 是当前显示列  col 最大是DispMaxCols-1 列
*         'dat' 是显示的数据
* 返 回 : 无
* 说 明 : 1> 只显示到十位
********************************************************************************************************/
#if DISP_TXT_EN > 0 && DISP_TXT_BCD_EN > 0 && DISP_TXT_CHAR_EN > 0

void DispTxtBCD (INT8U row, INT8U col, INT8U dat)
{
    DispLock();                                   //
    dat %= 100;                                   //
    DispTxtCharExt(row, col,   dat / 10  + '0');  //
    DispTxtCharExt(row, col+1, dat % 10  + '0');  //
    DispUnLock();                                 //
}
#endif


/********************************************************************************************************
* 功 能 : 在指定的行列位置 显示一个字符
* 入 口 : 'row' 是当前显示行  row 最大是DispMaxRows-1 行
*         'col' 是当前显示列  col 最大是DispMaxCols-1 列
*         'c'   是按照row 和col 决定的位置显示的字符 CA12864K 有扩展的字符 需要自己定义 其他兼容ASCII码
* 返 回 : 无
* 说 明 : 无
********************************************************************************************************/
#if DISP_TXT_EN > 0 && DISP_TXT_CHAR_EN > 0

void  DispTxtChar (INT8U row, INT8U col, char c)
{
    DispLock();                                   //
    DispTxtCharExt(row, col, c);                  //
    DispUnLock();                                 //
}
#endif


/********************************************************************************************************
* 功 能 : 在指定的行列位置 显示一个字符
* 入 口 : 'row' 是当前显示行  row 最大是DispMaxRows-1 行
*         'col' 是当前显示列  col 最大是DispMaxCols-1 列
*         'c'   是按照row 和col 决定的位置显示的字符 CA12864K 有扩展的字符 需要自己定义 其他兼容ASCII码
* 返 回 : 无
* 说 明 : 无
********************************************************************************************************/
#if DISP_TXT_EN > 0 && (DISP_TXT_CHAR_EN > 0 || DISP_TXT_BCD_EN > 0 || DISP_TXT_HEX_EN > 0)

static void  DispTxtCharExt (INT8U row, INT8U col, char c)
{
    if ((row < DISP_TXT_MAX_ROWS) && (col < DISP_TXT_MAX_COLS)) {
        DispCtrlCmdWr(DISP_CMD_BASIC);            // 基本命令集
        DispTxtPosSetFront(row, col);             // 设置上一次的位置坐标
        DispCtrlDataWr(c);                        // 顺序写入这次的数据
    }

⌨️ 快捷键说明

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