一、实验目的
1.编写能够在嵌入式开发板LCD上显示汉字的程序;
2.在Ubuntu系统中编译上述程序生成可执行文件;
3.到开发板中验证。
二、实验步骤
1. Ubuntu系统上编写验证程序
Ubuntu系统上编写的验证程序如下,为了验证是否能够正确从HZK16字库中读取出某个字。
HZK16汉字16*16点阵字库的使用及实例程序
2. Ubuntu系统上编写能够在板子上执行的程序
要在LCD上显示“福州大学”,首先打开FrameBuffer驱动:fd_fb = open(“/dev/fb0”, O_RDWR),之后使用函数mmap映射显示存储器,最后调用函数PrintLCD显示字体,代码如下:
#include <stdio.h> #include <stdlib.h>#include <fcntl.h>#include <sys/mman.h>#include <sys/types.h>#include <sys/stat.h>#include <string.h>#include <unistd.h>#define FONT_COLOR 0xf100 // 红色#define SCREEN_WIDTH 1280#define SCREEN_HEIGHT 1600#define PIXEL_BYTES 2#define ZOOM_FACTOR 20 // 放大倍数#define CHAR_SPACING 10 // 字符间距unsigned short *fb = 0;void getHZCode(unsigned char incode[], unsigned char hzCode[]) {long offset; // 相对于字库起始位置的偏移字节数 int quCode = incode[0] - 0xa0; // 区码: 该汉字的区号 int weiCode = incode[1] - 0xa0; // 位码: 该汉字的位号 offset = (94 * (quCode - 1) + (weiCode - 1)) * 32; // 32为一个汉字需要32字节(16*16=256个点,256/8=32) FILE *HZK = fopen("HZK16S", "rb"); if (HZK == NULL) { // rb: 打开二进制文件 printf("Can't Open HZK16S\n"); exit(1); } fseek(HZK, offset, SEEK_SET); fread(hzCode, 1, 32, HZK); // 读取表示此汉字的32字节数到hzCode中 fclose(HZK); }void printLCD(int top, int left, unsigned char hzCode[]) {int i, j, k, m, n;for (j = 0; j < 16; j++) {for (i = 0; i < 2; i++) {for (k = 0; k < 8; k++) {if (hzCode[j * 2 + i] & (0x80 >> k)) {for (m = 0; m < ZOOM_FACTOR; m++) {for (n = 0; n < ZOOM_FACTOR; n++) {*(fb + (j * ZOOM_FACTOR + m + top) * SCREEN_WIDTH + left + (i * 8 + k) * ZOOM_FACTOR + n) = FONT_COLOR;}}}}}}}int main() {int i;int fd_fb = 0;unsigned char incode[2]; // 存储区码和位码unsigned char hzCode[32]; // 存储汉字点阵数据char testStr[] = {0xB8, 0xA3, // 福0xD6, 0xDD, // 州0xB4, 0xF3, // 大0xD1, 0xA7 // 学};int strLength = sizeof(testStr);fd_fb = open("/dev/fb0", O_RDWR); // 打开FrameBuffer驱动if (fd_fb == -1) {perror("open fb0");return 1;}fb = (unsigned short *)mmap(0, SCREEN_WIDTH * SCREEN_HEIGHT * PIXEL_BYTES, PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb, 0); // 映射显示存储器,2: 2Bytesif (fb == MAP_FAILED) {perror("mmap");close(fd_fb);return 1;}memset(fb, 0, SCREEN_WIDTH * SCREEN_HEIGHT * PIXEL_BYTES); // 清屏for (i = 0; i < strLength; i += 2) {incode[0] = testStr[i]; // 区码incode[1] = testStr[i + 1]; // 位码getHZCode(incode, hzCode);printLCD(100, i / 2 * (16 * ZOOM_FACTOR + CHAR_SPACING), hzCode); // 显示放大的点阵}munmap(fb, SCREEN_WIDTH * SCREEN_HEIGHT * PIXEL_BYTES);close(fd_fb);return 0;}