標(biāo)題: 單片機(jī)根據(jù)字符串生成二維碼并在OLED顯示 附源程序 [打印本頁]
作者: Linux— 時(shí)間: 2020-6-6 23:35
標(biāo)題: 單片機(jī)根據(jù)字符串生成二維碼并在OLED顯示 附源程序
12864反顯打底.jpg (3.73 MB, 下載次數(shù): 151)
下載附件
反顯二維碼打底
2020-6-6 23:37 上傳
12864反顯畫邊框.jpg (3.84 MB, 下載次數(shù): 143)
下載附件
12864反顯二維碼畫邊框
2020-6-6 23:38 上傳
可以看到圖片清晰地顯示了出來,且用任意掃碼工具都能快速掃描出結(jié)果。感謝前輩的無私分享。
好了,回歸正題,最近手頭有一塊0.96寸OLED 屏幕,閑來無事就顯示個(gè)二維碼玩玩。首先移植前輩的二維碼庫,只需要QR_Encode.c和QR_Encode.h這兩個(gè)就足夠了。移植到任何一個(gè)能正常使用的oled驅(qū)動(dòng)例程中,編寫打點(diǎn)和畫矩形函數(shù),再調(diào)用QR_Encode.c中的bool EncodeData(char *lpsSource)函數(shù)就會(huì)根據(jù)你輸入的字符串生成二維碼數(shù)據(jù)并保存在全局?jǐn)?shù)組m_byModuleData[MAX_MODULESIZE][MAX_MODULESIZE];中了,二維碼的數(shù)據(jù)都是0或1,顯示到屏幕時(shí)只需要一個(gè)個(gè)判斷,遇1打點(diǎn),遇0擦點(diǎn)(二維碼正顯)或遇1擦點(diǎn),遇0打點(diǎn)(二維碼反顯),最后再刷新到oled上就好了。但這樣的話得出來的二維碼是比較小的,我們需要寫算法進(jìn)行放大。放大的原理是一個(gè)點(diǎn)用幾個(gè)點(diǎn)表示,我用的方法是遇到0就畫一個(gè)實(shí)心的矩形,遇到1就擦除一個(gè)實(shí)心矩形里面的所有點(diǎn)(反顯),效果圖如下:
oled反顯.jpg (2.29 MB, 下載次數(shù): 131)
下載附件
oled反顯二維碼
2020-6-6 23:38 上傳
我們看到,這個(gè)反顯的二維碼是能生成并顯示出來了,但是沒有打底或沒有邊框就顯得很難看。所以為了好看,需要給它加個(gè)邊框或打個(gè)白底,效果圖如下(右)
oled正反顯2.jpg (2.75 MB, 下載次數(shù): 139)
下載附件
oled反顯
2020-6-6 23:39 上傳
此時(shí)可以看到右邊這個(gè)打了白底的邊框就顯得很好看了。圖中左邊是沒有打底的正顯二維碼,為何要用反顯而不用正顯呢?因?yàn)檎@的除非掃碼算法優(yōu)化得特別好(如QQ、微信等),不然一般的掃碼比較難掃描出結(jié)果,而反顯的一掃就出來了,不信你們可以用瀏覽器的掃碼或多試幾個(gè)掃碼軟件看看。下圖是正顯的二維碼
oled正顯.jpg (113.41 KB, 下載次數(shù): 131)
下載附件
oled二維碼正顯
2020-6-6 23:40 上傳
顯示二維碼到LCD最重要的是打點(diǎn)函數(shù),可以開辟一個(gè)緩存用來存儲(chǔ)打點(diǎn)的數(shù)據(jù),最后把二維碼數(shù)據(jù)和其他數(shù)據(jù)如邊框或打底的數(shù)據(jù)都存完進(jìn)這個(gè)緩存后再調(diào)用刷新屏幕函數(shù)刷新到oled即可。
打點(diǎn)函數(shù)如下:
- 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);
- }
復(fù)制代碼刷新顯存函數(shù)如下:
- void OLED_Refresh_Gram(void)//更新顯存到OLED
- {
- u8 i, n;
- for(i = 0; i < 8; i++)
- {
- WriteCmd(0xb0 + i); //設(shè)置頁地址(0~7)
- WriteCmd(0x00); //設(shè)置顯示位置—列低地址
- WriteCmd(0x10); //設(shè)置顯示位置—列高地址
- for(n = 0; n < 128; n++)
- {
- WriteDat(OLED_GRAM[n]);
- }
- }
- }
復(fù)制代碼下面就是最重要的我封裝好了的二維碼顯示函數(shù):
- /**************************************************************************************************************
- 功能:在oled上顯示二維碼
- 參數(shù):str->二維碼內(nèi)容; offset->二維碼在X軸上的位置,范圍為0-127; colour=1->二維碼正顯 colour=0->二維碼反顯
- **************************************************************************************************************/
- void OLED_QRcode_Display(char *str,uint8_t offset,uint8_t colour)//二維碼的內(nèi)容和第一個(gè)點(diǎn)再X軸的位置
- {
- uint32_t i,j,point;
- uint8_t exp = 1;//放大倍數(shù)
- uint8_t pos_X,pos_Y;
- if(colour)
- point = 1;
- else
- point = 0;
- EncodeData(str);
- exp = 64 / m_nSymbleSize; //根據(jù)屏幕尺寸自動(dòng)計(jì)算最佳放大倍數(shù)
- pos_Y = (64 - exp*m_nSymbleSize)/2; //這是二維碼左下角第一個(gè)點(diǎn)的縱坐標(biāo)
- pos_X = pos_Y + offset; //這是二維碼左下角第一個(gè)點(diǎn)的橫坐標(biāo)
- 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為放大后二維碼的邊長(zhǎng)(二維碼是正方形)
- 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);//清空矩形區(qū)域
- }
- pos_Y += exp;
- }
- pos_X += exp;
- pos_Y -= m_nSymbleSize*exp;
- }
- OLED_Refresh_Gram();
- }
復(fù)制代碼調(diào)用方法如下:
調(diào)用.png (72.84 KB, 下載次數(shù): 151)
下載附件
調(diào)用
2020-6-6 23:44 上傳
file:///C:\Users\梁溥開\AppData\Local\Temp\ksohtml16084\wps6.jpg
其中,str是二維碼的內(nèi)容,可中英文和數(shù)字,若要掃碼時(shí)自動(dòng)打開網(wǎng)頁,則需要在前面加https:// ;offset是二維碼在X軸上的初始橫坐標(biāo),范圍為0-127,可用此調(diào)整二維碼的橫坐標(biāo)讓它居左居中等,縱坐標(biāo)我現(xiàn)在設(shè)定的是自動(dòng)調(diào)整到最大,可以自己修改。colour是正反顯選擇,0是反顯,1是正顯。如我要生成一個(gè)掃碼就自動(dòng)進(jìn)入百度網(wǎng)頁的居中反顯二維碼時(shí)參數(shù)如下:OLED_QRcode_Display("https://baidu.com",63,0);這樣就能達(dá)到我們想要的效果了。下面是一正一反顯二維碼圖:
正反顯.jpg (2.35 MB, 下載次數(shù): 189)
下載附件
二維碼正反顯
2020-6-6 23:44 上傳
下面是我的硬件平臺(tái):STM32F103C8T6核心板和0.96寸oled。移植到其他平臺(tái)時(shí)內(nèi)存8K以下的慎用,可能內(nèi)存會(huì)爆。。
硬件平臺(tái).jpg (2.59 MB, 下載次數(shù): 153)
下載附件
硬件平臺(tái)
2020-6-6 23:45 上傳
大家可以多多評(píng)論,多多交流。
下方有完整工程可下載,用的HAL庫,STM32Cubemx配置的工程。
我的更多實(shí)用帖子大家也可看下哈,說不定某天用到呢哈哈
3、后續(xù)可能偶爾出新帖分享有趣的東西。
大家覺得不錯(cuò)的可以多多評(píng)論或轉(zhuǎn)發(fā)收藏點(diǎn)贊哈,還有,轉(zhuǎn)載注明出處,謝謝~
全部資料51hei下載地址:
IIC_OLED_QR_Code.7z
(14.33 MB, 下載次數(shù): 408)
2020-6-7 04:24 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
作者: 爐石 時(shí)間: 2020-11-5 15:22
樓主,我想問問 如果將 二維碼的數(shù)據(jù)通過熱敏打印機(jī)輸出需要如何做?
不知道你有么有頭緒,我自己寫的輸出在紙上是一串亂碼
作者: Linux— 時(shí)間: 2020-11-5 22:41
二維碼的所有數(shù)據(jù)不是0就是1,字符串轉(zhuǎn)換成二維碼數(shù)據(jù)后所有數(shù)據(jù)就都已經(jīng)存儲(chǔ)在m_byModuleData[][]這個(gè)二維數(shù)組中了,附件代碼里面有個(gè)QR_Print.c,里面有把二維碼打印到串口調(diào)試助手的代碼,是我以前調(diào)試用的,你可以看看,不知道對(duì)你有沒有幫助。
作者: 爐石 時(shí)間: 2020-11-6 17:08
嗯,我去看看,謝謝樓主
作者: 易活小乙 時(shí)間: 2020-11-13 11:23
樓主,我這邊需要弄一個(gè)二維碼顯示的東西。需要開發(fā)。請(qǐng)問有沒有時(shí)間和興趣
作者: Linux— 時(shí)間: 2020-11-16 20:12
我沒時(shí)間哦,你QQ掃碼上面最后一張圖片右邊那個(gè)二維碼,進(jìn)群找高手,那個(gè)是二維碼討論群,里面大佬非常多,源代碼和顯示的參考方法就是里面的群主分享的。
作者: steve0033 時(shí)間: 2020-11-18 16:23
c++我不懂,如果用c#可以在VSIDE用QR控件生成流數(shù)據(jù)加載到picture控件,然后保存為JPG供打印,我這個(gè)完全是windows操作思路,估計(jì)不是你的需求
作者: seanking 時(shí)間: 2020-11-20 07:54
收藏,有空看下
作者: 2099過 時(shí)間: 2021-9-9 13:30
請(qǐng)問大神 OLED_Fill2()是什么函數(shù)?
作者: cooleaf 時(shí)間: 2021-9-9 17:12
感謝樓主分享,收藏,有空看下
作者: 電子電子小宅神 時(shí)間: 2022-3-31 10:15
大佬,你的調(diào)試器和燒錄方式是?
作者: qinghua900 時(shí)間: 2022-4-20 11:29
正在研究二維碼顯示
作者: lhzw2001 時(shí)間: 2022-5-16 16:48
感謝樓主分享,
正在研究二維碼顯示
作者: 黑暗深處 時(shí)間: 2022-9-13 17:07
有個(gè)項(xiàng)目需要用這個(gè),也是OLED屏幕,剛好合適,下載來學(xué)習(xí)學(xué)習(xí)
作者: 流金歲月yy 時(shí)間: 2022-10-19 09:00
好玩,樓主會(huì)玩
作者: kbq1985 時(shí)間: 2022-11-4 23:51
謝謝樓主分享。正好想搞這個(gè)。。
作者: jiahui001 時(shí)間: 2024-10-15 13:59
怎么解決的
作者: sfd123 時(shí)間: 2024-10-16 06:51
這個(gè)挺有意思的,下一個(gè)學(xué)習(xí)一下
作者: bd7jad 時(shí)間: 2024-10-24 20:54
非常 好的教程。正是我需要的。感謝。不過我還差3個(gè)幣才能下載。。。
作者: bd7jad 時(shí)間: 2024-10-28 16:36
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);//清空矩形區(qū)域
}
以上這段中, if(m_byModuleData[j] == 1) 是錯(cuò)誤的,
原因:m_byModuleData【i】[j] 是個(gè)二維數(shù)組,
所以應(yīng)該更正為: if(m_byModuleData[i] [j] == 1)
歡迎光臨 (http://m.zg4o1577.cn/bbs/) |
Powered by Discuz! X3.1 |
主站蜘蛛池模板:
日韩精品毛片
|
成人免费高清视频
|
久久精品视频国产
|
亚洲激情一区
|
成人毛片在线
|
日韩欧美国产综合
|
国产在线h
|
日韩精品一级
|
黄色免费大片
|
日韩黄色在线观看
|
精品免费国产一区二区三区四区
|
国产午夜av
|
日韩网站在线观看
|
二级黄色片
|
亚洲另类视频
|
a级一级片
|
免费看黄色大片
|
香蕉看片|
国产999久久久
|
高清国产mv在线观看
|
久热综合
|
国产精品少妇
|
91在线精品秘密一区二区
|
五月天婷婷视频
|
亚洲永久免费视频
|
大乳女喂男人吃奶
|
中国av在线播放
|
香蕉视频在线免费看
|
午夜久久久
|
蜜臀av在线播放
|
亚洲日本精品
|
国产成人精品一区二区三区四区
|
国产做爰免费观看视频
|
黄色片免费看
|
黑人精品xxx一区一二区
|
精品视频免费在线观看
|
国产精品成人免费精品自在线观看
|
538在线视频|
精品视频在线免费观看
|
国产激情一区二区三区
|
黄www.
|