找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 7736|回复: 15
收起左侧

单片机根据字符串生成二维码并在OLED显示 附源程序

  [复制链接]
ID:435174 发表于 2020-6-6 23:35 | 显示全部楼层 |阅读模式
以前因为某些需要,需要单片机根据字符串自动生成二维码,(而不是把二维码图片取模再用LCD显示图片)恰好https://blog.csdn.net/qq_21475601/article/details/71480028这位前辈中找到了好资源,并利用这位前辈提供的LCD显示方法成功在LCD12864中显示了出来,效果图如下:

反显二维码打底

反显二维码打底

12864反显二维码画边框

12864反显二维码画边框

可以看到图片清晰地显示了出来,且用任意扫码工具都能快速扫描出结果。感谢前辈的无私分享。
        好了,回归正题,最近手头有一块0.96OLED 屏幕,闲来无事就显示个二维码玩玩。首先移植前辈的二维码库,只需要QR_Encode.cQR_Encode.h这两个就足够了。移植到任何一个能正常使用的oled驱动例程中,编写打点和画矩形函数,再调用QR_Encode.c中的bool EncodeData(char *lpsSource)函数就会根据你输入的字符串生成二维码数据并保存在全局数组m_byModuleData[MAX_MODULESIZE][MAX_MODULESIZE];中了,二维码的数据都是01,显示到屏幕时只需要一个个判断,遇1打点,遇0擦点(二维码正显)或遇1擦点,遇0打点(二维码反显),最后再刷新到oled上就好了。但这样的话得出来的二维码是比较小的,我们需要写算法进行放大。放大的原理是一个点用几个点表示,我用的方法是遇到0就画一个实心的矩形,遇到1就擦除一个实心矩形里面的所有点(反显),效果图如下:

oled反显二维码

oled反显二维码
我们看到,这个反显的二维码是能生成并显示出来了,但是没有打底或没有边框就显得很难看。所以为了好看,需要给它加个边框或打个白底,效果图如下(右)

oled反显

oled反显

此时可以看到右边这个打了白底的边框就显得很好看了。图中左边是没有打底的正显二维码,为何要用反显而不用正显呢?因为正显的除非扫码算法优化得特别好(如QQ、微信等),不然一般的扫码比较难扫描出结果,而反显的一扫就出来了,不信你们可以用浏览器的扫码或多试几个扫码软件看看。下图是正显的二维码

oled二维码正显

oled二维码正显

显示二维码到LCD最重要的是打点函数,可以开辟一个缓存用来存储打点的数据,最后把二维码数据和其他数据如边框或打底的数据都存完进这个缓存后再调用刷新屏幕函数刷新到oled即可。
打点函数如下:
  1. void OLED_DrawPoint(u8 x, u8 y, u8 t)
  2. {
  3.     u8 pos, bx, temp = 0;
  4.     if(x > 127 || y > 63)
  5.     {
  6.         return;//超出范围了.
  7.     }
  8.         pos = 7 - y/8;
  9.         bx = y % 8;
  10.         temp = 1 << (7 - bx);
  11.         t ? (OLED_GRAM[x][pos] |= temp) : (OLED_GRAM[x][pos] &= ~temp);   
  12. }
复制代码
刷新显存函数如下:
  1. void OLED_Refresh_Gram(void)//更新显存到OLED
  2. {
  3.         u8 i, n;                    
  4.         for(i = 0; i < 8; i++)  
  5.         {  
  6.                 WriteCmd(0xb0 + i);    //设置页地址(0~7)
  7.                 WriteCmd(0x00);      //设置显示位置—列低地址
  8.                 WriteCmd(0x10);      //设置显示位置—列高地址   
  9.                 for(n = 0; n < 128; n++)
  10.                 {
  11.                         WriteDat(OLED_GRAM[n]);
  12.                 }
  13.         }   
  14. }
