[分享] CH549EVT开发板测试——驱动LCD5110显示屏

hujj   2019-7-4 16:29 楼主

    经过几天的测试,驱动LCD5110显示屏的代码终于移植成功,下面是测试过程的图片:

lcd_11.jpg

    这是显示的效果:

lcd_12.jpg

    在移植过程中,字库文件的函数定义花费了不少时间。由于有些时间没有接触C51了,我一尝试用ARM的定义方式将字库数据存放到EEPROM中,反复用static和const来定义字库文件,编译总出错,提示数据太大。在沁恒技术人员的提示下,改为用code来定义,编译就顺利通过了。下面是LCD5110的驱动代码:

 

#include ".\Public\CH549.H"
#include ".\Public\DEBUG.H"

#include ".\mydrive\lcd_5110.h"
#include ".\mydrive\ascii5x8.h"           //5x8ASCII字符集
#include ".\mydrive\charcode.h"           //12x16(14)汉字子集
#include ".\mydrive\asciicode.h"          //5x8(8)ASCII子集


/*********************************************
* 函数名称:Delay
* 函数功能:延时毫秒
* 入口参数:xms    :毫秒数
* 出口参数:无
* 备注:
*********************************************/
void Delay(UINT8 xms)  
{
    UINT8 x,y;
    for(x=xms;x>0;x--)
    for(y=10;y>0;y--);    //for(y=110;y>0;y--)
}


/*********************************************
* 函数名称:LCD_write_byte
* 函数功能:模拟SPI接口时序写数据/命令LCD
* 入口参数:data   :写入的数据;
*           dc        :写数据1/命令0选择
* 出口参数:无
* 备注:管脚D/C(LCD_DC)用于选择写的是命令(D/C=0)还是数据(D/C=1)
*********************************************/
void LCD_write_byte(UINT8 dat,UINT8 dc)
{
    UINT8 i;
    LCD_CLK = 0;                         //先拉低时钟CLK
    LCD_CE = 0;                          //选择5110
    LCD_DC = dc;                         //dc=0数据,dc=1命令

    for(i=0; i<8; i++)                   //发送8位
    {
        if (dat & 0x80){
            LCD_DIN = 1;
        }
        else{
            LCD_DIN = 0;
        }
        LCD_CLK = 1;

        Delay(1);

        dat = dat << 1;                     //移位,准备发送下一位
        LCD_CLK = 0;                     //发送同步时钟
    }
    
    LCD_CE = 1;                          //关闭5110
}

/*********************************************
* 函数名称:LCD_set_XY
* 函数功能:设置LCD坐标函数
* 入口参数:X   :0-83;
*           Y         :0-5
* 出口参数:无
* 备注:
*********************************************/
void LCD_set_XY(UINT8 X,UINT8 Y)
{
    LCD_write_byte(0x40 | Y,0); //column?
    LCD_write_byte(0x80 | X,0); //row?
}


/*********************************************
* 函数名称:LCD_clear
* 函数功能:5110清屏(用空白写满屏幕)
* 入口参数:无
* 出口参数:无
* 备注:、
*********************************************/
void LCD_clear(void)
{
    UINT8 i,j;
    LCD_set_XY(0,0);        //定位左上角
    for (i=0; i<6; i++)
    {
        for (j=0; j<84; j++)
        {
            LCD_write_byte(0x00,1);
        }
    }
}

 
/*********************************************
* 函数名称:LCD_init
* 函数功能:5110初始化
* 入口参数:无
* 出口参数:无
* 备注:接通电源后需要一个RES低电平脉冲复位,当VDD变为高电平之后
*       最多100ms,RST输入低电平(<0.3VDD)
*********************************************/
void LCD_init(void)
{
//    LCD_Config();                      //配置LCD连线
    LCD_RST = 0;                         //复位LCD5110
    Delay(2);
    LCD_RST = 1;

    LCD_CE = 0;                          //关闭LCD
    Delay(2);
    LCD_CE = 0;                          //关闭LCD

    LCD_write_byte(0x21,0);              //使用扩展LCD令设置LCD模式
    LCD_write_byte(0xc8,0);              //设置液晶偏置电压
    LCD_write_byte(0x06,0);              //温度校正(温度系数2)
    LCD_write_byte(0x13,0);              //1:48
    LCD_write_byte(0x20,0);              //使用基本命令,V=0,水平寻址
    LCD_write_byte(0x0c,0);              //设定显示模式,正常显示
    LCD_clear();                         //清屏

    LCD_CE = 0;                          //关闭LCD
}

 

/*********************************************
* 函数名称:LCD_write_ASCII
* 函数功能:显示字符串5*7(8)
* 入口参数:x,y,cid   :显示ASCII字符
* 出口参数:无            编号(行号)32~127
* 备注:ASCII码表的数组ASC_5[95][8]来寻址
*********************************************/
void LCD_write_ASCII(UINT8 X,UINT8 Y,UINT8 *stru)
{
    UINT8 i;
//    j = cid - 32;
    LCD_set_XY(X,Y);               //定位(左上角)
    while (1)
    {
        for ( i=0; i<5; i++)       //输出一个5*7字符
        {
            LCD_write_byte(ASC_5[*stru-32],1);
        }
        stru++;
        LCD_write_byte(0x00,1);    //插入空列
        if(*stru == '\0') break;   //在每个字符串的最后,会有一个'\0'
    }  
}


