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

📄 5.txt

📁 LCD 的C语言驱动程序
💻 TXT
📖 第 1 页 / 共 3 页
字号:

       wricmd( 0x10 | (xdot >> 4 ));   

       wricmd(0xe0);

       for(i=0;i<16;i++)                  //显示上半个汉字

       {

              wridata(hzdata[i]);

       }

       wricmd(0xee);

       wricmd( 0xb0+cursor.y+1); 

       wricmd(xdot & 0x0f);

       wricmd( 0x10 | (xdot >> 4 ));   

       wricmd(0xe0);

       for(;i<32;i++)                      //显示下半个汉字

       {

              wridata(hzdata[i]);

       }

       wricmd(0xee);

}

*****************************************/

这个程序的作用就是在当前光标位置显示一个16*16 汉字或者全角字符。入口参数ch1表示该汉字的区码,入口参数ch2表示位码。

说到这里可能有一些朋友不理解了。下面我来讲一下。前面已经介绍了汉字库的一些知识,虽然汉字库种类繁多,但都是按照区位的顺序排列的。前一个字节为该汉字的区号,后一个字节为该字的位号。每一个区记录94个汉字,位号则为该字在该区中的位置。因此,汉字在汉字库中的具体位置计算公式为:94*(区号-1)+位号-1。减1是因为数组是以0为开始而区号位号是以1为开始的。这仅为以汉字为单位该汉字在汉字库中的位置,那么,如何得到以字节为单位得到该汉字在汉字库中的位置呢?只需乘上一个汉字字模占用的字节数即可,即:(94*(区号-1)+位号-1)*一个汉字字模占用字节数,而按每种汉字库的汉字大小不同又会得到不同的结果。以16*16点阵字库为例,计算公式则为:(94*(区号-1)+(位号-1))*32。汉字库文该从该位置起的32字节信息即记录了该字的字模信息。

Ok,明白了这些,这个程序就很好理解了,其实质是和我们分析的上一个显示ASC字符的程序是差不多的,首先除了定义,就是寻址汉字在flash中的物理位置。

由于在中文环境下,输入的是汉字的内码,我们必须将之转换成区位码,算出偏移量,从字库中找到对应的汉字,将其字模显示即可。内码转换成区位码方法如下: 
    qh=c1-0xa0           wh=c2-0xa0 
  其区位码就是: 
    qw=qh*0xff+wh 
    该汉字在字库中离起点的位置是: 
    offset=(94*(qh-1)+(wh-1))*32L??????????????

其他步骤和上一个函数几乎一模一样,就不多废话了~。





/*****************************************

void setcursor(uchar x, uchar y)

{

        if ( x<= LCD_MAX_X )

               cursor.x= x;

        else

               cursor.x= LCD_MAX_X;



        if ( y<= LCD_MAX_Y )

               cursor.y= y;

        else

               cursor.y= LCD_MAX_Y-1;

}

*****************************************/


再看接下来的这个程序。这个程序的作用是设置光标位置,以8×8点阵为一个光标单位,入口参数表示x方向和y方向光标位置。LCD_MAX_X和LCD_MAX_Y的含义和计算公式在刚开始的时候我们就已经说过了。至于这里为什么是LCD_MAX_Y-1,前面已经说了一个字符或者汉字都应该由两个page来提供数据,现在我需要在7,8页显示东西,那么我应该是把纵坐标点设置到7页吧?呵呵,其实点破就很简单了。




