您的位置:首页 > 其它

LCD 显示文字与图片

2015-09-24 09:21 417 查看
第一种方法:直接输汉字或字母等 直接输出

在GB2312编码中对所收汉字进行了“分区”处理,94个区,每区含有94个汉字/符号

 * 汉字由两个ASCII码组成,第一个减去160就是区码,第二个减去160就是位码

 * 在C中处理时,如"啊"的代码是B0A0 +1,定义*pStr = "啊",则*pStr = 176(B0),*(pStr+1) = 161(A0+1)

 * 第一个ASC 176 - 160(0xA0) = 16 ,第二个 ASC 161 - 160(0xA0) = 1,所以区位码为:1601

 * 按GB2312表顺序,从第一行开始向右每取8个点作为一个字节,如果最后不足8个点就补满8位。

 * 8位逐行取模,第一点为高位.16X16汉字一行就有两个字节 X 16行

 * 因字模数字式从0开始,所以 起始位为 ( ( (*pStr - 0xA0) - 1 ) * 94 + ( *(pStr+1) - 0xA0 ) - 1 ) * 32                  

 */

  /* 左侧字模起始地址 */

   pZKL = &__CHS[ ( ( (*pStr - 0xA0) - 1 ) * 94 + ( *(pStr+1) - 0xA0 ) - 1 ) * 32];

   /* 右侧字模起始地址 */ 

   pZKR = &__CHS[ ( ( ( (*pStr - 0xA0) - 1 ) * 94 + ( *(pStr+1) - 0xA0 ) - 1 ) * 32 ) + 1];

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

* 函数名称: Lcd_Print_ZW

* 功能描述: 在LCD屏幕上指定坐标点写汉字 NETC-陈建长.

* 输入参数: (unsigned int x,unsigned int y坐标),(unsigned char *pStr 单个汉字 如 “啊”),

             (unsigned int c,unsigned int bk_c颜色和区域颜色),unsigned int st  区域颜色选择

     st = 1 有 st = 0 无,在动态变化的情况下,如果没有区域颜色则前后信息叠加.   

* 输出参数: None        

* 返回参数: None

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

void Lcd_Print_ZW(unsigned int x,unsigned int y,unsigned char *pStr,unsigned int c,unsigned int bk_c,unsigned int st)

{

    unsigned short int i,j;     

    unsigned char *pZKL,*pZKR,mask,buf;   

    pZKL = &__CHS[ ( ( (*pStr - 0xA0) - 1 ) * 94 + ( *(pStr+1) - 0xA0 ) - 1 ) * 32];

    pZKR = &__CHS[ ( ( ( (*pStr - 0xA0) - 1 ) * 94 + ( *(pStr+1) - 0xA0 ) - 1 ) * 32 ) + 1];

    for( i = 0 ; i < 16 ; i++ )

       {

              /* 处理左侧显示 */

              mask = 0x80;

              buf = *pZKL;

     *(pZKL += 2);

              for( j = 0 ; j < 8 ; j++ )

              {

                     if( buf & mask )

                     {

                            PutPixel(x+j,y+i,c);

                     }

      else

      {

       if( st )

                  {

                      PutPixel(x+j,y+j,bk_c);

                  }

      }

                    

                     mask = mask >> 1;

              }     

             /* 处理右侧显示 */

              mask = 0x80;

              buf = *pZKR;

     *(pZKR += 2);

              for( j = 0 ; j < 8 ; j++ )

              {

                     if( buf & mask )

                     {

                            PutPixel(x+j + 8,y+i,c);

                     }

      else

      {

      if( st )

                     {

                         PutPixel(x+j + 8,y+i,bk_c);

                     }

     }

                     mask = mask >> 1;

              }                

       }

}

eg : 输出:“啊”

Lcd_Print_ZW(100, 100, "啊", 0x0, 0x0, 0);

第二种方法:用字符取模软件生成字符数组,读取输出

代码如下:

*************************************************

file name     LCD_hanzi

function    显示16*16汉字 和 16*8 ASCII码字符

硬件设备    mini2440开发板

        索尼X-35 3.5寸液晶屏

lcd参数    宽和高 240x320

        TFT 16bpp显示

完成时间    2011-08-10

作者        周茂夫

problem    暂无

修改记录    暂无

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

#define    GLOBAL_CLK        1

#include <stdlib.h>

#include <string.h>

#include "def.h"

#include "option.h"

#include "2440addr.h"

#include "2440lib.h"

#include "2440slib.h"

#include "mmu.h"

#include "profile.h"

#include "memtest.h"

#include "zifu.h"

#define baudrate 115200

