2014年(38)
分类: 嵌入式
2014-03-13 16:56:35
本实验在驱动前一个实验的基础上实现了汉字和字母的显示。主要在于汉字写入函数Draw_Text16()和ASCII写入函数Draw_ASCII()的编写,这两个函数主要用到一个两重循环给每个点赋值相应的颜色,汉字占用16*16个像素比ASCII的8*16复杂一点,需要在第二层循环再来一次,具体实验代码后有详细注释。区分汉字与ASCII也很简单,ASCII码的最高位是0,而中文的最高位是1,因此当读取到的一个字节的最高位是0,则该字节为ASCII码,它的下一个字节与这个字节无关。编码规则:每个汉字是由两个字节表示的,前一个字节表示的区号,后一个字节表示的位号,那么汉字在汉字库中的位置为:94×(区号-1)+(位号-1)。具体到汉字在某一数据库中的位置,还需要乘以一个汉字字模所占的字节数,即[94×(区号-1)+(位号-1)]×一个汉字字模所占字节数。如一个字模大小为16×16的宋体数据库,库里每个汉字所占的字节为16×16÷8=32,则每个汉字在该宋体数据库中的位置为:[94×(区号-1)+(位号-1)]×32。
本实验实验代码如下:
#define GLOBAL_CLK 1
#include
#include
#include "def.h"
#include "option.h"
#include "2440addr.h"
#include "2440lib.h"
#include "2440slib.h"
#include "lcdlib.c"
#include "lcdlib.h"
#include "font_libs.h" //内有两个数组__HZK[ ]和__ASCII[ ]
#define LCD_XSIZE LCD_WIDTH
#define LCD_YSIZE LCD_HEIGHT
#define SCR_XSIZE LCD_WIDTH
#define SCR_YSIZE LCD_HEIGHT
volatile static unsigned short LCD_BUFFER[SCR_YSIZE][SCR_XSIZE];
void delay(int times)//延时函数
{
int i;
for(;times>0;times--)
for(i=0;i<400;i++);
}
void Lcd_init(void)
{
rGPCUP = 0xffffffff;
rGPCCON = 0xaaaa02a9;
rGPDUP = 0xffffffff;
rGPDCON = 0xaaaaaaaa;
rLCDCON1 = (LCD_PIXCLOCK << 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 = (13 << 8) | (LCD_HSYNC_LEN << 0);
rLCDCON5 = LCD_CON5;
rLCDSADDR1 = (((U32)LCD_BUFFER >> 22) << 21) | ((M5D((U32)LCD_BUFFER >> 1)) << 0);
rLCDSADDR2 = M5D(((U32)LCD_BUFFER + LCD_WIDTH * LCD_HEIGHT * 2) >> 1);
rLCDSADDR3 = LCD_WIDTH;
rLCDINTMSK|=(3); // 屏蔽LCD中断
rTCONSEL = 0; //无效LPC3480
rGPGUP=rGPGUP&(~(1<<4))|(1<<4); //GPG4上拉电阻无效
rGPGCON=rGPGCON&(~(3<<8))|(3<<8); //设置GPG4为LCD_PWREN
rGPGDAT = rGPGDAT | (1<<4) ; //GPG4置1
rLCDCON5=rLCDCON5&(~(1<<3))|(1<<3); //有效PWREN信号
rLCDCON5=rLCDCON5&(~(1<<5))|(0<<5); //PWREN信号极性不翻转
rLCDCON1|=1; //LCD开启
}
void Draw_Circular(U32 c)//画圆函数
{
int x,y ;
int tempX,tempY;
int radius = 80;
int SquareOfR = radius*radius;
for( y = 0 ; y
{
for( x = 0 ; x < LCD_HEIGHT ; x++ )
{
if(y<=120 && x<=160)
{
tempY=120-y;
tempX=160-x;
}
else if(y<=120&& x>=160)
{
tempY=120-y;
tempX=x-160;
}
else if(y>=120&& x<=160)
{
tempY=y-120;
tempX=160-x;
}
else
{
tempY = y-120;
tempX = x-160;
}
if ((tempY*tempY+tempX*tempX)<=SquareOfR)
LCD_BUFFER[y][x] = c ;
}
}
}
//绘制屏幕背景颜色,颜色为c
void Brush_Background( U32 c)
{
int x,y ;
for( y = 0 ; y < SCR_YSIZE; y++ )
{
for( x = 0 ; x < SCR_YSIZE; x++ )
{
LCD_BUFFER[y][x] = c ;
}
}
}
void PutPixel(U32 x,U32 y, U32 c )//绘制像素点
{
LCD_BUFFER[y][x] = c;
}
void Draw_Text16(U32 x,U32 y,U32 color,const unsigned char ch[])//绘制大小为16×16的中文字符
{
unsigned short int i,j;
unsigned char mask,buffer;
for(i=0;i<16;i++)
{
mask=0x80; //掩码
buffer=ch[i*2]; //提取一行的第一个字节
for(j=0;j<8;j++)
{
if(buffer&mask)
{
PutPixel(x+j,y+i,color); //为笔画上色
}
mask=mask>>1;
}
mask=0x80; //掩码复位
buffer=ch[i*2+1]; //提取一行的第二个字节
for(j=0;j<8;j++)
{
if(buffer&mask)
{
PutPixel(x+j+8,y+i,color); //为笔画上色
}
mask=mask>>1;
}
}
}
void Draw_ASCII(U32 x,U32 y,U32 color,const unsigned char ch[])//绘制大小为8×16的ASCII码
{
unsigned short int i,j;
unsigned char mask,buffer;
for(i=0;i<16;i++)
{
mask=0x80;
buffer=ch[i];
for(j=0;j<8;j++)
{
if(buffer&mask)
{
PutPixel(x+j,y+i,color);
}
mask=mask>>1;
}
}
}
void Main(void)
{
unsigned char String[]="My name is lilei.我的名字是李磊。";
int length = sizeof(String);
int i,j=0;
unsigned char qh,wh;
const unsigned char *mould;
Lcd_init();// 初始化lcd
rLCDCON1|=1; //打开lcd开关
Brush_Background(0xffffff);//绘制背景为白色
for(i=0;i
{
if(String[i]&0x80) //中文字符
{
qh=String[i]-0xa0; //区号
wh=String[i+1]-0xa0; //位号
mould = & __HZK[ ( ( qh - 1 )*94 + wh- 1 )*32 ];
Draw_Text16(100,4+j,0x0f,mould);
j+=16;//每写完一个右移16个像素
i++;
}
else //ASCII码字符
{
mould = & __ASCII[String[i]*16];
Draw_ASCII(100,4+j,0x0,mould);
j+=8;//每写完一个右移8个像素
}
}
while(1);
}