复制代码
下面就是最重要的我封装好了的二维码显示函数:
  1. /**************************************************************************************************************
  2. 功能:在oled上显示二维码
  3. 参数:str->二维码内容;   offset->二维码在X轴上的位置,范围为0-127;  colour=1->二维码正显  colour=0->二维码反显
  4. **************************************************************************************************************/
  5. void OLED_QRcode_Display(char *str,uint8_t offset,uint8_t colour)//二维码的内容和第一个点再X轴的位置
  6. {
  7.         uint32_t i,j,point;
  8.         uint8_t exp = 1;//放大倍数
  9.         uint8_t pos_X,pos_Y;   
  10.     if(colour)
  11.         point = 1;
  12.     else
  13.         point = 0;   

  14.     EncodeData(str);        
  15.         exp = 64 / m_nSymbleSize;           //根据屏幕尺寸自动计算最佳放大倍数
  16.         pos_Y = (64 - exp*m_nSymbleSize)/2;        //这是二维码左下角第一个点的纵坐标
  17.         pos_X = pos_Y + offset;             //这是二维码左下角第一个点的横坐标

  18.     if(point==0)
  19.         OLED_Fill2(pos_X-2,pos_Y-2,pos_X + exp*m_nSymbleSize+2,pos_Y + exp*m_nSymbleSize+2,1);//给反显的二维码填充底色
  20.     //exp*m_nSymbleSize为放大后二维码的边长(二维码是正方形)
  21.         for(i=0;i<m_nSymbleSize;i++)
  22.         {
  23.                 for(j=0;j<m_nSymbleSize;j++)
  24.                 {
  25.                                 if(m_byModuleData[j] == 1)
  26.                                 {
  27.                                         OLED_Fill2(pos_X,pos_Y,pos_X+exp,pos_Y+exp,point);//画矩形并填充
  28.                                 }
  29.                                 if(m_byModuleData[j] == 0)
  30.                                 {
  31.                                         OLED_Fill2(pos_X,pos_Y,pos_X+exp,pos_Y+exp,1-point);//清空矩形区域
  32.                                 }
  33.                                 pos_Y += exp;
  34.                 }
  35.                 pos_X += exp;
  36.                 pos_Y -= m_nSymbleSize*exp;
  37.         }
  38.     OLED_Refresh_Gram();
  39. }
复制代码
调用方法如下:

调用

调用

file:///C:\Users\梁溥开\AppData\Local\Temp\ksohtml16084\wps6.jpg
其中,str是二维码的内容,可中英文和数字,若要扫码时自动打开网页,则需要在前面加https:// offset是二维码在X轴上的初始横坐标,范围为0-127,可用此调整二维码的横坐标让它居左居中等,纵坐标我现在设定的是自动调整到最大,可以自己修改。colour是正反显选择,0是反显,1是正显。如我要生成一个扫码就自动进入百度网页的居中反显二维码时参数如下:OLED_QRcode_Display("https://baidu.com",63,0);这样就能达到我们想要的效果了。下面是一正一反显二维码图:

二维码正反显

二维码正反显

下面是我的硬件平台:STM32F103C8T6核心板和0.96oled。移植到其他平台时内存8K以下的慎用,可能内存会爆。。

硬件平台

硬件平台

大家可以多多评论,多多交流。
下方有完整工程可下载,用的HAL库,STM32Cubemx配置的工程。
我的更多实用帖子大家也可看下哈,说不定某天用到呢哈哈
1、按键自由定义的矩阵键盘程序:http://www.51hei.com/bbs/dpj-150013-1.html
2、GSM获取网络时间的三种方法:http://www.51hei.com/bbs/dpj-163719-1.html
3、后续可能偶尔出新帖分享有趣的东西。
没黑币或黑币不够的小可爱请点击这里下载:https://download.csdn.net/download/qq_36112455/12503413
大家觉得不错的可以多多评论或转发收藏点赞哈,还有,转载注明出处,谢谢~