/*****************************************

void lcdstring( uchar *pst)

{

       while ( *pst != 0 )

       {

              if ( *pst < 0x80 ) //小于0x80是字符

           {

             if (*pst==0x0a)  setcursor(0, cursor.y+2); //处理回车换行

             else if (*pst== 0x0d) setcursor(0, cursor.y );

             else

             {

                            show_asc(*pst);  //显示ASC字符

                            cursor.x++;

                            if (( cursor.x > LCD_MAX_X )&& (*(pst+1)!=0x0a)){cursor.x=0;cursor.y=cursor.y+2;}

                     }

                     pst++;     //下一个要显示的字符

              }

              else         //大于0x80是汉字

              {

                     if ( cursor.x>= LCD_MAX_X )

                     {

                            show_asc(0x20);   //一行的尾部只有半个汉字位置的处理,加一个空格,在下一行开始显示

                            cursor.x=0;cursor.y=cursor.y+2;

                            if (cursor.y> LCD_MAX_Y) cursor.y=0; //

                     }

                     show_hz(*pst, *(pst+1)); //显示一个汉字

                     cursor.x+=2;

                     pst+=2;

                     if ((cursor.x> LCD_MAX_X)&& (*(pst+1)!=0x0a)){cursor.x=0;cursor.y=cursor.y+2;}

              }

              if ( cursor.y> LCD_MAX_Y ){     cursor.x=0;cursor.y=0;return;}  

       }

}

*****************************************/

这个程序呢,也就是我们这篇文章介绍的内容的中心程序!地位重要吧。那么他的作用是什么呢?就是在当前光标位置显示字符串拉。入口参数就是要显示的字符串。更关键的是同时也显示汉字!。什么?你还是没有理解到这个东西的好处?这样说吧,只要你的程序中包含我们所介绍的这些程序,那么在应用程序中,我们如果想让lcd显示“风”,那么我们就直接lcdstring(“风”)就行了。哈哈,这么神奇的功能,实现起来其实是很简单的拉。下面我门就一起来分析分析这个函数。

首先是字符处理函数。前面的while,if语句中的内容都很好理解,大家看程序注释就行了,这里我要说的是if (*pst==0x0a)  setcursor(0, cursor.y+2); 这句是处理回车换行,为什么?因为0x0a在asc码表中就是表示换行的,而接下来的0x0d是表示回车的,还有后来汉字显示需要用的0x20表示space。呵呵,因为我当时看的时候半天没有找到asc码表,为了避免让大家也都去找,这里直接说出来了。为什么是cursor.y+2呢?相信大家已经知道答案了。什么?你不知道?ohyeah,请看上一页~

这里有必要再讲讲cursor.x++;这句。为什么是cursor.x自增一?横坐标一个字符不是占用8个点么?千万不要忘了,横坐标的点是用xdot表示的。计算公式是什么呢?xdot=cursor.x*8;。明白了吧?

接下来就是汉字处理部分。其流程和前一部分完全一样,只不过cursor.x和pst都是自增2,原因当然是因为汉字是由区码和位码决定的,因此占用的字节数是字符的两倍~呵呵,你看看显示汉字的语句不是show_hz(*pst, *(pst+1))么?

到这里,我们的学习历程就基本结束了。整个程序的精华已经给大家介绍完了。当然最后还剩两个“在当前光标以十进制方式在液晶上显示一个字节的值”和“在当前光标显示一个ASC字符”两个函数,不过非常简单,这里只是作为附录附在后面,有兴趣的朋友可以试试自己分析一下。

这只是许多种lcd控制器其中一种的使用方法。但是不要怕,我这几天又看了看其他的驱动控制器,原理其实是一样的,只不过是实现功能的程序可能不同,所以最关键的还是要理解思想。思想理解了,学别的类似东西也就相通了。

希望看到这个文章各位都能获得一些知识和心得。如果能够帮助你,将是我莫大的荣幸。



附录: 

//**********************************************

//在当前光标以十进制方式在液晶上显示一个字节的值

//入口:要显示的值

lcddigit(uchar ch)

{

       uchar i[4];

       i[0]=(0x30+ch/100);

       i[1]=(0x30+(ch%100)/10);

       i[2]=(0x30+ch%10);

       i[3]=0;   //添加结束符号

       lcdstring(i);

}

//***********************************

//在当前光标显示一个ASC字符

//入口:要显示的字符

lcdchar(uchar ch)

{

       uchar i[2];

       i[0]=ch;

       i[1]=0; //添加结束符号

       lcdstring(i);

}


--------------------------------------------------------------------------------



copyright by 风雷

⌨️ 快捷键说明

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