LCD_ShowChar(u16 x,u16 y,u8 num,u8 size,u8 mode)

2023-05-16

阴码+逐列 式+顺向+C51 格式

void LCD_ShowChar(u16 x,u16 y,u8 num,u8 size,u8 mode)
{  							  
    u8 temp,t1,t;
	u16 y0=y;
	u8 csize=(size/8+((size%8)?1:0))*(size/2);		//得到字体一个字符对应点阵集所占的字节数	
 	num=num-' ';//得到偏移后的值(ASCII字库是从空格开始取模,所以-' '就是对应字符的字库)
	for(t=0;t<csize;t++)
	{   
		if(size==12)temp=ascii_1206[num][t]; 	 	//调用1206字体
		else if(size==16)temp=ascii_1608[num][t];	//调用1608字体
		else if(size==24)temp=ascii_2412[num][t];	//调用2412字体
		else return;								//没有的字库
		for(t1=0;t1<8;t1++)
		{			    
			if(temp&0x80)LCD_DrawFRONT_COLOR(x,y,FRONT_COLOR);
			else if(mode==0)LCD_DrawFRONT_COLOR(x,y,BACK_COLOR);
			temp<<=1;
			y++;
			if(y>=tftlcd_data.height)return;		//超区域了
			if((y-y0)==size)
			{
				y=y0;
				x++;
				if(x>=tftlcd_data.width)return;	//超区域了
				break;
			}
		}  	 
	}  	    	   	 	  
} 

从第一列开始向下 每取 8 个点作为一个字节,如果最后不足 8 个点就补满 8 位。取模顺序是从 高到低,即第一个点作为最高位。
在这里插入图片描述
temp其实就是一列,位与0x80取得最高位(相当于D7),如果为1则要用前景色点亮,如果为0为背景色即没有点该点的颜色,temp<<1位,相当于取了D6,y++,y相当于列扫描,一列扫完以后,x++
相当于向右进行行扫描