全部资料51hei下载地址:
IIC_OLED_QR_Code.7z (14.33 MB, 下载次数: 371)

评分

参与人数 1黑币 +100 收起 理由
admin + 100 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:560778 发表于 2020-11-5 15:22 | 显示全部楼层
楼主,我想问问 如果将 二维码的数据通过热敏打印机输出需要如何做?
不知道你有么有头绪,我自己写的输出在纸上是一串乱码
回复

使用道具 举报

ID:435174 发表于 2020-11-5 22:41 | 显示全部楼层
炉石 发表于 2020-11-5 15:22
楼主,我想问问 如果将 二维码的数据通过热敏打印机输出需要如何做?
不知道你有么有头绪,我自己写的输出 ...

二维码的所有数据不是0就是1,字符串转换成二维码数据后所有数据就都已经存储在m_byModuleData[][]这个二维数组中了,附件代码里面有个QR_Print.c,里面有把二维码打印到串口调试助手的代码,是我以前调试用的,你可以看看,不知道对你有没有帮助。
回复

使用道具 举报

ID:560778 发表于 2020-11-6 17:08 | 显示全部楼层
Linux— 发表于 2020-11-5 22:41
二维码的所有数据不是0就是1,字符串转换成二维码数据后所有数据就都已经存储在m_byModuleData[][]这个二 ...

嗯,我去看看,谢谢楼主
回复

使用道具 举报

ID:843004 发表于 2020-11-13 11:23 | 显示全部楼层
楼主,我这边需要弄一个二维码显示的东西。需要开发。请问有没有时间和兴趣
回复

使用道具 举报

ID:435174 发表于 2020-11-16 20:12 | 显示全部楼层
易活小乙 发表于 2020-11-13 11:23
楼主,我这边需要弄一个二维码显示的东西。需要开发。请问有没有时间和兴趣

我没时间哦,你QQ扫码上面最后一张图片右边那个二维码,进群找高手,那个是二维码讨论群,里面大佬非常多,源代码和显示的参考方法就是里面的群主分享的。
回复

使用道具 举报

ID:667992 发表于 2020-11-18 16:23 | 显示全部楼层
炉石 发表于 2020-11-5 15:22
楼主,我想问问 如果将 二维码的数据通过热敏打印机输出需要如何做?
不知道你有么有头绪,我自己写的输出 ...

c++我不懂,如果用c#可以在VSIDE用QR控件生成流数据加载到picture控件,然后保存为JPG供打印,我这个完全是windows操作思路,估计不是你的需求
回复

使用道具 举报

ID:710888 发表于 2020-11-20 07:54 | 显示全部楼层
收藏,有空看下
回复

使用道具 举报

ID:965054 发表于 2021-9-9 13:30 | 显示全部楼层
请问大神 OLED_Fill2()是什么函数?
回复

使用道具 举报

ID:430492 发表于 2021-9-9 17:12 | 显示全部楼层
感谢楼主分享,收藏,有空看下
回复

使用道具 举报

ID:830316 发表于 2022-3-31 10:15 | 显示全部楼层
大佬,你的调试器和烧录方式是?
回复

使用道具 举报

ID:1019980 发表于 2022-4-20 11:29 | 显示全部楼层
正在研究二维码显示
回复

使用道具 举报

ID:203661 发表于 2022-5-16 16:48 | 显示全部楼层

感谢楼主分享,
正在研究二维码显示
回复

使用道具 举报

ID:581552 发表于 2022-9-13 17:07 | 显示全部楼层
有个项目需要用这个,也是OLED屏幕,刚好合适,下载来学习学习
回复

使用道具 举报

ID:970487 发表于 2022-10-19 09:00 | 显示全部楼层
好玩,楼主会玩
回复

使用道具 举报

ID:163817 发表于 2022-11-4 23:51 | 显示全部楼层
谢谢楼主分享。正好想搞这个。。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表