#define    LCD_WIDTH    240

#define    LCD_HEIGHT    320

//#define LCD_CLKCAL    17    //这个我计算出来是17参考程序给的是4 测试俩个都可以

                            //影响不大 测试25 30 都还可以

#define LCD_CLKCAL    17        

#define    LCD_RIGHT_MARGIN 25

#define    LCD_LEFT_MARGIN 0

#define    LCD_HSYNC_LEN 4

#define    LCD_UPPER_MARGIN 0

#define    LCD_LOWER_MARGIN 4

#define    LCD_VSYNC_LEN 9

#define    LCD_XSIZE    LCD_WIDTH

#define    LCD_YSIZE    LCD_HEIGHT

#define    SCR_XSIZE    LCD_WIDTH

#define    SCR_YSIZE    LCD_HEIGHT

extern const unsigned char sunflower_240x320[];

extern const unsigned char GB2312Dot16X16[];

volatile static unsigned short LCD_BUFFER[SCR_YSIZE][SCR_XSIZE];//LCD
BUFFER

#define M5D(n)        ((n)&0x1fffff)//设置显示缓存区时取地址的低21位

#define    LCD_ADDR    ((U32)(LCD_BUFFER))    

/********横向取模,字节不倒序,C51格式*******/

unsigned char zhou[]=

{

0x00,0x00,0x1F,0xFC,0x10,0x84,0x13,0xE4,0x10,0x84,0x10,0x84,0x17,0xF4,0x10,0x04,

0x13,0xE4,0x12,0x24,0x12,0x24,0x13,0xE4,0x22,0x24,0x20,0x04,0x40,0x14,0x80,0x08,

} ;

unsigned char mao[]=

{

0x04,0x40,0x04,0x40,0xFF,0xFE,0x04,0x40,0x00,0xA0,0x00,0x90,0x3F,0xFE,0x20,0x80,

0x20,0x84,0x20,0x48,0x20,0x50,0x20,0x60,0x20,0xA0,0x43,0x12,0x4C,0x0A,0x80,0x04,

} ;

unsigned char Y[]=

{

0x00,0x00,0x00,0xEE,0x44,0x44,0x28,0x28,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00,

} ;

unsigned char zhao[]=

{

0x00,0x00, 0xF7,0x7E, 0x95,0x04, 0x95,0x04,

0x96,0x74, 0x96,0x54, 0x95,0x54, 0x95,0x54,

0x95,0x54, 0xF5,0x54, 0x97,0x74, 0x04,0x04,

0x04,0x04, 0x04,0x04, 0x04,0x14, 0x04,0x08,

} ;

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

void delay(int times)

{

    int i = 1000;

    while(times--)

    {

        for(; i>0;--i)

            ;

    }

}

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

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

UART_int初始化led IO端口GPBCON5-8

初始化GPBHCON为串口通信

配置串口通信寄存器

配置中断寄存器

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

void UART_int_init(void)

{

    /********configuration
LED IO port**********/

    rGPBCON &=~(0xff<<10);

    rGPBCON |= 0x55<<10;

    

    /*******configuration
GPHCON to UART*******/

    rGPHCON &=~(0xf<<4);

    rGPHCON |= 0xa<<4;

    

    /****configuration UART0 communication register******/

    rULCON0 = 0x03
;                        //8-bits,1 stop bit, no parity

    rUCON0 = 0x05
;

    rUBRDIV0=
(int)(PCLK/baudrate/16)-1;    //configuration
UART baudrate

    

    /*****clean interrupt bit clea RX_INT******/

    rSUBSRCPND |= 0x1;

    rSRCPND |= 1<<28;

    rINTPND |= 1<<28;

    /******open
UART interrupt*********/

    rINTSUBMSK &=~(0x1);

    rINTMSK &=~(0x1<<28);    

}

//UART send byte

void UART_send_byte(char Tx_data)

{

    while(!(rUTRSTAT0&0x2));//wait
Txempty

    if(Tx_data=='\n')        //Tx'\n'

    {

        rUTXH0 = 0x0d
;

        while(!(rUTRSTAT0&0x2));

        rUTXH0 = 0x0a
;

    }

    else

    {

        rUTXH0 = Tx_data
;

    }

}

//UART sendstring

void UART_send_string(const char*str)

{

    while(*str)

    {

        UART_send_byte(*str);

        str++;

    }

}

//UART receive byte

void UART_receive_byte(void)

{

    char temp ;

    

    while(!(rUTRSTAT0&0x1));    //wait
RX ready

    

    temp = rURXH0
;

    

    switch(temp)            //测试发送单个字符

    {

        case 's': rGPBDAT&=~(0xf<<5);
break;

        case 'p': rGPBDAT|=(0xf<<5);
break;

    }

    UART_send_byte(temp);

}

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

