0.96英寸128*64 OLED显示二维码

news/2024/11/15 7:04:26/

0.96英寸I2C,OLED 显示屏显示二维码 STM32 SSD1306 RT-Thread

    • 关于
    • 软、硬件环境
    • 开启RT-Thread的终端打印二维码功能
    • 思路
    • 移植开肝
    • 开始测试

关于

最近手头上有个0.96英寸的 128*64得单色显示屏,突发想法能不能在上面显示二维码,手机扫描出来呢,这样的功能对于拥有这种显示屏的物联网设备肯定大有用处啊。
首先 百度一下,发现还真有人已经实现了这样的功能,CSDN上也有资源,但是这特么的积分也要的太狠吧,我这个穷逼买不起啊,开源给大家看看会屎么?MP啊。

网上找了些资料,发现有开源的库,发现一个库https://github.com/fukuchi/libqrencode 研究了下,表示看的不太明白,放弃。

突然想到 卧槽,我这个用的RT-Thread,不是有在终端打印出二维码的功能么。。。。。
在这里插入图片描述
卧槽。。。。。。什么都⑧说了,开干。

软、硬件环境

首先给大家说明下,我的环境,免得后续出现一系列问题。

  1. 主控MCU ,STM32F103VE;
  2. 显示屏 ,0.96 英寸 128*64 OLED显示屏,控制芯片是SSD1306,接口I2C
  3. 操作系统,众所周知,RT-Thread。
    显示的驱动已经移植好了。只需要可以正常显示字符就可以了。

开启RT-Thread的终端打印二维码功能

利用控制台,开启QRCode
在生成工程之前不要忘记 输入命令 pkgs --update

生成工程 scons --target=mdk5

打开工程,编译。

一切正常的情况下,可以看到下图
在这里插入图片描述
RT-Thread 的这个QrCode的库也是移植这个的https://github.com/ricmoo/QRCode

思路

从源码可以看到如下示例:

