有完整工程可下载,用的HAL库,STM32Cubemx配置的工程
STM32_IIC_OLED_QR_Code.zip
(15.77 MB, 售价: 5 E币)
以前因为某些需要,需要单片机根据字符串自动生成二维码,(而不是把二维码图片取模再用LCD显示图片)在LCD12864中显示了出来,效果图如下:
可以看到图片清晰地显示了出来,且用任意扫码工具都能快速扫描出结果。感谢前辈的无私分享。
好了,回归正题,最近手头有一块0.96寸OLED 屏幕,闲来无事就显示个二维码玩玩。首先移植前辈的二维码库,只需要QR_Encode.c和QR_Encode.h这两个就足够了。移植到任何一个能正常使用的oled驱动例程中,编写打点和画矩形函数,再调用QR_Encode.c中的bool EncodeData(char *lpsSource)函数就会根据你输入的字符串生成二维码数据并保存在全局数组m_byModuleData[MAX_MODULESIZE][MAX_MODULESIZE];中了,二维码的数据都是0或1,显示到屏幕时只需要一个个判断,遇1打点,遇0擦点(二维码正显)或遇1擦点,遇0打点(二维码反显),最后再刷新到oled上就好了。但这样的话得出来的二维码是比较小的,我们需要写算法进行放大。放大的原理是一个点用几个点表示,我用的方法是遇到0就画一个实心的矩形,遇到1就擦除一个实心矩形里面的所有点(反显),效果图如下:
我们看到,这个反显的二维码是能生成并显示出来了,但是没有打底或没有边框就显得很难看。所以为了好看,需要给它加个边框或打个白底,效果图如下(右)
此时可以看到右边这个打了白底的边框就显得很好看了。图中左边是没有打底的正显二维码,为何要用反显而不用正显呢?因为正显的除非扫码算法优化得特别好(如QQ、微信等),不然一般的扫码比较难扫描出结果,而反显的一扫就出来了,不信你们可以用浏览器的扫码或多试几个扫码软件看看。下图是正显的二维码
显示二维码到LCD最重要的是打点函数,可以开辟一个缓存用来存储打点的数据,最后把二维码数据和其他数据如边框或打底的数据都存完进这个缓存后再调用刷新屏幕函数刷新到oled即可。
打点函数如下:
- void OLED_DrawPoint(u8 x, u8 y, u8 t)
- {
- u8 pos, bx, temp = 0;
- if(x > 127 || y > 63)
- {
- return;//超出范围了.
- }
- pos = 7 - y/8;
- bx = y % 8;
- temp = 1 << (7 - bx);
- t ? (OLED_GRAM[x][pos] |= temp) : (OLED_GRAM[x][pos] &= ~temp);
- }
复制代码 刷新显存函数如下:
- void OLED_Refresh_Gram(void)//更新显存到OLED
- {
- u8 i, n;
- for(i = 0; i < 8; i++)
- {
- WriteCmd(0xb0 + i); //设置页地址(0~7)
- WriteCmd(0x00); //设置显示位置—列低地址
- WriteCmd(0x10); //设置显示位置—列高地址
- for(n = 0; n < 128; n++)
- {
- WriteDat(OLED_GRAM[n]);
- }
- }
- }
复制代码 下面就是最重要的我封装好了的二维码显示函数:- /**************************************************************************************************************
- 功能:在oled上显示二维码
- 参数:str->二维码内容; offset->二维码在X轴上的位置,范围为0-127; colour=1->二维码正显 colour=0->二维码反显
- **************************************************************************************************************/
- void OLED_QRcode_Display(char *str,uint8_t offset,uint8_t colour)//二维码的内容和第一个点再X轴的位置
- {
- uint32_t i,j,point;
- uint8_t exp = 1;//放大倍数
- uint8_t pos_X,pos_Y;
- if(colour)
- point = 1;
- else
- point = 0;
- EncodeData(str);
- exp = 64 / m_nSymbleSize; //根据屏幕尺寸自动计算最佳放大倍数
- pos_Y = (64 - exp*m_nSymbleSize)/2; //这是二维码左下角第一个点的纵坐标
- pos_X = pos_Y + offset; //这是二维码左下角第一个点的横坐标
- if(point==0)
- OLED_Fill2(pos_X-2,pos_Y-2,pos_X + exp*m_nSymbleSize+2,pos_Y + exp*m_nSymbleSize+2,1);//给反显的二维码填充底色
- //exp*m_nSymbleSize为放大后二维码的边长(二维码是正方形)
- for(i=0;i<m_nSymbleSize;i++)
- {
- for(j=0;j<m_nSymbleSize;j++)
- {
- if(m_byModuleData[j] == 1)
- {
- OLED_Fill2(pos_X,pos_Y,pos_X+exp,pos_Y+exp,point);//画矩形并填充
- }
- if(m_byModuleData[j] == 0)
- {
- OLED_Fill2(pos_X,pos_Y,pos_X+exp,pos_Y+exp,1-point);//清空矩形区域
- }
- pos_Y += exp;
- }
- pos_X += exp;
- pos_Y -= m_nSymbleSize*exp;
- }
- OLED_Refresh_Gram();
- }
复制代码 调用方法如下:
其中,str是二维码的内容,可中英文和数字,若要扫码时自动打开网页,则需要在前面加https:// ;offset是二维码在X轴上的初始横坐标,范围为0-127,可用此调整二维码的横坐标让它居左居中等,纵坐标我现在设定的是自动调整到最大,可以自己修改。colour是正反显选择,0是反显,1是正显。如我要生成一个扫码就自动进入百度网页的居中反显二维码时参数如下:OLED_QRcode_Display("https://baidu.com",63,0);这样就能达到我们想要的效果了。下面是一正一反显二维码图:
下面是我的硬件平台:STM32F103C8T6核心板和0.96寸oled。移植到其他平台时内存8K以下的慎用,可能内存会爆。。
【必读】版权免责声明
1、本主题所有言论和内容纯属会员个人意见,与本论坛立场无关。2、本站对所发内容真实性、客观性、可用性不做任何保证也不负任何责任,网友之间仅出于学习目的进行交流。3、对提供的数字内容不拥有任何权利,其版权归原著者拥有。请勿将该数字内容进行商业交易、转载等行为,该内容只为学习所提供,使用后发生的一切问题与本站无关。 4、本网站不保证本站提供的下载资源的准确性、安全性和完整性;同时本网站也不承担用户因使用这些下载资源对自己和他人造成任何形式的损失或伤害。 5、本网站所有软件和资料均为网友推荐收集整理而来,仅供学习用途使用,请务必下载后两小时内删除,禁止商用。6、如有侵犯你版权的,请及时联系我们(电子邮箱1370723259@qq.com)指出,本站将立即改正。
|
|