中断处理函数

置1清除中断,注意顺序,先子中断后父中断

点亮led灯

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

void __irq UART0_interrupt(void)

{

    /******clean
interrupt bit*************/

    rSUBSRCPND |= 0x1;

    rSRCPND |= 1<<28;

    rINTPND |= 1<<28;

    

    rGPBDAT &=~(0xf<<5);    //lighten
led

    UART_receive_byte();

}

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

function    initialize LCD IO port VD[0:15] VM VLINE VCLK VFREAM

input         void

return        void

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

static void Lcd_port_init(void)

{

    rGPCUP    = 0xffffffff
; //Disable Pull-up register

    rGPCCON    = 0xaaaa02a8
; //Initialize VD[7:0],VM,VFREAM,VLINE,VCLK

    

    rGPDUP    = 0xffffffff
; //Disable Pull-up register

    rGPDCON    = 0xaaaaaaaa
; //Initialize VD[15:8]

    

}

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

function    configarution LCDCON1-5 LCDSADDR1-3 LCD INTERRUPT TPAL

            etc register TFT 16bpp

input         void

return        void

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

static void Lcd_init(void)

{

    rLCDCON1 =
(LCD_CLKCAL<<8)|(3<<5)|(12<<1);    

       rLCDCON2 =
(LCD_UPPER_MARGIN << 24)|((LCD_HEIGHT-
1)<< 14)|(LCD_LOWER_MARGIN<<
6)|(LCD_VSYNC_LEN<< 0);

       rLCDCON3 =
(LCD_RIGHT_MARGIN << 19)|((LCD_WIDTH-
1)<< 8)|(LCD_LEFT_MARGIN<<
0);

       rLCDCON4 =
(LCD_HSYNC_LEN << 0);    

       rLCDCON5 =
(1<<11)|(1
<< 9)|(1
<< 8)|(1<<6)|(1
<< 3)|(1
<< 0);

    

    rLCDSADDR1    =
((LCD_ADDR>>22)<<21)|(M5D(LCD_ADDR>>1));

    //LCDBASEL OFFSIZE=0,PAGEWIDTH=LCD_WIDTH,
x2的原因 16bpp 每个像素点2个字节,>>1见地址对应关系 16bpp

    rLCDSADDR2    = M5D((LCD_ADDR+ LCD_WIDTH* LCD_HEIGHT*
2)>>1);

     rLCDSADDR3    = LCD_WIDTH
;

     

     rLCDINTMSK    |= 3;//屏蔽中断

     rTCONSEL    = 0
; //LPC3600 LCC3600 无效

     rTPAL        = 0
; //禁止临时调色板

 }

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

function    Envid turn
on or off

input         onoff    1,Envid turn
on

return        void

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

static void Lcd_EnvidOnOff(int onoff)

{

     if(onoff==1)

         rLCDCON1 |= 1;//ENVIDON

     else

         rLCDCON1 &=~(1<<0);//ENBID
OFF

}

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

function    LCD power enable

input         pwren    1, enable lcd power

return        void

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

static void Lcd_PowerEnable(int pwren)

{

     rGPGUP    |=(1<<4);//Pull-up
Disable

     rGPGCON    |=(3<<8);//GPG4is
LCD_PWREN

     

     rLCDCON5&=~(1<<5);    //invpwren
正常极性

     rLCDCON5 = rLCDCON5
& ~(1<<3)|(pwren<<3);    //PWREN
使能

}

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

function    Filling sole colour into LCD background

input         c         colour

return        void

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

static void Lcd_FillCor(U16 c)

{

     unsigned int x,y;

     for(y=0; y<SCR_YSIZE; y++)

     {

         for(x=0; x<SCR_XSIZE; x++)

         {

             LCD_BUFFER[y][x]= c;        

         }

     }

}

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

function    Paint picture

input         x0 y0            assign start bit

            level vertical    the wide and high of picture

            *bmp            the picture
string

return        void

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

static void Paint_BMP(int x0,int y0,int level,
int vertical,
const unsigned char
*bmp)

{

     int x, y;

     U32 col ;

     int p = 0;

     

     for(y=0; y<vertical; y++)

     {

         for(x=0; x<level; x++)

         {

             col = bmp[p+1]|(bmp[p]<<8);    //16bpp
一个像素点用俩个字节

             if(((x0+x)<SCR_XSIZE)&&((y0+y)<SCR_YSIZE))

                 LCD_BUFFER[y0+y][x0+x]=
col ;

             p += 2;

         }

     }

}

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