for (uint8 y = 0; y < qrcode.size; y++) {for (uint8 x = 0; x < qrcode.size; x++) {if (qrcode_getModule(&qrcode, x, y) {Serial.print("**");} else {Serial.print("  ");}}Serial.print("\n");
}

这个是打印到终端的示例程序,根据代码可以判断,原理是根据生成的点阵,判断点阵的x,y是否为1,然后在再终端打印**或者空格。
函数 qrcode_getModule(&qrcode, x, y),获取指定位置是否有点的,返回1则表示该位置有点,返回0则改位置无点。

那么问题来了,这个得到的二维码的点阵大小是多少?
到刚才那个github项目大佬主页,可以看到
在这里插入图片描述
原来这个点阵和代码里面,定义的#define DEFAULT_QR_VERSION 3
有关,例如定义为4,那么生成的点阵就是 33*33 个点。

那么很简单了,把这些点阵 填充到显示的缓冲,然后不就ojbk了,是不是?
好了开始肝了。
在这里插入图片描述

移植开肝

这里首先我们要搞清楚,这个屏幕显示的原理
屏幕的主控用的是SSD1306:手册
在这里插入图片描述
可以看到点阵的显示扫描方式是,从左到右(也可从右到左),从上到下扫描显示的。每个页纵向8个点,横向127个点。纵向每8个点表示一页,如果是128*64的话就是8页(0~7)。

搞清了显示的原理,那么特么只要填点阵就可以了。
初始化显示屏

    OLED_WR_Byte(0xAE,OLED_CMD);//--display offOLED_WR_Byte(0x00,OLED_CMD);//---set low column addressOLED_WR_Byte(0x10,OLED_CMD);//---set high column addressOLED_WR_Byte(0x40,OLED_CMD);//--set start line address  OLED_WR_Byte(0xB0,OLED_CMD);//--set page addressOLED_WR_Byte(0x81,OLED_CMD); // contract controlOLED_WR_Byte(0xFF,OLED_CMD);//--128   OLED_WR_Byte(0xA1,OLED_CMD);//set segment remap OLED_WR_Byte(0xA6,OLED_CMD);//--normal / reverseOLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)OLED_WR_Byte(0x3F,OLED_CMD);//--1/32 dutyOLED_WR_Byte(0xC8,OLED_CMD);//Com scan directionOLED_WR_Byte(0xD3,OLED_CMD);//-set display offsetOLED_WR_Byte(0x00,OLED_CMD);//OLED_WR_Byte(0xD5,OLED_CMD);//set osc divisionOLED_WR_Byte(0x80,OLED_CMD);//OLED_WR_Byte(0xD8,OLED_CMD);//set area color mode offOLED_WR_Byte(0x05,OLED_CMD);//OLED_WR_Byte(0xD9,OLED_CMD);//Set Pre-Charge PeriodOLED_WR_Byte(0xF1,OLED_CMD);//OLED_WR_Byte(0xDA,OLED_CMD);//set com pin configuartionOLED_WR_Byte(0x12,OLED_CMD);//OLED_WR_Byte(0xDB,OLED_CMD);//set VcomhOLED_WR_Byte(0x30,OLED_CMD);//OLED_WR_Byte(0x8D,OLED_CMD);//set charge pump enableOLED_WR_Byte(0x14,OLED_CMD);//OLED_WR_Byte(0xAF,OLED_CMD);//--turn on oled panelOLED_Clear();

声明一个显示的二位数组

#define DEFAULT_QR_VERSION 6
#define Xsize  4*DEFAULT_QR_VERSION+17
#define Ysize  (4*DEFAULT_QR_VERSION+17)/8+1
uint8_t qr_code_buff[Ysize][Xsize]={0};  // 显示点阵缓冲

对于显示的点阵,大家可以看如下解释:

                 -------------------------------->X
|       0	    0	2	3	4	.	.	.	.	.	   127
|		0       x	x	x	x	x	.	.	.	.	.	x
|		1       x	x	x	x	x	.	.	.	.	.	x
|		2		x	x	x	x	x	.	.	.	.	.	x
|		.		x	x	x	x	x	.	.	.	.	.	x
|		.		x	x	x	x	x	.	.	.	.	.	x
|		.		x	x	x	x	x	.	.	.	.	.	x
Y		.		x	x	x	x	x	.	.	.	.	.	x.		x	x	x	x	x	.	.	.	.	.	x7		x	x	x	x	x	.	.	.	.	.	x每个X位 表示OLED 的纵向8个点阵的16进制数据

先搞个函数,方便后面操作。下面这个函数可以对上面矩阵任意位置填充一位16进制数。

//根据x,y填充纵向8个点阵的数据
void OLED_Draw_Vertical_Byte(u8 x,u8 y, u8 data)
{OLED_Set_Pos(x,y);OLED_WR_Byte(data,OLED_DATA);}

ojbk!!!
继续下一步
搞个方法,通过生成的二维码的点阵,来对显示的缓存进行相应位置填充,这里大家注意一下细节:
首先 起个函数名,然后第二步确定好传入的参数,可以了。。。。。。。。。。
接下来就像下面这样。。。。。。。。

void OLED_Draw_QRCode(char *qrstr) //绘制 二维码图片    
{QRCode qrc;uint8_t x, y,z, *qrcodeBytes = (uint8_t *)rt_calloc(1, qrcode_getBufferSize(DEFAULT_QR_VERSION));int8_t result;uint8_t num=0;if (qrcodeBytes){result = qrcode_initText(&qrc, qrcodeBytes, DEFAULT_QR_VERSION, ECC_LOW, qrstr);if (result >= 0){num=qrc.size/8;//扫描方式:先每次扫y轴8个点,再扫描整个x轴for(x=0;x<qrc.size;x++)   //根据生产的二维码点阵  填充到显示的缓冲矩阵重    先计算到 二维码点阵y坐标的8的整数倍  {		for(z=0;z<num;z++)  {					for(y=0;y<8;y++)  //y 坐标每次8个点  {if (qrcode_getModule(&qrc, x, 8*z+y)){setbit(qr_code_buff[z][x],y);  }else{clrbit(qr_code_buff[z][x],y);  }								 }							}							}	for(x=0;x<qrc.size;x++)                     //计算填充y轴剩下的 点阵{			for(y=0;y<qrc.size%8;y++){if (qrcode_getModule(&qrc, x, num*8+y)){setbit(qr_code_buff[num][x],y); }else{clrbit(qr_code_buff[num][x],y); }					}				}				for(y=0;y<Ysize;y++){for(x=0;x<Xsize;x++){				OLED_Draw_Vertical_Byte(x,y,qr_code_buff[y][x]);		//将计算好点阵 填到屏幕上}}			rt_free(qrcodeBytes);}else{rt_kprintf("Warning: no memory!\n");}}
}

好了,到此应该问题不大。。。。。。。。。。。
ojbk!!!!!!!!!!!!!
在这里插入图片描述

开始测试

用RT-Thread 的MSH控制台搞个测试命令

static void qrcode(uint8_t argc, char **argv)
{#define DEFAULT_QR_STRING "HELLO WORLD"char *qrstr = DEFAULT_QR_STRING;if (argc > 1){qrstr = argv[1];}				OLED_Draw_QRCode(qrstr);
}
MSH_CMD_EXPORT(qrcode, qrcode generator: qrcode [string]);

everthing is OK!!!!!!

放图看下显示效果
在这里插入图片描述
看看大家扫出了什么?

在这里插入图片描述


http://www.ppmy.cn/news/253590.html

相关文章

C语言人五英尺七英寸,5尺7寸(5尺7寸是多高美国)

如题、换算成米或厘米 五尺五165 五尺六167 五尺七170 每高出一英寸都是2或者3厘米往上加6尺1837尺213 每加一英寸后面可能都有小数点 一般就是四舍五入 五英尺十英寸 英尺=12寸1寸=2.54. 楼主如果问的是英制的话,5尺7寸半就可能是一个高个子女生或一个普通男生的身高了。英制…

英寸、磅等单位的换算

英寸换算 长度单位&#xff1a; 1 英寸&#xff1d;2.5400 厘 米 1 英 尺 &#xff1d;12 英 寸 &#xff1d;0.3048 米 1 码 &#xff1d;3 英 尺 &#xff1d;0.9144 米 1 英 里 &#xff1d;1760 码 &#xff1d;1.6093 千 米 厘米:cm 英寸:in 1 in2.54cm 1英尺&#xff1d;…

2022 Apple 春季发布会带来全新 27 英寸 Studio Display

北京时间2022年3月9日凌晨的苹果春季发布会上&#xff0c;Apple为大家带来了新的显示器&#xff0c;Studio Display 是 Apple 十多年来推出的第一款以消费者为中心的显示器&#xff0c;旨在与新的 M1 驱动的 Mac Studio 配合使用。 自从苹果在 2016 年停止了其最后一款消费者显…

一英寸芯片大小_CCD芯片尺寸

焦距 f = WD CCD 芯片尺寸 ( H or V) / FOV( H or V) 视场 FOV ( H or V) = 物距 WD CCD 芯片尺寸 ( H or V) / 焦距 f 视场 FOV( H or V) = CCD 芯片尺寸 ( H or V) / 光学倍率 工作距离 WD= f( 焦距 ) CCD 芯片尺寸 /FOV( H or V) 光学倍率 = CCD 芯片尺寸 ( H or V) /…

毫米、微米、英寸、目数对照表

毫米、微米、英寸、目数对照表 微米um是我们常用的长度单位&#xff0c;很多重要的场合都会使用到&#xff0c;它是很短的长度&#xff0c;所以特别在一些要求很精确的地方微米就是一个极其重要的长度了&#xff0c;我们一起来了解下微米与常用单位的换算及相关知识&#xff0…

分析师称苹果年内将发布60英寸电视

4月4日&#xff0c;有机构分析师称&#xff0c;苹果今年或发布60英寸的电视机产品“iTV”&#xff0c;售价在1500美元到2500美元之间。 机构Topeka Capital的分析师布莱恩怀特(Brian White)在周三发布的报告中指出&#xff0c;他得知苹果今年晚些时候将开售这种大尺寸的“iTV”…

5英寸是几厘米

单位换算 &#xff08;1&#xff09;英寸换算&#xff1a;1码3英尺36英寸、l英尺12英寸&#xff0c;通常在使用英寸时&#xff0c;采用简记符号“” &#xff08;2&#xff09;厘米换算&#xff1a;lcm10mm、ldm10cm、1m10dm。 英寸、英尺为英制单位&#xff0c;采用8与12进…

java+英尺英寸,身高英寸换算(身高换算成英尺英寸)

大腿围1尺8寸半。袖长1尺6.衣长2尺2.裤裆1尺半。该怎么换算 一尺一般换算成33.3cm就可以了。不过量的时候要注意,很多量衣服的尺子一面是厘米,一面却是英尺,而不是市尺。一英尺一般换算成30.5cm。 告诉你一个换算公式英尺换算成米=(英尺*12+英寸)*0.0254(定值)英尺换算成厘米…