一、字符编码
为更好的存储和展示,于是出现了字符编码。下面来看一下字符编码的发展过程。分为三个阶段:
阶段1:ASCII码
欧美人发明,用一个字节来标志。也就是常说的ASCII码,由于英语中只有26个英文字母,以及常用符号,可以很简单的编码出来。Ox41:A;0x61:a。
阶段2:国家编码GB2312(GBK)
我们国家有上千的汉子,所以编码要比较多一些,用两个字节来表示一个汉字。对于内地采用GB2312编码(GBK);big5(繁体字)等等。
D6DO:中。
阶段3:世界统一unicode码
世界需要一个统一的标准,于是出现了unicode,常见的utf-8;utf-16等
问题:
源文件用不同的编码方式编写,会导致执行结果不一样。
怎么解决?编译程序时,要指定字符集
man gcc , /charset
-finput-charset=charset 表示源文件的编码方式, 默认以UTF-8来解析
-fexec-charset=charset 表示可执行程序里的字时候以什么编码方式来表示,默认是UTF-8
gcc -o a a.c
gcc -finput-charset=GBK-fexec-charset=UTF-8 -o utf-8_2 ansi.c
二、点阵显示
(1)打开lcd设备:
- fd_fb = open("/dev/fb0", O_RDWR);
- if (fd_fb < 0)
- {
- printf("can't open /dev/fb0\n");
- return -1;
- }
(2)得到lcd信息
- if (ioctl(fd_fb, FBIOGET_VSCREENINFO, &var))
- {
- printf("can't get var\n");
- return -1;
- }
- if (ioctl(fd_fb, FBIOGET_FSCREENINFO, &fix))
- {
- printf("can't get fix\n");
- return -1;
- }
(3)显存占据多少字节
- line_width = var.xres * var.bits_per_pixel / 8;
- pixel_width = var.bits_per_pixel / 8;
- screen_size = var.xres * var.yres * var.bits_per_pixel / 8;
(4)LCD提供mmap
显存fb内存映射:
fbmem= (unsigned char *)mmap(NULL , screen_size, PROT_READ | PROT_WRITE, MAP_SHARED,fd_fb, 0);
screen_size:大小
PROT_READ | PROT_WRITE, MAP_SHARED:可读可写
(5)显示A+中
unsignedchar str[] = "中";
lcd_put_ascii(var.xres/2, var.yres/2, 'A');
printf("chinesecode: %02x %02x\n", str[0], str[1]);
lcd_put_chinese(var.xres/2 + 8, var.yres/2, str);
return0;
三、代码
- #include <sys/mman.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <unistd.h>
- #include <linux/fb.h>
- #include <fcntl.h>
- #include <stdio.h>
- #include <string.h>
- #define FONTDATAMAX 4096
- static const unsigned char fontdata_8x16[FONTDATAMAX] = {
- ...
- }
- int fd_fb;
- struct fb_var_screeninfo var; /* Current var */
- struct fb_fix_screeninfo fix; /* Current fix */
- int screen_size;
- unsigned char *fbmem;
- unsigned int line_width;
- unsigned int pixel_width;
- int fd_hzk16;
- struct stat hzk_stat;
- unsigned char *hzkmem;
- /* color : 0x00RRGGBB */
- void lcd_put_pixel(int x, int y, unsigned int color)
- {
- unsigned char *pen_8 = fbmem+y*line_width+x*pixel_width;
- unsigned short *pen_16;
- unsigned int *pen_32;
- unsigned int red, green, blue;
- pen_16 = (unsigned short *)pen_8;
- pen_32 = (unsigned int *)pen_8;
- switch (var.bits_per_pixel)
- {
- case 8:
- {
- *pen_8 = color;
- break;
- }
- case 16:
- {
- /* 565 */
- red = (color >> 16) & 0xff;
- green = (color >> 8) & 0xff;
- blue = (color >> 0) & 0xff;
- color = ((red >> 3) << 11) | ((green >> 2) << 5) | (blue >> 3);
- *pen_16 = color;
- break;
- }
- case 32:
- {
- *pen_32 = color;
- break;
- }
- default:
- {
- printf("can't surport %dbpp\n", var.bits_per_pixel);
- break;
- }
- }
- }
- void lcd_put_ascii(int x, int y, unsigned char c)
- {
- unsigned char *dots = (unsigned char *)&fontdata_8x16[c*16];
- int i, b;
- unsigned char byte;
- for (i = 0; i < 16; i++)
- {
- byte = dots[i];
- for (b = 7; b >= 0; b--)
- {
- if (byte & (1<<b))
- {
- /* show */
- lcd_put_pixel(x+7-b, y+i, 0xffffff); /* 白 */
- }
- else
- {
- /* hide */
- lcd_put_pixel(x+7-b, y+i, 0); /* 黑 */
- }
- }
- }
- }
- void lcd_put_chinese(int x, int y, unsigned char *str)
- {
- unsigned int area = str[0] - 0xA1;
- unsigned int where = str[1] - 0xA1;
- unsigned char *dots = hzkmem + (area * 94 + where)*32;
- unsigned char byte;
- int i, j, b;
- for (i = 0; i < 16; i++)
- for (j = 0; j < 2; j++)
- {
- byte = dots[i*2 + j];
- for (b = 7; b >=0; b--)
- {
- if (byte & (1<<b))
- {
- /* show */
- lcd_put_pixel(x+j*8+7-b, y+i, 0xffffff); /* 白 */
- }
- else
- {
- /* hide */
- lcd_put_pixel(x+j*8+7-b, y+i, 0); /* 黑 */
- }
- }
- }
- }
- int main(int argc, char **argv)
- {
- unsigned char str[] = "中";
- fd_fb = open("/dev/fb0", O_RDWR);
- if (fd_fb < 0)
- {
- printf("can't open /dev/fb0\n");
- return -1;
- }
- if (ioctl(fd_fb, FBIOGET_VSCREENINFO, &var))
- {
- printf("can't get var\n");
- return -1;
- }
- if (ioctl(fd_fb, FBIOGET_FSCREENINFO, &fix))
- {
- printf("can't get fix\n");
- return -1;
- }
- line_width = var.xres * var.bits_per_pixel / 8;
- pixel_width = var.bits_per_pixel / 8;
- screen_size = var.xres * var.yres * var.bits_per_pixel / 8;
- fbmem = (unsigned char *)mmap(NULL , screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb, 0);
- if (fbmem == (unsigned char *)-1)
- {
- printf("can't mmap\n");
- return -1;
- }
- fd_hzk16 = open("HZK16", O_RDONLY);
- if (fd_hzk16 < 0)
- {
- printf("can't open HZK16\n");
- return -1;
- }
- if(fstat(fd_hzk16, &hzk_stat))
- {
- printf("can't get fstat\n");
- return -1;
- }
- hzkmem = (unsigned char *)mmap(NULL , hzk_stat.st_size, PROT_READ, MAP_SHARED, fd_hzk16, 0);
- if (hzkmem == (unsigned char *)-1)
- {
- printf("can't mmap for hzk16\n");
- return -1;
- }
- /* 清屏: 全部设为黑色 */
- memset(fbmem, 0, screen_size);
- lcd_put_ascii(var.xres/2, var.yres/2, 'A');
- printf("chinese code: %02x %02x\n", str[0], str[1]);
- lcd_put_chinese(var.xres/2 + 8, var.yres/2, str);
- return 0;
- }