Linux 下 使用点阵在LCD上显示汉字,字符

news2024/11/20 18:34:57

文章目录

  • 前言
  • 一、显示字符
      • 1.获取点阵:
      • 2.描点(显示字符函数):
      • 3. 要打开LCD设备:
      • 4. 通过ioctl 获取Framebuffer参数:
      • 5. 通过mmap映射出Framebuffer的地址:
      • 6.清屏并显示字符:
  • 二、显示汉字
      • 1.区位码:
      • 2. 打开汉字库文件:
      • 3.显示汉字函数:
  • 总结


前言

这篇文章主要讲一下如何在 LCD 上使用点阵显示汉字,字符 ,修改颜色 及效果展示。其中包含了几个核心函数,我们需要了解。

一、显示字符

1.获取点阵:

各个字符对应的点阵都保存在一个数组里,大家可以打开 font_8x16.c 中得到点阵。(不同的点阵对应不同的代码,这里我使用的是 8x16 的点阵 )

	unsigned char *dots = (unsigned char *)&fontdata_8x16[c*16];

2.描点(显示字符函数):

找到点阵,将里面需要的点上色就可以在 LCD 上显示出不同的字符
我们使用的是 8x16 的点阵 ,点阵有十六行,每一行里有8位。所以首先要有一个循环16次的大循环代表每一行,在每一个大循环里也需要一个循环8次的小循环,代表每一位。

x ,y : 代表对应点的横纵坐标
c : 表示你要显示的字符
lcd_put_pixel 此函数为描点函数,在 Linux 应用基础 Framebuffer应用编程 中我已详细的写出该函数。(第一二个参数代表x,y 坐标 。第三个参数代表颜色,可任意修改。)

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, 0x00ff00); /* 绿色 */
			}
			else
			{
				/* hide */
				lcd_put_pixel(x+7-b, y+i, 0); /* 黑 */
			}
		}
	}
}

3. 要打开LCD设备:

对于不同的板子,你的 framebuffer 节点可能有所不同,需注意。

	int fd_fb;
	
	fd_fb = open("/dev/fb0", O_RDWR);

4. 通过ioctl 获取Framebuffer参数:

将得到的数据保存在 var 结构体中。这个结构体如果不了解的可以参考 Linux 应用基础 Framebuffer应用编程,我都已详细的说明。

	struct fb_var_screeninfo var;
	
    if (ioctl(fd_fb, FBIOGET_VSCREENINFO, &var))

5. 通过mmap映射出Framebuffer的地址:

要映射一块内存,就需要知道它的大小和地址。
screen_size : 为该内存的地址。(整个framebuffer 的大小)

	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);

6.清屏并显示字符:

使用 memset 将屏幕变成黑色,再显示字符,便于观察。

	memset(fbmem, 0, screen_size);

	lcd_put_ascii(var.xres/2, var.yres/2, 'A'); /*在屏幕中间显示8*16的字母A*/

注意: 上面我们映射了一块内存,我们使用完后需要释放 munmap

munmap(fbmem , screen_size);

二、显示汉字

显示汉字,我们可以从网上下载 HZK16 这个文件, 它是常用汉字的 16*16 点阵字库。HZK16里每个汉字使用32字节来描述

1.区位码:

HZK16中是以 GB2312 编码值来查找点阵的,这里就要涉及汉字的区位码。区位码把GB2312字符集分为94个区,每区含有94个位。一个汉字所在的区号和位号简单地组合在一起就构成了该汉字的"区位码"。

例如:
以“中”字为例,它的编码值是“0xd6 0xd0”,其中的0xd6表示“区码”,表示在哪一个区。其中的0xd0表示“位码”,表示它是这个区里的哪一个字符。由于区位码从0xA1开始,所以 “中” 字在 第“0xd6 - 0xa1”区,第“0xd0 - 0xa1”个。

	unsigned int area  = str[0] - 0xA1; //区码
	unsigned int where = str[1] - 0xA1; //位码
	unsigned char *dots = hzkmem + (area * 94 + where)*32;//每一个区有94个汉字每个汉字占了32个字节

2. 打开汉字库文件:

struct stat 这个结构体是用来描述一个linux系统文件系统中的文件属性的结构。通过 fstat 函数获得文件状态,保存到 hzk_stat 结构体中。

	int fd_hzk16;
	struct stat hzk_stat;

	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;
	}

下面是 struct stat 结构体:

