第四篇:嵌入式Linux利用开发基础知识第六章:文件显示 - 6.3 中文字符的点阵显示批改 lcd_put_chinese 函数,能够指定字符色彩。实现 lcd_put_str 函数, 能够输入混合的中英文字符,比方“中国 china”,反对主动换行。成果:读取指定文件中英文数据到lcd显示文件:show_chinses.c
#include <linux/fb.h>#include <sys/mman.h>#include <sys/ioctl.h>#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include <fcntl.h>#include <string.h>#include <stdio.h>extern const unsigned char fontdata_8x16[]; // fontdata_8x16 独自在 fontdata.cstatic int fd_fb = 0;static unsigned char *fb_base = NULL;static struct fb_var_screeninfo var = {0};static int screen_size = 0;static int line_width = 0;static int pixel_width = 0;static int fd_hzk16;static struct stat hzk_stat = {0};static unsigned char *hzkmem = {0};void lcd_put_pixel(int x, int y, unsigned int color){ unsigned char *pen_8 = fb_base + y * line_width + x * pixel_width; unsigned short *pen_16 = (unsigned short*)(pen_8); unsigned int *pen_32 = (unsigned int*)(pen_8); unsigned int red = 0; unsigned int green = 0; unsigned int blue = 0; switch (var.bits_per_pixel) { case 8: *pen_8 = color; break; case 16: 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 open %dbpp\n", var.bits_per_pixel); break; }}void lcd_put_ascii(int x, int y, char c, unsigned int color){ unsigned char *dots = (unsigned char*)(&fontdata_8x16[c * 16]); int i = 0; int b = 0; for (i=0; i<16; ++i) { for (b=7; b>=0; --b) { if (dots[i] & (1 << b)) lcd_put_pixel(x+7-b, y+i, color); else lcd_put_pixel(x+7-b, y+i, 0xffffff); } }}void lcd_put_ascii_str(int x, int y, const unsigned char *str, unsigned int color){ unsigned int index = 0; while(*str) { if (*str == '\r' || *str == '\n') { y += 16; index = 0; } else { lcd_put_ascii(x + index, y, *str, color); index += 8; } ++str; }}void lcd_put_chinese(int x, int y, const unsigned char *str, unsigned int color){ unsigned int area = str[0] - 0xa1; unsigned int where = str[1] - 0xa1; unsigned char *dots = hzkmem + (area * 94 + where) * 32; unsigned char byte = 0; int i = 0; int j = 0; int b = 0; 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)) lcd_put_pixel(x+j*8+7-b, y+i, color); else lcd_put_pixel(x+j*8+7-b, y+i, 0xffffff); } } }}void lcd_put_str(int x, int y, const unsigned char*str, unsigned int color){ unsigned int index = 0; while (*str) { if (*str <= 0xa1) { if (*str == '\r' || *str == '\n') { y += 16; index = 0; } else { lcd_put_ascii(x + index, y, *str, color); index += 8; } str++; } else { lcd_put_chinese(x + index, y, str, color); index += 16; str+=2; } }}int test_show(const unsigned char *path){ int fd_src = 0; unsigned char *srcmem = NULL; struct stat src_stat = {0}; fd_src = open(path, O_RDONLY); if (fd_src < 0) { printf("can't open %s\n", path); return -1; } if(fstat(fd_src, &src_stat)) { printf("can't get src_stat\n"); return -1; } srcmem = (unsigned char*)mmap(NULL, src_stat.st_size, PROT_READ, MAP_SHARED, fd_src, 0); if (srcmem == (void*)-1) { printf("can't mmap for srcmem\n"); return -1; } lcd_put_str(10, 10, srcmem, 0x11ee88); munmap(srcmem, src_stat.st_size); close(fd_src); }int main(int argc, char **argv){ int i = 0; 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 == (void*)-1) { printf("can't mmap for hzkmem\n"); return -1; } 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 fd_fb var\n"); return -1; } screen_size = var.xres * var.yres * var.bits_per_pixel / 8; pixel_width = var.bits_per_pixel / 8; line_width = var.xres * var.bits_per_pixel / 8; fb_base = mmap(NULL, screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb, 0); if (fb_base == (void*)-1) { printf("cant mmap for fb_base\n"); return -1; } memset(fb_base, 0xff, screen_size); //==================================================== if (argc == 1) { // lcd_put_ascii(100, 100, 'A', 0); // lcd_put_ascii_str(100, 100, "Hello word\nHow are you", 0x567894); // lcd_put_chinese(200, 200, "中", 0x123456); lcd_put_str(100, 100, "A中A\nhahah", 0x11ee88); } else { test_show(argv[1]) ; } //==================================================== munmap(fb_base, screen_size); munmap(hzkmem, hzk_stat.st_size); close(fd_fb); close(fd_hzk16); return 0;}编译运行:
...