有完整工程可下載,用的HAL庫,STM32Cubemx配置的工程
STM32_IIC_OLED_QR_Code.zip
(15.77 MB, 售價: 1 E幣)
2023-6-6 16:05 上傳
點擊文件名下載附件
售價: 1 E幣 [記錄]
[ 購買]
8.png (7.05 KB)
下載附件
2020-6-7 16:02 上傳
以前因為某些需要,需要單片機根據字符串自動生成二維碼,(而不是把二維碼圖片取模再用LCD顯示圖片)在LCD12864中顯示了出來,效果圖如下:
1.png (390.47 KB)
下載附件
2020-6-7 15:33 上傳
2.png (406.58 KB)
下載附件
2020-6-7 15:33 上傳
可以看到圖片清晰地顯示了出來,且用任意掃碼工具都能快速掃描出結果。感謝前輩的無私分享。
好了,回歸正題,最近手頭有一塊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就擦除一個實心矩形里面的所有點(反顯),效果圖如下:
3.png (259.39 KB)
下載附件
2020-6-7 15:36 上傳
我們看到,這個反顯的二維碼是能生成并顯示出來了,但是沒有打底或沒有邊框就顯得很難看。所以為了好看,需要給它加個邊框或打個白底,效果圖如下(右)
4.png (266.44 KB)
下載附件
2020-6-7 15:37 上傳
此時可以看到右邊這個打了白底的邊框就顯得很好看了。圖中左邊是沒有打底的正顯二維碼,為何要用反顯而不用正顯呢?因為正顯的除非掃碼算法優化得特別好(如QQ、微信等),不然一般的掃碼比較難掃描出結果,而反顯的一掃就出來了,不信你們可以用瀏覽器的掃碼或多試幾個掃碼軟件看看。下圖是正顯的二維碼
5.png (300.86 KB)
下載附件
2020-6-7 15:44 上傳
顯示二維碼到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();
- }
復制代碼 調用方法如下:
234421qqxppz9ssbsjxbz3.png (85.41 KB)
下載附件
2020-6-7 15:47 上傳
其中,str是二維碼的內容,可中英文和數字,若要掃碼時自動打開網頁,則需要在前面加https:// ;offset是二維碼在X軸上的初始橫坐標,范圍為0-127,可用此調整二維碼的橫坐標讓它居左居中等,縱坐標我現在設定的是自動調整到最大,可以自己修改。colour是正反顯選擇,0是反顯,1是正顯。如我要生成一個掃碼就自動進入百度網頁的居中反顯二維碼時參數如下:OLED_QRcode_Display("https://baidu.com",63,0);這樣就能達到我們想要的效果了。下面是一正一反顯二維碼圖:
6.png (167.46 KB)
下載附件
2020-6-7 15:49 上傳
下面是我的硬件平臺:STM32F103C8T6核心板和0.96寸oled。移植到其他平臺時內存8K以下的慎用,可能內存會爆。。
7.png (519.79 KB)
下載附件
2020-6-7 16:01 上傳
【必讀】版權免責聲明
1、本主題所有言論和內容純屬會員個人意見,與本論壇立場無關。2、本站對所發內容真實性、客觀性、可用性不做任何保證也不負任何責任,網友之間僅出于學習目的進行交流。3、對提供的數字內容不擁有任何權利,其版權歸原著者擁有。請勿將該數字內容進行商業交易、轉載等行為,該內容只為學習所提供,使用后發生的一切問題與本站無關。 4、本網站不保證本站提供的下載資源的準確性、安全性和完整性;同時本網站也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的損失或傷害。 5、本網站所有軟件和資料均為網友推薦收集整理而來,僅供學習用途使用,請務必下載后兩小時內刪除,禁止商用。6、如有侵犯你版權的,請及時聯系我們(電子郵箱1370723259@qq.com)指出,本站將立即改正。
|
|