當前位置:首頁 > 公眾號精選 > 嵌入式云IOT技術圈
[導讀]請留意變量數(shù)據(jù)類型的范圍!

國慶中秋這些天沒有回汕頭,一直留在深圳家里,據(jù)說深圳回汕頭300公里的路,老爸國慶中秋當天早上10點回去,開了20個小時才到家,也就是第二天才到,于是我就選擇不回去了,白天帶家人出去吃吃玩玩,晚上就在給客戶開發(fā)和調(diào)試一款手持儀器,順便把之前報考的MBA國際商務課老師布置的作業(yè)寫完了;這個國慶中秋可謂過得相當充實,一點都沒有浪費!簡直棒!下面這幅圖來自國慶中秋當前,顯示8小時,但是大部分朋友都開了16個小時以上,國慶中秋在高速上度過。

回到正題,客戶委托我開發(fā)的這款手持儀器屏幕采用的是和小熊派一樣的240*240分辨率的TFT顯示屏,鑒于職業(yè)道德操守與雙方協(xié)定的保密制度,這里我就不說具體是什么東西了,但是技術其實都是通用的,我們直接用小熊派來模擬這個過程就行了。

LCD屏驅(qū)動也是現(xiàn)成的,這里我直接搬了世偉兄(公眾號mculover666)的代碼,關于怎么編寫ST7789的驅(qū)動,世偉兄在之前的一篇文章里也寫得很詳細,包括怎么配置STM32CubeMX,移植他的代碼的流程等等全套保姆式服務,不得不佩服啊哈哈,鏈接如下:

STM32Cube-17 | 使用硬件SPI驅(qū)動TFT-LCD(ST7789)

這里注意到,世偉兄沒有在這個驅(qū)動里實現(xiàn)中文字模的顯示,客戶的儀器上面是要有中文顯示的,于是根據(jù)客戶的要求,我移植了之前開發(fā)積累下來的顯示中文字模的代碼:

void?LCD_ShowChinese(uint16_t?x,uint16_t?y,uint8_t?*s,uint16_t?fc,uint16_t?bc,uint8_t?sizey,uint8_t?mode);

這個函數(shù)用于顯示漢字串,原型如下:

/**********************************************************/
//顯示漢字
/******************************************************************************
??????函數(shù)說明:顯示漢字串
??????入口數(shù)據(jù):x,y顯示坐標
????????????????*s?要顯示的漢字串
????????????????fc?字的顏色
????????????????bc?字的背景色
????????????????sizey?字號?可選?16?24?32
????????????????mode:??0非疊加模式??1疊加模式
??????返回值:??無
******************************************************************************/
void?LCD_ShowChinese(uint16_t?x,uint16_t?y,uint8_t?*s,uint16_t?fc,uint16_t?bc,uint8_t?sizey,uint8_t?mode)
{
?while(*s!=0)
?{
??if(sizey==12)?LCD_ShowChinese12x12(x,y,s,fc,bc,sizey,mode);
??else?if(sizey==16)?LCD_ShowChinese16x16(x,y,s,fc,bc,sizey,mode);
??else?if(sizey==24)?LCD_ShowChinese24x24(x,y,s,fc,bc,sizey,mode);
??else?if(sizey==32)?LCD_ShowChinese32x32(x,y,s,fc,bc,sizey,mode);
??else?if(sizey==48)?LCD_ShowChinese48x48(x,y,s,fc,bc,sizey,mode);
??else?if(sizey==64)?LCD_ShowChinese64x64(x,y,s,fc,bc,sizey,mode);
??else?return;
??s+=2;
??x+=sizey;
?}
}

這樣,通過傳入字號參數(shù),我們可以靈活根據(jù)項目需求配置顯示不同字號的中文字體,這里我配置了12、16、24、32、48、64規(guī)格的字體,以顯示單個12*12字號為例,詳細函數(shù)實現(xiàn)如下:

