嵌入式图形显示
一、液晶显示器 嵌入式系统中多数采用液晶显示器(LCD,Liquid Crystal Display),LCD是一种低成本、低功率的器件,既可显示文字,又可显示图像。
二、显示控制器 控制器 GPU 接口 嵌入式处理器 MCU MPU DSP
三、帧缓图形显示 VRAM显存 VRAM显存 VRAM是一种内存,可以使用系统内存,也可以是独立显卡(GPU)的专用内存。
四、显示参数 1)分辨率:显示器支持的像素多少,一般采用屏幕的宽x高表示,如:800x600,1600x1200, 480x320。 2)“像素”(Pixel) 是由 Picture(图像) 和 Element(元素)这两个单词的字母所组成的,是用来计算数码影像的一种单位,是计算机屏幕上所能显示的最小单位。 3)颜色深度:显示一个像素点的位数; 4)颜色:单色、伪彩色、彩色、真彩色 真彩色:16/24/32 RGB ARGB RGB565 RGB888 ARGB8888
四、显示参数 像素颜色是由红(Red)、绿(Green)、蓝(Blue)三种颜色组成,即所谓RGB。 对于16位深颜色来说,采用565格式表示颜色,其中Red占高5、Grenn占中间6位、Blue占低5位。每个像素占VRAM中的2个字节。 对于24位深颜色,RGB分别占用8位,每个像素占用VRAM中的3个字节。
显示一个点 显存 f800
显示一个字符 A 显存
五、点阵字符 对于LCD显示的字符,大都采用点阵方式进行显示,字符点阵有5*7、8*16、12*24,而汉字是有两个字节组成,一般有16*16、24*24点阵。
五、点阵字符 ASCII字符集 7位编码的字符集只能支持128个字符,为了表示更多的欧洲常用字符对ASCII进行了扩展,ASCII扩展字符集使用8位(bits)表示一个字符,共256字符。 ASCII扩展字符集比ASCII字符集扩充出来的符号包括表格符号、计算符号、希腊字母和特殊的拉丁符号。
五、点阵字符 GB2312 字符集 1.名称的由来 GB2312又称为GB2312-80字符集,全称为《信息交换用汉字编码字符集·基本集》,由原中国国家标准总局发布,1981年5月1日实施。 2.特点 GB2312是中国国家标准的简体中文字符集。它所收录的汉字已经覆盖99.75%的使用频率,基本满足了汉字的计算机处理需要。在中国大陆和新加坡获广泛使用。
五、点阵字符 3.包含内容 GB2312收录简化汉字及一般符号、序号、数字、拉丁字母、日文假名、希腊字母、俄文字母、汉语拼音符号、汉语注音字母,共 7445 个图形字符。其中包括6763个汉字,其中一级汉字3755个,二级汉字3008个;包括拉丁字母、希腊字母、日文平假名及片假名字母、俄语西里尔字母在内的682个全角字符。
五、点阵字符 4、汉字表示 (1) 分区表示: GB2312中对所收汉字进行了“分区”处理,每区含有94个汉字/符号。这种表示方式也称为区位码。 各区包含的字符如下:01-09区为特殊符号;16-55区为一级汉字,按拼音排序;56-87区为二级汉字,按部首/笔画排序;10-15区及88-94区则未有编码。
五、点阵字符 (2) 双字节表示 两个字节中前面的字节为第一字节,后面的字节为第二字节。习惯上称第一字节为“高字节” ,而称第二字节为“低字节”。 “高位字节”使用了0xA1-0xF7(把01-87区的区号加上0xA0),“低位字节”使用了0xA1-0xFE(把01-94加上0xA0)。
五、点阵字符 5.编码举例 以GB2312字符集的第一个汉字“啊”字为例,它的区号16,位号01,则区位码是1601,在大多数计算机程序中,高字节和低字节分别加0xA0得到程序的汉字处理编码0xB0A1。计算公式是:0xB0=0xA0+16, 0xA1=0xA0+1。
五、点阵字符 2.汉字内码 汉字内码是用于汉字信息的存储、交换、检索等操作的机内代码,一般采用两个字节表示。英文字符的机内代码是七位的ASCII码,当用一个字节表示时,最高位为“0”。为了与英文字符能相互区别,汉字机内代码中两个字节的最高位均规定为“1”。 注意:有些系统中字节的最高位用于奇偶校验位,这种情况下用三个字节表示汉字内码。
五、点阵字符 3.汉字字模码 字模码是用点阵表示的汉字字形代码,它是汉字的输出形式。 根据汉字输出的要求不同,点阵的多少也不同。字模点阵的信息量很大,所占存储空间也很大。因此字模点阵只能用来构成汉字库,而不能用于机内存储。字库中存储了每个汉字的点阵代码。当显示输出或打印输出时才检索字库,输出字模点阵,得到字形。
五、点阵字符
六、点阵字库 Asc16.h Hzk16.h
七、显示程序开发 屏幕大小:4.3吋 分辨率: 480x272 颜色深度:16位 颜色表示:RGB565
1)显示设备初始化 显示作为一种输出设备,在linux系统采用设备文件的方式进行管理,显示设备文件名称为:/dev/fb0 打开设备 dev_fb = open("/dev/fb0", O_RDWR);
1)显示设备初始化 获取设备的参数 struct fb_var_screeninfo vinfo; ioctl ( dev_fp, FBIOGET_VSCREENINFO, &vinfo ) 在头文件 include/linux/fb.h中定义数据结构: struct fb_var_screeninfo { __u32 xres; /* visible resolution */ __u32 yres; __u32 xres_virtual; /* virtual resolution */ __u32 yres_virtual; __u32 xoffset; /* offset from virtual to visible */ __u32 yoffset; /* resolution */ __u32 bits_per_pixel; /* guess what */
1)显示设备初始化 获取设备VRAM地址 mmap将一个文件或者其它对象映射进内存。文件被映射到多个页上,如果文件的大小不是所有页的大小之和,最后一个页不被使用的空间将会清零。 void *mmap(void *start, size_t length, int prot, int flags,int fd, off_t offset); start:映射区的开始地址,设置为0时表示由系统决定映射区的起始地址。 length:映射区的长度。 prot:期望的内存保护标志,不能与文件的打开模式冲突。 flags:指定映射对象的类型,映射选项和映射页是否可以共享。 fd:有效的文件描述词。一般是由open()函数返回。 offset:被映射对象内容的起点。
1)显示设备初始化 Width = vinfo.xres; Height = vinfo.yres; fb_bpp = vinfo.bits_per_pixel; fb_size = width*height*fb_bpp/8; fb_addr = (short *)mmap( 0, fb_size, PROT_READ | PROT_WRITE, MAP_SHARED, dev_fb, 0);
2)画一个点 void put_pixel(int x, int y, short color) { short * vram = fb_addr + y*width + x; *vram = color; } width fb_addr 例子: put_pixel(100, 30, 0xf800); height (100,30)
3)画一条水平线 void draw_h_line(int x, int y, int w, short color) { short *vram = fb_addr + y*width + x; while (w--) *vram++ = color; } 例子: draw_h_line (100,30,100,0xffff);
4)画一条垂直线 void draw_v_line(int x, int y, int h, short color) { short *vram = fb_addr + y*width + x; while (h--) *vram = color; vram += width; } 例子: draw_v_line (100,30,60,0xf800);
5)清屏? void clear_screen(short color) { }
思考题 1)画直线? 2)画矩形? 3)矩形填充? 4)画圆? 5)椭圆? 6)多边形填充?
思考题 1)显示点阵字符? 2)显示点阵汉字?
画一个字符 void draw_char8x16(int x, int y, int fc , int bc , char ch){ unsigned short * vram , *addr; unsigned char *dot; int i, j; vram = ((unsigned short *)fb_addr) + y * width + x; dot = &asc16[ch * 16]; for (j=0; j<16; j++) { addr = vram; for (i=0; i<8; i++) { if (dot[j]&(0x80>>i)) *addr ++= (unsigned short)fc; else *addr ++= (unsigned short)bc; } vram += width;
显示一个汉字 (1)汉字在计算机以两个字节表示,即汉字内码,起始内码为0xa1a1; (3)每个区共有94个字,即0xff – 0xa1 = 0x5e = 94; (4)对于16×16点阵的汉字共有32个字节表示。 (5)汉字在库中的位置偏移量。 unsigned char chinease[3]=“你"; i=chinease[0]-0xa0; /* 获得区码 */ j=chinease[1]-0xa0; /* 获得位码 */ off = ( (i-1)*94+(j-1) ) * 32;
显示一个汉字 void draw_hz16(int x, int y, int fc , int bc , unsigned short hzcode) vram= ((unsigned short *)fb_addr) + y * width + x; pDot = (unsigned char*)Hzk16 + off; for(i=0; i<16; i++) { addr=vram+15; for(k=0; k<16; k++) { if( pDot[i*2+(1-k/8)] & (1<<(k%8)) ) *addr = (unsigned short)fc; else *addr = (unsigned short)bc; addr--; } vram += width;