/*********************************************
* 函数名称:LCD_write_ASCII
* 函数功能:显示单个字符5*7(8)
* 入口参数:x,y,cid   :显示ASCII字符
* 出口参数:无            编号(行号)32~127
* 备注:ASCII码表的数组ASC_5[95][8]来寻址
*********************************************/
void LCD_write_ASC_SIN(UINT8 X,UINT8 Y,UINT8 cid)
{
    UINT8 i;
    LCD_set_XY(X,Y);               //定位(左上角)
    for ( i=0; i<5; i++)           //输出一个5*7字符
    {
        LCD_write_byte(ASC_5[cid-32],1);
    }
}


/*********************************************
* 函数名称:LCD_write_ASC7x12
* 函数功能:显示自定义字符7*12(16)
* 入口参数:x,y,cid   :显示的字符  0 1 2 3 4 5 6 7 8 9  =  m  s
* 出口参数:无            编号(行号)0,1,2,3,4,5,6,7,8,9,10,11,12
* 备注:ASCII码表的数组ASC_7[13][14]来寻址
*********************************************/
void LCD_write_ASC7x12(UINT8 X,UINT8 Y,UINT8 cid)
{
    UINT8 i;
    
    LCD_set_XY(X,Y);               //定位{左上角)
    for (i=0; i<7; i++)            //显示字符的上半部分(7列)
    {
        LCD_write_byte(ASC_7[cid],1);
    }
    
    LCD_set_XY(X,Y+1);             //显示字符的下半部分
    for (i=7; i<14; i++) 
    {
        LCD_write_byte(ASC_7[cid],1); 
    }
}


/*********************************************
* 函数名称:LCD_write_CHAR
* 函数功能:显示自定义字符12*14(16)
* 入口参数:x,y,cid   :显示的字符  电子点焊机接间隔毫秒时
* 出口参数:无            编号(行号)0,1,2,3,4,5,6,7,8,9,10
* 备注:CHAR字库的数组CHAR_12[11][24]来寻址
***********************************************/

void LCD_write_char(UINT8 x,UINT8 y,UINT8 cid)
{
    UINT8 i;
    
    LCD_set_XY(x,y);                //定位(左上角)
    for (i=0; i<12; i++)            //写字符的上半部分(12列)
    {
        LCD_write_byte(CHAR_12[cid],1);
    }
    
    LCD_set_XY(x,y+1);              //写字符的下半部分
    for (i=12; i<24; i++) 
    {
        LCD_write_byte(CHAR_12[cid],1); 
    }
}

/*********************************************
* 函数名称:LCD_write_string
* 函数功能:显示汉字字符串
* 入口参数:x,y,*stru :显示的字符串 
* 出口参数:无
* 备注:根据汉字内码从二维数组cid_12中找到字库中的行号,再逐个调用显示
***********************************************/

void LCD_write_string(UINT8 x,UINT8 y,UINT8 *stru)
{
    UINT8 j,n;
    while(1)
    {
//        for (j = 0; j < 38; j++)     //查找汉字对应字库的行号
        j = 0;
        while(1)
        {
            n = 0;                   //查找失败,用首个字替代
            
            if((stru[0] == cid_12[j][0])  &&  (stru[1] == cid_12[j][1]))
            {
                n = j;               //找到行号,结束跳出
                break;
            }
            j++;
            if(*cid_12 == '\0') break;
        }
        
        LCD_write_char(x, y, n);
        
        x += 12;
        stru += 2;
        if(*stru == '\0') break;    //在每个字符串的最后,会有一个'\0'
        
        LCD_write_byte(0x00,1);      //插入空列
    }
    
}


/*********************************************
* 函数名称:LCD_write_value
* 函数功能:显示变量字符5*7(8)或7*12(16)
* 入口参数:x,y,L,val :座标、长度、小数、前导零(1显示 0不显示)、变量
* 出口参数:无        编号(行号)
* 备注:ASCII码表的数组ASC_5[95][8]来寻址
*********************************************/
void LCD_write_value(UINT8 X,UINT8 Y,UINT8 L,UINT8 D,UINT8 Z,UINT16 val)
{
    UINT8 i,j,f = 0;              //列循环、字循环、显示标志
    UINT16 t,cid;                 //当前余数、当前数字
    UINT32 n;                     //当前倍数

    t = val;
    n = 1;
    if(Z == 1)
        f = 16;                     //空格=0,“0”=16
    for (j = 0; j < L; j++)
      n = n * 10;
    
    LCD_set_XY(X,Y);                //定位(左上角)

    for (j = L; j > 0; j--)         //字符循环开始
    {
        n = j < 2 ? 1: n / 10;      //计算当前的倍数
        cid = t / n;                //当前位数字
        t = t - (cid * n);

        if ((cid > 0)|(j-1 == D))   //显示字符0
            f = 16;    
        
        for ( i=0; i<5; i++)        //写一个5*7字符
        {
            LCD_write_byte(ASC_5[cid + f],1);
        }
        if ( D > 0 & D == (j - 1))
        {
            for ( i=0; i<5; i++)    //写小数点
            {
                LCD_write_byte(ASC_5[14],1);
            }
        }
        else
          if(j>1) LCD_write_byte(0x00,1);//插入空列
    }
}

 

 

 

回复评论

暂无评论,赶紧抢沙发吧
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复