转载:
void LCD_ShowChar(u16 x,u16 y,u8 num,u8 size,u8 mode)
{
u8 temp,t1,t;
u16 y0=y;
u16 colortemp=POINT_COLOR;
num=num-’ ';//得到偏移后的值
if(!mode) //非叠加方式
{
for(t=0;t
{
if(size==12)temp=asc2_1206[num][t]; //调用1206字体
else temp=asc2_1608[num][t]; //调用1608字体
for(t1=0;t1<8;t1++)
{
if(temp&0x80)POINT_COLOR=colortemp;
else POINT_COLOR=BACK_COLOR;
LCD_DrawPoint(x,y);
temp<<=1;
y++;
if(x>=lcddev.width){POINT_COLOR=colortemp;return;}//超区域了
if((y-y0)==size)
{
y=y0;
x++;
if(x>=lcddev.width){POINT_COLOR=colortemp;return;}//超区域了
break;
}
}
}
}
1206字体和1608字体是两种不同的字号,就是一个横向6点,纵向12点,一个横向8点,纵向16点,从判断语句可以看出,二者对应的码表是不一样的,这个码表在工程里搜索一下,在font.h里,是一个二维数组。我们这里使用1608字体,以字母“M”为例。查一下码表中“M”对应的数组,如下:
{0x10,0x04,0x1F,0xFC,0x1F,0x00,0x00,0xFC,0x1F,0x00,0x1F,0xFC,0x10,0x04,0x00,0x00},
’ ‘是码表的开始,由字母减去’ '得到偏移量,也就是二维数组的第几行。第一个循环开始,就给临时变量temp赋值为数组的第一个值,由于是1608字体,因此也有一个数组中有16个数,第一个循环就是为了让temp遍历这16个数。
之后第二个循环开始,由于数组中的每一个数均是8位,由于每次循环都会对temp左移一位,因此第二个循环的次数是8次。经if(temp&0x80)判断,如果数字的最高位为1,则进行描点的颜色为字体颜色,如果不是1,则描点颜色为底色。(PS:描点函数LCD_DrawPoint还是很简单滴,总的来说就是向写GRAM寄存器R20h,R21h写入我们希望写的点颜色,基本操作O(∩_∩)O)
每次移位,y都会自加,第二个循环是8次,而size为16,也就是说数组中每读过两个数,y自加16次之后都会清零,然后x加1,就像列扫描一样,一列16个点结束后会进行到下一列。
超区域那部分就是说超过size了,描个点就返回啦。下面以“M”为例描述下描点的过程。
码表前8个
0x10 (0,3) 00010000 所以bit3点亮
0x04 (0,13) 00000100 上面0x10占8位,所以bit13点亮
0x1F (1,3),(1,4),(1,5),(1,6),(1,7)
0xFC (1,8),(1,9),(1,10),(1,11),(1,12),(1,13)
0x1F (2,3),(2,4),(2,5),(2,6),(2,7)
0x00 无
0x00 无
0xFC (3,8),(3,9),(3,10),(3,11),(3,12),(3,13)
码表后8个
0x1F (4,3),(4,4),(4,5),(4,6),(4,7)
0x00 无
0x1F (5,3),(5,4),(5,5),(5,6),(5,7)
0xFC (5,8),(5,9),(5,10),(5,11),(5,12),(5,13)
0x10 (6,3)
0x04 (6,13)
0x00 无
0x00 无
这个不直观啊,用matlab的scatter(x,y)描个点,正好就是TFT屏幕显示的“M”图形
在这里插入图片描述

//显示数字,高位为0,则不显示
//x,y :起点坐标	 
//len :数字的位数
//size:字体大小
//color:颜色 
//num:数值(0~4294967295);	 
void LCD_ShowNum(u16 x,u16 y,u32 num,u8 len,u8 size)
{         	
	u8 t,temp;
	u8 enshow=0;						   
	for(t=0;t<len;t++)
	{
		temp=(num/LCD_Pow(10,len-t-1))%10;
		if(enshow==0&&t<(len-1))
		{
			if(temp==0)
			{
				LCD_ShowChar(x+(size/2)*t,y,' ',size,0);
				continue;
			}else enshow=1; 
		 	 
		}
	 	LCD_ShowChar(x+(size/2)*t,y,temp+'0',size,0); 
	}
} 

转载:http://www.51hei.com/bbs/dpj-141896-1.html

u32 oled_pow(u8 m,u8 n)
{
u32 result=1;
while(n–)result*=m;
return result;
}

这个函数我觉得你并不理解,不然也就不会不明白temp指的是什么了。现在我给你分析一下,就按照我最开始的思路来读程序,跟着我一步一步走好了:

根据函数名,我们可以大概了解这个函数的功能是显示一个数字,传入的参数是X坐标(字符在一行的哪一个位置)、y坐标(字符显示在哪一个行)、一个待显示的数据、数据的长度和显示字符的跨度

enshow是一个使能标志,那么这个使能位是在什么时候起作用,什么时候关闭呢?

if(enshow==0&&t<(len-1))

这一句的意思你明白,是当这个enshow为0并且再数据长度范围内的时候,进行temp==0的判断,而不满足这个条件,enshow就会置1,显然,是在判断数据传输是否完成,并且在达到给定的数据长度后终止传输。

纵观函数的结构可以看出,在许可长度范围内,函数循环计算一个temp量,从最后一句
OLED_ShowChar(x+(size2/2)*t,y,temp+‘0’);
可以看到,这个temp实际上是待显示位数字,比如1,2,3…而不是数字的ASCII码,所以这里需要以‘0’做基准把数字转换为其ASCII码,可以猜测,OLED_ShowChar()函数是传入一个ASCII码,在ASCII码字模表中取模显示对应的字符。

知道了temp是什么意思,我们反过来看temp是如何求得的:

temp=(num/oled_pow(10,len-t-1))%10

这句中,num是待显示的数据,我们知道了该显示函数是按位取出num,那么这一句的作用必然是按位取数,结尾的%10(取余运算)表明所取的数是前面所求整数数据的最后一位。

现在到了最关键的部分了
oled_pow(10,len-t-1)返回的是一个什么数据?

将实参代入形参即m为累乘数据,n为数据长度-已处理位数-1
(此处的减一是为了适应C语言计数到“0”为止)

u32 oled_pow(u8 m,u8 n)
{
u32 result=1;
while(n–)result*=m;
return result;
}
翻译一下:
结果值result初始值为1;
当 在长度范围内 时,结果值=结果值*累乘数据
返回 结果值

也就是说,返回的是(10)^(显示的长度)

这样,num/oled_pow(10,len-t-1)指的是对指定长度取模(取num定长)

例如:num=1325416;显示长度为5,那么num/oled_pow(10,len-t-1)运算之后就是13。在这个结果上再对10取余就是最后一位。
由于t的变化,可以遍历每一位。

但是如果数据在变化,那当数据位数过少的时候,前面位会显示什么呢?是0。例如规定显示5位,但是实际上数据只有2位,那显示就会变成000XX,为了美观,也要把这个0干掉。

事实上,
if(temp==0)
{
OLED_ShowChar(x+(size2/2)*t,y,’ ');
continue;
}
就是干这个工作的,当取出的位为0的时候,就用空格代替改数值达到消隐无效0的作用。从上面的分析我们可以知道,这个传入的ASCII码应该是由一个char类型的值在接收,所以这里的空格会以ASCII码的形式存入形参。

我想我应该讲完了,你的三个问题答案整理如下:

1.temp=(num/oled_pow(10,len-t-1))%10;//这里算出来到底是什么数
答:该出算出的是本次要显示的位对应的数值

2.OLED_ShowChar(x+(size2/2)*t,y,’’);//这里的’'怎么和阿斯克码表对上的
答:猜测接收的形参是char类型,所以空格直接以字符型存入了(即存入的是空格的ASCII码)

3.OLED_ShowChar(x+(size2/2)*t,y,temp+‘0’); //这里又为什么+0
答:因为需要以0为基准将数字类型转为对应的ASCII码。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

LCD_ShowChar(u16 x,u16 y,u8 num,u8 size,u8 mode) 的相关文章

  • View 的 getWidth() 和 getHeight() 返回 0

    我看过类似的问题并尝试了他们的解决方案 但它对我不起作用 我正在尝试阅读width of an imageView 但它正在返回0 这是代码 public class MainActivity extends Activity privat
  • 在 C++ 中打包嵌套结构

    使用 Visual Studio 2017 以下给出 struct AAA 15 bytes double d short s char a1 char a2 char a3 char s4 char s5 struct BBB AAA d
  • 声纳数据库有多大?

    这可能看起来像一个愚蠢的问题 事实上 这更像是一项民意调查 您的声纳数据库有多大 我需要它来估计托管我的 Sonar 实例的虚拟机的要求 Also 你的团队有多大 每次新提交在 Sonar 数据库中使用了多少额外字节 我将不胜感激任何帮助
  • 使用不同搜索空间大小的不同 lucene 搜索结果

    我有一个使用 lucene 进行搜索的应用程序 搜索空间有数千个 在这数千个搜索中 我只得到了一些结果 大约 20 个 这是正常的并且是预期的 然而 当我将搜索空间减少到只有那 20 个条目时 即我只对这 20 个条目建立索引并忽略其他所有
  • Python 3 - pickle 可以处理大于 4GB 的字节对象吗?

    基于此comment https stackoverflow com a 29704623 1202808以及参考文档 来自 Python 3 4 的 Pickle 4 0 应该能够 pickle 大于 4 GB 的字节对象 但是 在 Ma
  • 在大屏幕上修复 FireFox 与 Chrome 中的网站大小

    看起来 Gecko Trident 和 Webkit 在高分辨率屏幕上显示网页的方式不同 Chrome 和新 Opera 等 Webkit 浏览器会缩小页面以匹配屏幕的像素分辨率 然而 这可能会使小文本很难阅读 另一方面 Firefox 和
  • 为什么C中函数的大小总是1字节?

    当我们使用以下命令检查函数的大小时sizeof 我们总是得到1 byte 这1个字节代表什么 这是一个约束违规 你的编译器should诊断它 如果它编译它 尽管如此 你的程序有未定义的行为 感谢 Steve Jessop对失败模式的澄清 并
  • JTextField 固定高度

    我如何获得JTextField当框架最大化时有固定的高度 我希望它看起来有点类似于 Ubuntu 上的 Skype 应用程序 private JTextField username private JPasswordField passwo
  • 如何获得 (lcd) 显示屏对角线的实际尺寸,即它是 17 英寸还是 19 英寸或其他?

    这对我很有用 因为我必须在屏幕上以正确的尺寸映射对象 如果我使用分辨率为 1280x1024 的 19 lcd 和正常的 96dpi 设置 那么为了映射正确的 1 英寸正方形 我必须编写这样的 xaml
  • R ggplot2 - 底部的图例被剪切,如何动态找到图例的最佳列数?

    我想在底部制作一个带有图例的情节 但图例总是被剪切 因为看起来ggplot2无法自动确定底部图例中的最佳列数 我尝试自己做 但没有成功 假设我有以下内容mydf数据框 mydf lt data frame group paste0 gr 1
  • 计算R中目录的大小

    我想计算 R 中目录的大小 我尝试使用list info函数 不幸的是 它遵循符号链接 所以我的结果有偏差 return wrong size with duplicate counts for symlinks sum file info
  • 如何找出网页浏览者每英寸的像素数?

    谁能想到一种方法来发现用户的每英寸像素数 我想确保图像显示在网络浏览器中exactly我需要它的大小 因此使用分辨率 我可以从用户代理获得 和每英寸像素的组合我可以做到这一点 但是 我不确定是否有任何方法可以发现用户的每英寸像素数 最好使用
  • 确定输入流的大小

    我目前的情况是 我必须读取一个文件并将内容放入InputStream 之后我需要将内容InputStream到一个字节数组中 它需要 据我所知 的大小InputStream 有任何想法吗 根据要求 我将显示我从上传的文件创建的输入流 Inp
  • 类文件的最佳大小是多少?

    我知道类文件没有单一的 理想 大小 但仍然 是否有任何关于类文件的最佳大小的数据 如研究 而不是意见 我想说 最佳大小足以让该类完成其工作
  • 使用 WCF 流上传文件,从流中进行微小读取

    我已经使用WCF的流实现了文件上传 一切都按预期进行 但是我遇到了一个问题 我分配 4kb 缓冲区来从传入流中读取数据 但 WCF 仅读取 255 字节 这是我的上传功能 public UploadResponse UploadFile F
  • 如何缩小自定义 Skobbler 离线地图应用程序的大小

    我正在将 Skobbler 地图集成到我的 iOS 应用程序中 目前 该应用程序的大小为 160Mb 这太大了 但我注意到已经集成了一堆地图 我想删除所有地图并让用户下载他需要的地图 现在 当我包含 SKMaps framework 时 其
  • C 中 long int 和 int 的大小显示 4 个字节 [重复]

    这个问题在这里已经有答案了 我做了以下实验来了解系统中 long int 和 int 的大小 系统规格 64位Windows 7 gcc MinGW 编译器 日食CDT 我对得到的输出感到困惑 我没有理由支持我的程序的结果 如果有人对此有任
  • 如何让用户轻松选择在 Java Swing 应用程序中分配多少内存?

    我们有一个处理相对大量数据的 Swing 应用程序 例如 我们目前处理包含数百万行数据的 CSV 文件 出于性能和简单性的原因 我们将所有数据保留在内存中 然而 不同的用户需要处理的数据量以及 RAM 量也不同 创建安装程序时 我们当然需要
  • facebook画布高度在ie8和firefox中没有设置滚动

    嘿 我想设置一个长页面应用程序 没有FB会限制我的应用程序的高度并附加滚动 我做了 iframes canvas 并在设置中自动调整大小并应用该代码 它限制了我在 ie 中显示滚动并在 firefox 中剪切内容 代码在这里 http pa
  • 各种 Android 设备的应用程序背景大小

    我正在为所有 Android 设备的应用程序设计背景 我在想图像的大小 以像素为单位 是多少 从开发者网站我发现了以下等式 px dp dpi 160 那么 px 取决于两个变量 首先 dp 我们有 xlarge screens are a

随机推荐

  • 来聊聊对象文件网关和分布式文件存储的区别

    前言 大家都知道 xff0c 存储系统一般分为块存储 对象存储和文件存储三种 其中文件存储的使用最广泛 xff0c 个人电脑 NAS 大到传统的HPC 大数据平台等等 这些都是以使用文件接口为主 最近几年 xff0c 由于成本低 存储空间大
  • Ubuntu中文件属性以及所属用户问题

    1 xff0c 查看文件属性 xff0c 命令如下 xff1a 查看当前目录下某个文件属性 ls l lt file name gt 查看当前目录下文件属性 ls l 查看所有当前文件下属性 ls al 在开始的 rwxr xr x 为该文
  • Android8.0 屏幕旋转180度

    一般手机只能旋转3个方向 xff0c 这里将介绍如何让手机可以旋转180度 xff0c 也就是上下颠倒 1 静态方法 frameworks base core res res values config xml config allowAl
  • 深度理解go中的Map

    这里写自定义目录标题 前言map的内存模型增量扩容查找过程分析插入过程分析 前言 本篇将从底层讲解map的赋值 删除 查询 扩容的具体执行过程 结合源码 xff0c 让你彻底明白map的原理 map的内存模型 在源码中 xff0c 表示ma
  • 在职场我们该具备哪些能力

    专才or 通才 不知道大家有没有这样的感觉 xff0c 现在的工作专业化程度越来越高 xff0c 细分粒度也越来越小 IT领域分到你是计算里面的数据库或者了流式计算引擎 xff0c 或者是协议存储还是KV存储引擎 专业化的程度带来了一个好处
  • 【zabbix Java开发教程】docker部署zabbix及api获取实战教程

    文章目录 Docker安装移除旧版本的docker环境安装必要系统工具添加源信息更新yum缓存安装Docker ce 启动Docker测试运行hello world 修改源 Docker部署zabbix创建zabbix的MySQL运行zab
  • go版本分布式锁redsync使用教程

    redsync使用教程 前言redsync结构Pool结构Mutex结构acquire加锁操作release解锁操作 redsync包的使用 前言 在编程语言中锁可以理解为一个变量 xff0c 该变量在同一时刻只能有一个线程拥有 xff0c
  • Fragment实例精讲——底部导航栏的实现(3)

    转自 xff1a http www runoob com w3cnote android tutorial fragment demo3 html 本节引言 前面我们已经跟大家讲解了实现底部导航栏的两种方案 xff0c 但是这两种方案只适合
  • Android NavigationBar 背景设置成完全透明不起作用

    lt item name 61 34 android navigationBarColor 34 gt 64 android color transparent lt item gt 使用 android navigationBarColo
  • 计算机视觉CV中RANSAC算法的学习笔记~

    1 致谢 感谢网友叶晚zd的博客 xff0c 原文链接如下 xff1a https blog csdn net u013925378 article details 82907502 2 RANSAC算法介绍 随机抽样一致算法 xff08
  • 【Java】JsonArray用法

    1 解析字符串为JsonArray JSONArray jsonArray 61 JSONArray parseArray str 2 存值 jsonArray add object 3 取值 for int i 61 0 i lt jso
  • 怎么用JMeter写性能测试脚本

    JMeter 可能是应用最广泛的性能测试工具 怎么用 JMeter 编写性能测试脚本 xff1f 一 脚本制作原则 我们一般写代码 xff0c 都会有代码规范 xff0c 比如写java有java规范 xff0c 写python有pytho
  • Android MVP Contract分析

    相关文章 xff1a Android MVP Contract 谷歌官方MVP Contract分析 View 只处理UI及页面效果的细节 xff0c 向Presenter暴露更新UI的方法 xff1b 并且持有Presenter的引用 x
  • 《Flask Web开发实战》第一章初识Flask——李辉,读书笔记

    目录 第一章 初识Flask开发环境的搭建使用Pipenv管理Python包 hello Flask启动开发服务器修改默认的重载器修改配置参数实现类似flask run的命令的方式 结尾 第一章 初识Flask 本章主要介绍了一些关于Fla
  • 基于cat12和SPM12进行VBM&SBM数据分析笔记1——数据预处理

    前言 今年是小编步入研究生生活的第一年 xff0c 研究方向待定 xff0c 但主要以磁共振成像为主 xff0c 以后会不断地总结这方面的知识 xff0c 涉及MRI xff0c 数据分析基础方法理论 xff0c 软件操作教程 xff0c
  • SpringBoot打war包运行在独立Tomcat的方式

    第一种方式 xff1a 手动配置 1 修改pom xml文件 1 添加 lt packaging gt war lt packaging gt span class token operator lt span span class tok
  • SpringBoot整合Mybatis

    1 在pom xml中添加依赖 xff0c 有两种方式 第一种 xff1a 直接在pom xml中添加mybatis spring boot starter依赖 span class token generics function span
  • Druid的sql监控页面没有数据

    1 本人使用各框架版本 springboot 2 2 2 druid 1 1 18 druid配置类 xff1a span class token keyword package span com span class token punc
  • docker下配置mysql主从复制之slave无法复制master的问题解决

    1 问题 xff1a 从节点连接主节点错误 xff0c 初步定位为网络原因 Last IO Error error connecting to master backup 64 192 168 1 150 3307 retry time 6
  • LCD_ShowChar(u16 x,u16 y,u8 num,u8 size,u8 mode)

    阴码 43 逐列 式 43 顺向 43 C51 格式 span class token keyword void span span class token function LCD ShowChar span span class tok