struct stat {
		mode_t     st_mode;       //文件对应的模式,文件,目录等
	    ino_t      st_ino;       //inode节点号
		dev_t      st_dev;        //设备号码
		dev_t      st_rdev;       //特殊设备号码
		nlink_t    st_nlink;      //文件的连接数
		uid_t      st_uid;        //文件所有者
		gid_t      st_gid;        //文件所有者对应的组
		off_t      st_size;       //普通文件,对应的文件字节数
		time_t     st_atime;      //文件最后被访问的时间
		time_t     st_mtime;      //文件内容最后被修改的时间
		time_t     st_ctime;      //文件状态改变时间
		blksize_t st_blksize;    //文件内容对应的块大小
		blkcnt_t   st_blocks;     //伟建内容对应的块数量
	 };

3.显示汉字函数:

void lcd_put_chinese(int x, int y, 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;//每一个区有94个汉字每个汉字占了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, 0x00ff00); /* 绿色 */
				}
				else
				{
					/* hide */
					lcd_put_pixel(x+j*8+7-b, y+i, 0); /* 黑 */
				}	
			}
		}
	}
}

可在主函数里面调用 :

	unsigned char str1[] = "你";
	unsigned char str2[] = "好";

	lcd_put_chinese(var.xres/2 + 8,  var.yres/2, str1);
	lcd_put_chinese(var.xres/2 + 8+16,  var.yres/2, str2);


总结

效果:
在这里插入图片描述

大家可以自行实践一下,有不懂的欢迎留言讨论。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/112032.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

WSL2的安装、应用

WSL2的安装、应用WSL安装、升级常用命令WSL导入导出其他 - 图形界面、虚拟化WSL安装、升级 win10系统上开启WSL参考如下&#xff0c;我先是安装了WSL1&#xff0c;之后又升级到WSL2的。关键是一些Win10上电配置&#xff0c;之后在windows应用商店下载ubuntu即可。 win10上lin…

又一家中国企业加入RISC-V,中国力推之下必将打破ARM的垄断

近日消息指腾讯已正式加入RISC-V&#xff0c;并且是以高级别的高级会员加入&#xff0c;显示出腾讯开发RISC-V架构芯片的决心&#xff0c;这显示出中国芯片行业正齐心协力发展RISC-V架构&#xff0c;将打破ARM的垄断。腾讯在芯片行业已取得一定的成绩&#xff0c;分别推出了AI推…

文字对称中的数学与魔术(二)——英文字母到单词的对称性

早点关注我&#xff0c;精彩不错过&#xff01;在上一篇文章中&#xff0c;我们引入了语言文字对称性这个领域&#xff0c;重点介绍了阿拉伯数字的对称性&#xff0c;相关内容请戳&#xff1a;文字对称中的数学与魔术&#xff08;一&#xff09;——阿拉伯数字的对称性今天我们…

Linux系统基础——内存管理

Linux系统内存管理 特此说明: 刘超的趣谈linux操作系统是比较重要的参考资料&#xff0c;本文大部分内容和所有图片来源于这个专栏。 1 物理内存 物理内存根据 NUMA 架构分节点。每个节点里面再分区域。每个区域里面再分页。 物理内存页通过伙伴系统进行分配。进程通过虚拟地址…

xv6 源码调试环境搭建

一、资源 官网&#xff1a;https://pdos.csail.mit.edu/6.828/2022/ 二、搭建 xv6 调试环境 1、下载 xv6 源码 git clone git://github.com/mit-pdos/xv6-riscv.git2、安装工具链 特别说明&#xff1a;ubuntu 仓库中已经提供&#xff0c;可直接安装。 1、从 ubuntu 仓库中…

前端小知识:文本分句、词、字(Intl.Segmenter)

5. 文本分字、词、句 参考文章&#xff1a; https://mp.weixin.qq.com/s/MLmi-Yoi9sez8-5DPtcBVw   官方文档&#xff08;构造参数&#xff09;&#xff1a; https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Intl/Segmenter/Segmenter   …

Redis系列:深刻理解高性能Redis的本质

1 背景 分布式系统绕不开的核心之一就是数据缓存&#xff0c;有了缓存的支撑&#xff0c;系统的整体吞吐量会有很大的提升。通过使用缓存&#xff0c;我们把频繁查询的数据由磁盘调度到缓存中&#xff0c;保证数据的高效率读写。 当然&#xff0c;除了在内存内运行还远远不够&…

Linux系统基础——BIOS和Bootloader

BIOS和Bootloader 特此说明: 刘超的趣谈linux操作系统是比较重要的参考资料&#xff0c;本文大部分内容和所有图片来源于这个专栏。 1 了解背景 1.1 目的 操作系统不是在板子上电就直接运行的&#xff0c;上电到系统启动的中间过程要搞明白&#xff0c;比如了解linux系统启动…

12月24日:数据结构

