來源:百問網(wǎng)
作者:韋東山
本文字數(shù):2108,閱讀時長:4分鐘
要在 LCD 中顯示一個 ASCII 字符,即英文字母這些字符,首先是要找到字符對應的點陣。在 linux 內核源碼中有這個文件:libfontsfont_8x16.c,里面以數(shù)組形式保存各個字符的點陣,比如:
上圖左側有 16 行數(shù)值,每行 1 個字節(jié)。每一個節(jié)對應右側一行中 8 個像素:像素從右邊數(shù)起,bit0 對應第 0 個像素,bit1 對應第 1 個像素,……,bit7 對應第 7 個像素。某位的值為 1 時,表示對應的像素要被點亮;值為 0 時表示對應的像素要熄滅。
所以要顯示某個字符時,根據(jù)它的 ASCII 碼在 fontdata_8x16 數(shù)組中找到它的點陣,然后取出這 16 個字節(jié)去描畫 16 行像素。
比如字符 A 的 ASCII 值是 0x41,那么從 fontdata_8x16[0x41*16]開始取其點陣數(shù)據(jù)。
使用 GIT 下載所有源碼后,本節(jié)源碼位于如下目錄:
01_all_series_quickstart
04_嵌入式 Linux 應用開發(fā)基礎知識source8_show_ascii c
核心函數(shù)是 void lcd_put_ascii(int x, int y, unsigned char c),它在 LCD 的(x,y)位置處顯示字符 c,代碼如下圖所示:
1、獲取點陣
對于字符 c,char c,它的點陣獲取方法如下:
4693 unsigned char *dots = (unsigned char *)&fontdata_8x16[c*16];
2、描點
根據(jù)上圖,我們分析下如何利用點陣在 LCD 上顯示一個英文字母。
因為有十六行,所以首先要有一個循環(huán) 16 次的大循環(huán),然后每一行里有 8 位,那么在每一個大循環(huán)里也需要一個循環(huán) 8 次的小循環(huán)。
小循環(huán)里的判斷單行的描點情況,如果是 1,就填充白色,如果是 0 就填充黑色,如此一來,就可以顯示出黑色底,白色輪廓的英文字母。
4697 for (i = 0; i < 16; i++)
4698 {
4699 byte = dots[i];
4700 for (b = 7; b >= 0; b--)
4701 {
4702 if (byte & (1<<b))
4703 {
4704 /* show */
4705 lcd_put_pixel(x+7-b, y+i, 0xffffff); /* 白 */
4706 }
4707 else
4708 {
4709 /* hide */
4710 lcd_put_pixel(x+7-b, y+i, 0); /* 黑 */
4711 }
4712 }
4713 }
3、main 函數(shù)
main 函數(shù)中首先要打開 LCD 設備,獲取 Framebuffer 參數(shù),實現(xiàn) lcd_put_pixel 函數(shù);然后調用lcd_put_ascii 即可繪制字符。
代碼如下:
4716 int main(int argc, char **argv)
4717 {
4718 fd_fb = open("/dev/fb0", O_RDWR);
4719 if (fd_fb < 0)
4720 {
4721 printf("can't open /dev/fb0n");
4722 return -1;
4723 }
4724 if (ioctl(fd_fb, FBIOGET_VSCREENINFO, &var))
4725 {
4726 printf("can't get varn");
4727 return -1;
4728 }
4729
4730 line_width = var.xres * var.bits_per_pixel / 8;
4731 pixel_width = var.bits_per_pixel / 8;
4732 screen_size = var.xres * var.yres * var.bits_per_pixel / 8;
4733 fbmem = (unsigned char *)mmap(NULL , screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb, 0);
4734 if (fbmem == (unsigned char *)-1)
4735 {
4736 printf("can't mmapn");
4737 return -1;
4738 }
4739
4740 /* 清屏: 全部設為黑色 */
4741 memset(fbmem, 0, screen_size);
4742
4743 lcd_put_ascii(var.xres/2, var.yres/2, 'A'); /*在屏幕中間顯示8*16的字母A*/
4744
4745 munmap(fbmem , screen_size);
4746 close(fd_fb);
4747
4748 return 0;
4749 }
4750
4、編譯 c 文件 show_ascii.c
編譯命令:arm-linux-gnueabihf-gcc -o show_ascii show_ascii.c
注意:不同的板子,編譯工具的前綴可能不一樣。
5、上機實驗
- 把 show_ascii 程序放到板子上,執(zhí)行命令:./show_ascii
- 如果實驗成功,我們將看到屏幕中間會顯示出一個白色的字母‘A’。
6、課后作業(yè)
- 修改 lcd_put_ascii 函數(shù),可以指定字符顏色。
- 實現(xiàn) lcd_put_str 函數(shù),輸出字符串,可以換行。
- 在 show_ascii.c 的基礎上實現(xiàn)漢字的顯示:要找到漢字字庫、了解像素排列順序、得到漢字編碼。