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的终端打印二维码功能


在生成工程之前不要忘记 输入命令 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!!!!!!

放图看下显示效果

看看大家扫出了什么?

0.96英寸128*64 OLED显示二维码相关推荐

  1. 利用51单片机+0.96寸iic接口oled显示图片或动图

    利用51单片机+0.96寸iic接口oled显示图片或动图 前言:之前讲过如何使用oled显示数字以及字符,但并未讲述如何显示BMP格式的图片, 这篇将在之前的基础上加以封装一些函数用来显示图片 硬件 ...

  2. 用STC单片机在TFT屏上显示二维码

    用STC8A单片机在TFT屏上显示二维码 概述 最近项目需要用单片机在TFT屏上显示二维码,将C++下显示二维码的代码经过改造,移值到C代码的单片机,成功运行,经多次测试能稳定运行,TFT屏显示部分, ...

  3. 物联网开发笔记(30)- 使用Micropython开发ESP32开发板之控制240x240的oled屏幕显示二维码(ST7789芯片)

    一.目的 在我们的240x240的oled屏幕上显示二维码 二.环境 ESP32 + 240x240的oled彩色屏幕+ Thonny IDE + 几根杜邦线 接线方式请看上前面的章节,此处不再重复赘 ...

  4. 用户登入腾讯视频,QQ扫描二维码不显示二维码

    环境: 电脑:联想E14 系统:Windows 10 专业版 64位 AC:深信服AC13.0.47 问题描述: 用户登入腾讯视频,QQ扫描二维码不显示二维码 解决方案: 1.在AC上,在线用户列表搜 ...

  5. 点击识别元素位置、生成显示二维码、下载二维码

    百度网盘地址 效果: 代码: <!DOCTYPE html> <html><head><meta charset="UTF-8">& ...

  6. Jenkins配置自动打包app发布蒲公英显示二维码

    Jenkins配置自动打包app发布蒲公英显示二维码 搞了一周,终于弄好了,下面就是见证奇迹的时刻. 1.下载Jenkins,去官网点这里选择Windows版本: 2.下载完是个zip解压 安装 一路 ...

  7. 使用CSS实现悬停显示二维码

    目录 方法一 方法二(推荐) 在进行广告配置时,要显示的二维码太小,直接扫码扫不出来,于是需要实现鼠标悬停显示大的二维码. 有两种实现的方法: 方法一 直接在要悬停显示二维码的 DOM 元素上添加样式 ...

  8. qrcode不显示二维码

    <!DOCTYPE html> <html><head><title>标题</title></head><script s ...

  9. 知云文献翻译登录时不显示二维码,显示二维码后扫描登录不跳转解决方案

    1.登录时不显示二维码--解决方案 打开 Internet Explorer 点击"设置"中的"Internet 选项" 切换到"连接"选项 ...

最新文章

  1. 最最基本的Git入门 -- 本地仓库操作
  2. python画折线图详解-python绘制简单折线图代码示例
  3. 大创项目实施方案模板范文_27篇互联网电商创业计划书范文+34个电商行业商业计划书模板下载...
  4. 【记录】python多线程的使用 线程同步(LOCK和RLOCK) python与mysql数据库交互实现增加和查找 python的格式化输出
  5. 【Luogu】P3380树套树模板(线段树套Splay)
  6. Servlet使用适配器模式进行增删改查案例(Emp.java)
  7. 升级无法登录_JeeSite v4.2.2 发布,代码生成增强、Boot 2.3、短信登录、性能提升...
  8. docker 容器开启ssh服务
  9. qt widget加载qml_Qml组件小知识
  10. android如何用代码实现界面ui
  11. golden gate 加initial load 在rac 上的配置
  12. 一个问题,两人讨论,几行代码,一些启发_刘未鹏
  13. windows 核心编程下的内存映射文件
  14. 异常的分类以及什么异常触发回滚
  15. 十大排序算法(C++版)
  16. Linux修改系统时间
  17. Win10如何取消开机密码?Win10取消开机密码步骤
  18. CNN中的小tips
  19. 普通人千万别把打工当赚钱,打工只是赚钱的一种方法
  20. 用户画像—打用户行为标签

热门文章

  1. 中基鸿业工薪家庭理财方法
  2. canvas开发手册完整版
  3. WindowsXP注册表详解
  4. 联想一体机电源键不亮_联想力压华为拿下6·18 PC“六冠王”,背后有何秘诀?...
  5. dotnet Multi-platform App UI 多平台应用 UI 框架简介
  6. OKA通证权益解析,参与Okaleido生态建设的不二之选
  7. html5 舰c 手机,我国最新款导弹驱逐舰052D,主力战舰的不二之选,中国厉害了!...
  8. JavaSE练习题之不死神兔
  9. php的解析别名,浅谈laravel aliases别名的原理
  10. 设备树文件里的aliases和chosen