Btree结构 ​​​​​​ BTree和BTree详解_菜鸟笔记的博客-CSDN博客_btree 简单的说一下什么是聚簇索引 , 和非聚簇索引有啥区别 聚簇索引&#xff1a;索引和数据存储放在了同一个文件中&#xff0c;找到了索引也就能找到数据 非聚簇索引&#xff1a;将数据存储和索引分开放置…

AAAI2023 | 户外超大规模场景数据如何生成?READ告诉你答案(浙大阿里巴巴)

点击下方卡片&#xff0c;关注“自动驾驶之心”公众号ADAS巨卷干货&#xff0c;即可获取点击进入→自动驾驶之心【多传感器融合】技术交流群后台回复【READ】获取论文和代码&#xff01;&#xff01;&#xff01;摘要合成自由视角真实感图像是多媒体领域的一项重要任务。随着高…

最长上升子序列(详解二分优化)

最长上升子序列一、题目描述二、思路分析1、问题分析2、思路分析&#xff08;1&#xff09;状态转移方程状态表示状态转移&#xff08;2&#xff09;循环设计三、代码实现一、题目描述 二、思路分析 1、问题分析 其实这道题第一个思路就是深度优先搜索&#xff0c;类似于全排…

一维树状数组

引入 树状数组和线段树具有相似的功能&#xff0c;但他俩毕竟还有一些区别&#xff1a;树状数组能有的操作&#xff0c;线段树一定有&#xff1b;线段树有的操作&#xff0c;树状数组不一定有。但是树状数组的代码要比线段树短&#xff0c;思维更清晰&#xff0c;速度也更快&a…

设计模式-命令模式

将一个请求封装为一个对象&#xff0c;从而使你可用不同的请求对客户进行参数化&#xff0c;对请求排队或记录请求日志&#xff0c;以及支持可撤销的操作 命令模式( Command Pattern) 是对命令的封装&#xff0c;每一个命令都是一个操作&#xff1a;请求的一方 发出请求要求执行…

DIDL1_基础优化算法

基础优化算法梯度下降选择学习率小批量随机梯度下降选择批量大小Batch_size总结梯度下降 挑选一个初始值w0w_0w0​重复迭代参数 t1&#xff0c;2&#xff0c;3 wtw_twt​等于上一个时刻wt−1w_t-1wt​−1减去一个&#xff08;学习率标量和损失函数关于wt−1w_t-1wt​−1处的梯…

【20天快速掌握Python】day12-文件操作

1.文件的打开与关闭 想一想&#xff1a; 如果想用word编写一份简历&#xff0c;应该有哪些流程呢&#xff1f; 打开word软件&#xff0c;新建一个word文件 写入个人简历信息 保存文件 关闭word软件 同样&#xff0c;在操作文件的整体过程与使用word编写一份简历的过程是很相…

B树(B-树) [数据结构与算法][Java]

B树 B树又称为多路平衡树查找树, 是一种组织和维护外存文件系统非常有效的数据结构 因为我们的二分搜索树构建的时候很可能会出现不平衡的情况, 所以我们提出了自平衡二分搜索树(AVL树)对我们的普通的二分搜索树进行了一个优化, 而自平衡二分搜索树中当元素很多的时候树的高度…

Axure绘制密码输入框

当我们在绘制登录页面时&#xff0c;如果登录方式包含账号密码登录&#xff0c;那么我们就会使用到密 码输入框&#xff0c;而常见的密码输入框&#xff0c;通常会使用到小眼睛控制密码的明文和密文显示。 大家知道axure中的输入框&#xff0c;当你设置成密码类型时&#xff…

结构体内存对齐问题

结构体重点&#x1f603; 1.结构体内存对齐问题&#xff0c;是在计算结构体的大小时&#xff0c;对结构体成员在内存中的位置进行研究的问题。 废话不多说&#xff0c;先看两个例子&#xff1a; 例题1&#xff1a; struct S1 {char c1;int age;char c2; };int main() {struc…

Spring Cloud Alibaba 2022.0.0.0 版本发布啦!

01新版本预览Aliware本次发布的 Spring Cloud Alibaba 2022.0.0.0-RC1 版本&#xff0c;是基于社区 2022.x 主干分支进行构建发布第一个 Release Candidate&#xff08;RC&#xff09;版本&#xff0c;考虑到本次版本升级属于重大版本变更&#xff0c;因此暂时先以 RC 版本形式…

如何不改一行代码,让Hippy启动速度提升50%?

导读&#xff5c;Hippy使用JS引擎进行异步渲染&#xff0c;在用户从点击到打开首屏可交互过程中会有一定的耗时&#xff0c;影响用户体验。如何优化这段耗时&#xff1f;腾讯客户端开发工程师李鹏&#xff0c;将介绍QQ浏览器通过切换JS引擎来优化耗时的探索过程和效果收益。在分…