function    Display 像素点

input         x y    display start bit

            col        color of the char

return        void

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

static void PutPixel(U32 x, U32 y, U16 col)

{

    LCD_BUFFER[y][x]= col;

}

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

function    Display 汉字 hzk16 16*16

input         x y    display start bit

            col        color of the char

            ch[]    字模数组

return        void

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

static void Draw_Text16(U32 x, U32 y, U16 col,const unsigned char ch[])

{

    unsigned short i, j
;

    unsigned char mask, tem
;

    for(i=0; i<16; i++)

    {

        mask= 0x80
;

        tem    = ch[i*2];    //俩个字节一组16位,取第一个字节

        for(j=0; j<8; j++)

        {

            if(tem& mask)

            {

                PutPixel(x+j, y+i, col);

            }

            mask = mask
>> 1 ;

        }

        

        mask = 0x80
;

        tem = ch[i*2+ 1];

        for(j=0; j<8; j++)

        {

            if(tem& mask)

            {

                PutPixel(x+j+8, y+i, col);

            }

            mask = mask
>> 1 ;

        }

    }

}

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

function    Display ASCII 字符 16*8

input         x y    display start bit

            col        color of the char

            ch[]    字模数组

return        void

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

static void Draw_ASCII(U32 x, U32 y, U16 col,const unsigned char ch[])

{

    unsigned short i, j
;

    unsigned char temp, mask
;

    for(i=0; i<16; i++)

    {

        mask = 0x80
;

        temp = ch[i];

        for(j=0; j<8; j++)

        {

            if(mask& temp)

            {

                PutPixel(x+j, y+i, col);

            }

            mask = mask
>> 1 ;

        }

    }

}

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

function    Display 汉字字符 16*16

input         x y    display start bit

            col        color of the char

            str[]    字符数组

            strlen 字符串长度 字节表示

return        void

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

static void Draw_ch_lib(U32 x, U32 y, U16 col,const unsigned char str[],
unsignedint strlen)

{

    int loc, i;

    unsigned char qh, wh
;

    const unsigned char
*pchlib ;

    

    for(loc=0, i=0; i<strlen;
i++)

    {

        if(str[i]& 0x80)

        {

            qh = str[i]- 0xa0;

            wh = str[i+1]- 0xa0;

            pchlib =
&GB2312Dot16X16[( 94*(qh-1)+(wh-1)-1410)*32];

            Draw_Text16( x+loc, y, col, pchlib);

            i++;

            loc += 16;

        }

    }

}

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

串口UART是挂在PCLK总线上的,需要设置PCLK时钟,即需要设置2440时钟。

首先需要设置PLLCON寄存器设置CPU时钟(FCLK),然后设置FCLK HCLK PCLK的

分频比,确定好PCLK时钟。

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

int Main(void)

{

    unsigned int length
;

    unsigned char display[]="啊周茂夫是个大笨蛋";

    /*****************【CLOCK】******************/

    MMU_Init();

    ChangeMPllValue(127,2,1);        //405MHZ

    ChangeClockDivider(13,12);//1:3:6    

    

    /**************【UART】**********************/

    UART_int_init();

    UART_send_string("wo zhen de hen yun si \n");    

    pISR_UART0 =
(U32)UART0_interrupt
;

    /*************【LCD】************************/

    Lcd_port_init();

    Lcd_init();

    Lcd_PowerEnable(1);

    Lcd_EnvidOnOff(1);

    UART_send_string("LCD initial \n");

    

    Lcd_FillCor(0xffff);

    Draw_Text16(16, 20, 0x0, zhou)     ;

    Draw_Text16(32, 20, 0x0, mao)     ;     //汉字后需要16位

    Draw_ASCII (48, 20, 0x0, Y)     ;

    Draw_ASCII (56, 20, 0x0, Y)     ;

    Draw_Text16 (100, 20, 0x0, zhao)     ;    

    Draw_Text16(80, 20, 0x0, zhou)     ;    

    

    length = sizeof(display)- 1;     //用sizeof可以直接算出数组占内存的字节数,减去1

                                    //字符串结束符占一个字节

    Draw_ch_lib(10, 100,0x0, display, length);

    while(1)

    {

        //Lcd_FillCor((0x00<<11)|(0x00<<5)|(0x00<<0));
    //clear screen

        //Paint_BMP(0,0,240,320,sunflower_240x320);            //filling
picture sunflower

    }

    return 0 ;

}

字符与图片取模软件 :
点击打开链接

GB2312汉字编码表与其字符数组: 
文档在这
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  LCD 编码