/******************************************************************************
??????函數(shù)說明:顯示單個12x12漢字
??????入口數(shù)據(jù):x,y顯示坐標
????????????????*s?要顯示的漢字
????????????????fc?字的顏色
????????????????bc?字的背景色
????????????????sizey?字號
????????????????mode:??0非疊加模式??1疊加模式
??????返回值:??無
******************************************************************************/
void?LCD_ShowChinese12x12(uint16_t?x,uint16_t?y,uint8_t?*s,uint16_t?fc,uint16_t?bc,uint8_t?sizey,uint8_t?mode)
{
?uint8_t?i,j,m=0;
?uint16_t?k;
?uint16_t?HZnum;//漢字數(shù)目
?uint16_t?TypefaceNum;//一個字符所占字節(jié)大小
?uint16_t?x0=x;
?TypefaceNum=(sizey/8+((sizey%8)?1:0))*sizey;
??????????????????????????
?HZnum=sizeof(tfont12)/sizeof(typFNT_GB12);?//統(tǒng)計漢字數(shù)目
?for(k=0;k?{
??if((tfont12[k].Index[0]==*(s))&&(tfont12[k].Index[1]==*(s+1)))
??{??
???LCD_Address_Set(x,y,x+sizey-1,y+sizey-1);
???for(i=0;i???{
????for(j=0;j<8;j++)
????{?
?????if(!mode)//非疊加方式
?????{
??????if(tfont12[k].Msk[i]&(0x01<fc);
??????else?LCD_Write_Data(bc);
??????m++;
??????if(m%sizey==0)
??????{
???????m=0;
???????break;
??????}
?????}
?????else//疊加方式
?????{
??????if(tfont12[k].Msk[i]&(0x01<fc);//畫一個點
??????x++;
??????if((x-x0)==sizey)
??????{
???????x=x0;
???????y++;
???????break;
??????}
?????}
????}
???}
??}???????
??continue;??//查找到對應點陣字庫立即退出,防止多個漢字重復取模帶來影響
?}
}?

這個函數(shù)其實就是從軟件生成的字模表里將對應漢字的字庫找出來,所謂的字模表是由一個定義好的結(jié)構體組成,結(jié)構體中有兩個分量,第一個是要顯示的漢字,第二個是該漢字的字庫,該函數(shù)就是將對應漢字的字庫數(shù)據(jù)一個字節(jié)一個字節(jié)取出來然后發(fā)送到LCD顯示屏上實現(xiàn)刷屏,由于加上了顏色分量,所以我們看到直觀的就是以某個顏色分量體現(xiàn)的字體顯示,12*12的字模表的數(shù)據(jù)結(jié)構定義如下:

typedef?struct?
{
?unsigned char Index[2];?//漢字內(nèi)碼索引
?unsigned?char?Msk[24];??//?點陣碼數(shù)據(jù)
}typFNT_GB12;?

這個點陣碼數(shù)據(jù)又是怎么生成的呢?以生成黑體字為例,打開PCtoLCD2002軟件,設置字模生成參數(shù):

然后我們將生成的復制到字模表對應的數(shù)組里就可以啦:

typedef?struct?
{
?unsigned?char?Index[2];?
?unsigned?char?Msk[24];
}typFNT_GB12;?

const?typFNT_GB12?tfont12[]={
//中(0)?景(1)?園(2)?電(3)?子(4)
"中",0x60,0x00,0x20,0x00,0x20,0x00,0xFE,0x07,0x22,0x04,0x22,0x04,0xFE,0x07,0x22,0x04,
0x20,0x00,0x20,0x00,0x20,0x00,0x00,0x00,/*"中",0*/
?
"景",0xFC,0x03,0x04,0x02,0xFC,0x03,0xFC,0x03,0x20,0x00,0xFE,0x07,0xF8,0x03,0x04,0x02,
0xF8,0x01,0x58,0x03,0x66,0x04,0x00,0x00,/*"景",1*/
?
"園",0x00,0x00,0xFE,0x07,0xF2,0x05,0x02,0x04,0xFA,0x05,0x52,0x04,0x52,0x04,0x52,0x07,
0x8A,0x05,0x02,0x04,0xFE,0x07,0x00,0x00,/*"園",2*/

"電",0x20,0x00,0x20,0x00,0xFE,0x03,0x22,0x02,0x22,0x02,0xFE,0x03,0x22,0x02,0xFE,0x03,
0x22,0x00,0x20,0x04,0xE0,0x07,0x00,0x00,/*"電",3*/

"子",0x00,0x00,0xFC,0x03,0x80,0x01,0x60,0x00,0x20,0x00,0xFE,0x07,0x20,0x00,0x20,0x00,
0x20,0x00,0x20,0x00,0x30,0x00,0x00,0x00,/*"子",4*/
};

Msk中的24代表一個字對應字庫需要占用24個字節(jié)的內(nèi)存,在main函數(shù)中編寫顯示字符串"中景園電子"的代碼,如下所示:

下載到小熊派開發(fā)板上,以下就是我們最后看到生成的效果,

這簡直太小了,不刺激,于是照葫蘆畫瓢,依次編寫了16*16、24*24、32*32、48*48、64*64這些常用的中文字庫,一起顯示看看效果如何,結(jié)果如下:

咦,怎么感覺前三個12*12、24*24、32*32這些都沒問題,48*48、64*64顯示就亂了呢???What???(黑人問號?)

仔細對比48*48、64*64兩個函數(shù),寫法和找字模的方法與前幾個都是一樣的,只是字模表做了更改,但原理都是一樣的啊!實在看不出問題出在哪?于是請教了正念兄(微信公眾號:嵌入式大雜燴)號主,正念兄也動手做了下實驗,而他那邊顯示是對的,只是顯示的函數(shù)的編寫方法和我的不一樣,但是原理是一樣的。

經(jīng)過我們的討論結(jié)果,以及正念兄在他那邊隨便拿了一個TFT屏測試的結(jié)果后,我恍然大悟,可能是數(shù)據(jù)類型的問題!到底是哪個數(shù)據(jù)類型導致顯示錯亂了呢?我們來單獨看看顯示48*48中文的函數(shù):

/******************************************************************************
??????函數(shù)說明:顯示單個48x48漢字
??????入口數(shù)據(jù):x,y顯示坐標
????????????????*s?要顯示的漢字
????????????????fc?字的顏色
????????????????bc?字的背景色
????????????????sizey?字號
????????????????mode:??0非疊加模式??1疊加模式
??????返回值:??無
******************************************************************************/
void?LCD_ShowChinese48x48(uint16_t?x,uint16_t?y,uint8_t?*s,uint16_t?fc,uint16_t?bc,uint8_t?sizey,uint8_t?mode)
{
?uint8_t?i,j,m=0;
?uint16_t?k;
?uint16_t?HZnum;//漢字數(shù)目
?uint16_t?TypefaceNum;//一個字符所占字節(jié)大小
?uint16_t?x0=x;
?TypefaceNum=(sizey/8+((sizey%8)?1:0))*sizey;
?printf("TypefaceNum:%d\n",TypefaceNum);
?HZnum=sizeof(tfont48)/sizeof(typFNT_GB48);?//統(tǒng)計漢字數(shù)目
?for(k=0;k?{
??if?((tfont48[k].Index[0]==*(s))&&(tfont48[k].Index[1]==*(s+1)))
??{??
???LCD_Address_Set(x,y,x+sizey-1,y+sizey-1);
???for(i=0;i???{
????for(j=0;j<8;j++)
????{?
?????if(!mode)//非疊加方式
?????{
??????if(tfont48[k].Msk[i]&(0x01<fc);
??????else?LCD_Write_Data(bc);
??????m++;
??????if(m%sizey==0)
??????{
???????m=0;
???????break;
??????}
?????}
?????else//疊加方式
?????{
??????if(tfont48[k].Msk[i]&(0x01<fc);//畫一個點
??????x++;
??????if((x-x0)==sizey)
??????{
???????x=x0;
???????y++;
???????break;
??????}
?????}
????}
???}
??}???????
??continue;??//查找到對應點陣字庫立即退出,防止多個漢字重復取模帶來影響
?}
}

經(jīng)過一段時間單步調(diào)試后,我開始懷疑i變量的數(shù)據(jù)類型(uint8_t)越界了,結(jié)果通過printf一打,還真的是這樣:

然后我把48*48以及64*64這兩個中文顯示函數(shù)里的uint8_t統(tǒng)一修改為uint16_t后,顯示正常了:

我相信有不少朋友也遇到過我遇到的這個坑,做嵌入式(指Linux端)的我們平常都是很豪邁的用int、short、long這樣的類型,然而MCU上由于資源緊張,沒辦法那么豪邁,于是定義合適的數(shù)據(jù)類型就顯得尤為重要了,不得不說,基礎還是很重要的,留一張表,再次碰到類似這樣的問題希望能夠立馬在腦海中反應過來。

本節(jié)代碼已同步到碼云的代碼倉庫中:

獲取方法如下:

1、新建一個文件夾

2、使用git clone遠程獲取小熊派所有案例代碼

我還將之前做的一些項目以及練習例程在近期內(nèi)全部上傳完畢,與大家一起分享交流:

公眾號粉絲福利時刻

這里我給大家申請到了福利,本公眾號讀者購買小熊派開發(fā)板可享受9折優(yōu)惠,有需要購買小熊派以及騰訊物聯(lián)網(wǎng)開發(fā)板的朋友,淘寶搜索即可,跟客服說你是公眾號:嵌入式云IOT技術圈?的粉絲,立享9折優(yōu)惠!

往期精彩

TencentOS tiny RTOS快速入門

移植uc/OS-III最新版到小熊派開發(fā)板(STM32L431)

TOS的AT模組框架

C/C++函數(shù)指針與指針函數(shù)

STM32硬核DIY機械鍵盤|藍牙USB雙模|燈控

覺得本次分享的文章對您有幫助,隨手點[在看]并轉(zhuǎn)發(fā)分享,也是對我的支持。

免責聲明:本文內(nèi)容由21ic獲得授權后發(fā)布,版權歸原作者所有,本平臺僅提供信息存儲服務。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫毥谦F公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務中斷的風險,如企業(yè)系統(tǒng)復雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務連續(xù)性,提升韌性,成...

關鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關鍵字: 華為 12nm EDA 半導體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權最終是由生態(tài)的繁榮決定的。

關鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務引領增長 以科技創(chuàng)新為引領,提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強核心競爭優(yōu)勢...

關鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術學會聯(lián)合牽頭組建的NVI技術創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術創(chuàng)新聯(lián)...

關鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關鍵字: BSP 信息技術
關閉
關閉