单片机模块——OLED模块(二)
学习目标:
一、通过画点函数和对显存实现画面渐隐渐显
因为我们用的OLED屏幕是单色的,只有亮和灭两种状态,要实现改变像素点密度,我打算用田字格的方法
就是把屏幕上的像素点,分割成2×2的一组一组区域,于是每个区域都是由四个像素点组成,每个像素点的起始坐标,分别为(0,0)、(1,0)、(0,1)、(1,1)
在程序代码中,创建一个名为FourPoints的函数,并且设置两个参数xstart和ystart作为田字格里被点亮像素点的起始坐标,然后建立两个循环,让y坐标从ystart开始,到63结束,递增步长为2;让x坐标从xstart开始,到127结束,递增步长也是2,在循环最里层,将显存数组中对应的点赋值为1,从而将屏幕上的每个田字格里的坐标为xstart和ystart对应的像素点点亮
调用函数后,可以看到田字格的四个点依次被点亮
根据四个点的点亮位置不同,田字格又可以分成五种状态:
如果用这样的田字格填满整个屏幕,就可以得到像素点密度为0%、25%、50%、75%、100%的五种视觉效果
这就像打印机,还有报刊和海报上的灰度图片,也是通过墨点的不同密度,产生不同的灰阶效果,这里我们也可以把这五种状态,看作是五个灰阶
执行下面代码,屏幕上的像素点以0%、25%、50%、75%、100%的密度依次循环变化
二、通过“蒙版”实现让OLED显示渐隐渐显的画面以及图片取模的操作过程
蒙版就是用一块镂空的模板,覆盖到另一块图案上,然后我们就只能看到模版透露出来的那部分图案,这个镂空的模版就是蒙版
假设现在有两张图片
将图片A覆盖到图片B上,就可以发现,两张图片上有一部分像素点是重合的,然后以图片A上的像素点的坐标为对象逐一扫描,同时跟图片B上的相同位置的像素点作比较,如果图片B上对应的点的值是0,咋跳过这个点继续扫描,如果对应点的值是1,那么就在显存数组GRAM中,用画点函数OLED_DrawPoint(x,y);在相同坐标的位置上画一个点
当图片B上的所有点都扫描完之后,图片A和图片B上所有的有交集的像素点的坐标,就都以数值1的形式保存在了显存数组中
从而就得到了一个像素点密度为25%的图案B,在这里图案A就起到了蒙版的作用
同理用另外三个点阵图案作为蒙版覆盖到图片B上,就又可以得到另外三种像素点密度为25%的图案B
如果将这四组图案按照不同密度叠加,就分别得到了不同灰度的图片
在实验之前,有一项非常重要的工作要做,就是为想要显示的图片创建一个图片数组,也就是给图片取模,只需要以下四个步骤
首先需要准备一张图片,用自己习惯的图片处理软件,将图片尺寸修改成宽128个像素,高64个像素大小的黑白图片
第二步是用系统自带的画图程序,打开刚才制作的那张图片,将图片保存成单色位图的格式,这样才能让取模软件正确识别图片内容,这一步转换会让图片损失掉一些细节,所以才会建议在上一个步骤预先把图片处理好
接下来第三步,请出专门为单色显示屏取模的工具PCtoLCD2002,模式一栏选择图形模式,点击“选项”或者齿轮按钮进入字模选项界面,因为选择的图片是白色背景黑色图案,而我们需要的是黑色图案部分是点亮的,白色背景部分是不亮的,所以点阵格式一栏选择阴码,如果选择阳码,生成的数据就是反色显示的,由于我的OLED屏幕的寻址模式设置的是水平模式,所以取模方式一栏选择列行式,右下角小窗口里可以看到取模顺序的动画演示,中间一栏保持默认,因为我们需要的数据是0x开头的十六进制数,所以最右边的自定义格式的下拉菜单选择C51格式,在下方自定义设置里,要将前缀和后缀里的花括号删掉,点击确定
然后打开要转换的图片,可以看到图片显示在了预览窗口中,如果对图像上的像素点有不满意的地方,可以在这个窗口中进行修改,鼠标左键可以点亮一个点,右键可以熄灭一个点,最后,在预览图右下方位置找到生成字模按钮,点击之后,下方的窗口就会出现密密麻麻的一组数据,这些就是生成的图片数据
第四步,把这些数据复制一下,回到程序界面,在主程序之前,创建一个图片数组FOX[8][128],使用二维数组的形式,是为了之后的编程方便,将刚刚生成的蹄片数据粘贴到这个数组里
,一张图片的取模过程就完成了
蒙版函数
三、用画点函数画线的原理
斜线
四、坐标系和波形图
屏幕上的像素点是从左上角为起始点开始排列的,这个点的坐标是(0,0),在向右和向下的方向上,像素点的坐标值都是依次增大的,如果以这个点为原点创建出一个坐标系,横向坐标是x,竖向坐标是y,那么位置越向右向下的点,xy的值越大,这跟我们惯用的坐标系不太一样,所以就要对y坐标进行一下反向
假设需要显示的范围的最下限,在屏幕最下面的一行,也就是y=63的那一行,只需要用63减去y的值,就得到了翻转后的y坐标值,而横向坐标,依旧跟屏幕坐标系的x坐标值相同。这样,画波形的第一步,一个我们习惯的新坐标系就建立好了
在这个新的坐标系里,我们就可以以左下角的点为坐标原点,任意的画出y坐标是0到63之间的任意一个点
但在实际使用中,我们获取的数值可能非常小,比如开关的逻辑状态,只有1或者0,或者数值可能又非常大,比如ADC数值、温湿度数值等等,超过了屏幕的最大y值63,于是就需要第二步操作,设定一个显示范围,然后将要显示的数值,按照一个比例进行放大或缩小,让它变成可以在屏幕上显示出来的y值,只需要在每次获取到数值时,将这个值按比例换算成y坐标,同时让x坐标不断增加,就可以在屏幕上画出对应的点了
波形函数
五、动态的波形图
刚才我们用一个数组来存放波形数据,这里我们可以把这个数组,想象成128个小格子,每个格子里都存放着要显示的一个数据,假设我们要让波形图从左向右移动,就从最右边的格子开始,每次都将序号为第126格里的数据放进第127格里,将序号为第125格里的数据放进第126格里,将序号为第124格里的数据放进第125格里,以此类推,直到将第0格里的数据放进第1格里,空出来的第0格就可以存放新获取到的数据了,一轮移动完成之后,将数组里的数据,显示到屏幕上,然后就可以进行下一轮的移动了
经过一轮一轮地移动数据和显示的操作,波形图也就移动起来了
可以看到,随着按键的按下和松开,屏幕上出现了一串向右移动的方波,实验成功了
还可以花式显示波形
,还有终点的坐标
(x1,y1),将两个xy值分别相减,就得到两个点的水平方向和竖直方向的距离长度|x1-x0|和
|y1-y0|。
然后以比较长的一个长度为基准,将xy两个方向的长度进行分割,分割出来的每一段的数值,就是这条线段上的相邻两个点的坐标值的变化量,如果在起点坐标的基础上,将这些变化量进行累加,就可以计算出线段上的每一个点的坐标值
由于得出的数值有时候会有小数,而画点函数只会取坐标值里的整数部分,所以还需要给xy坐标值的计算结果的小数部分,进行一下四舍五入,才能让像素点显示在比较准确的位置上
下面就根据这个思路创建一个画线函数
调用一下这个函数
更多玩法
作者:_不吃早饭_