第一种方法:直接输汉字或字母等 直接输出
在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屏幕上显示汉字和ASCII字符的两种方法。第一种方法涉及GB2312编码,通过计算汉字的区位码来定位字模并逐点绘制。第二种方法使用预先生成的字符数组进行输出。文中还提供了相关的代码示例,包括LCD初始化、延时函数以及串口通信的设置。
2476

被折叠的 条评论
为什么被折叠?



