最近因為要使用STM32做畢業設計,需要用LCD顯示中文,STM32開發板用的是原子的戰艦STM32開發板,給的LCD顯示例程里貌似沒有中文顯示,那么需要自己去編寫中文顯示程序。
軟件編寫對我來說並不是什么難事,關鍵就是在這個過程中遇到了一個非常奇葩的問題。
我用的取模軟件是PCtoLCD2002.exe,這在很多地方都能找到。生成字模后,在每一個字模的最后有對應的中文注釋,但是將生成的字模復制到程序中發現一個問題,中文顯示成了問號,顯示如下:
我想,這很簡單,無非就是中文編碼格式不一樣嘛,新建一個文本文檔,然后用notepad++打開,將生成的字模粘貼進去,發現可以正常顯示:
然后看一下它的編碼格式,發現是UTF-8編碼:
這意味着在keil5里使用UTF-8編碼就可以正常顯示了,在keil5菜單欄點擊Edit->Configuration:
在彈出的框中發現keil5中是用ANSI解碼的,現在我們換成UTF-8解碼,然后點擊OK:
完了之后會發現,剛剛復制過來的字模,中文注釋怎么還是一個問號啊,別着急,這是因為,之前將UTF-8的編碼內容復制進了ANSI解碼的文檔中,keil5會將無法解碼的部分直接替換成一個問號,也就是說,此時keil5中這個問號並不是亂碼,這是一個真真正正的問號啊。(這里有必要提一下,為什么只有中文亂碼了而英文和數字沒有亂碼,那是因為英文和數字都是用ASCLL編碼的,而ASCLL碼是所有編碼的一個子集,也就是說,無論你用什么方式編碼,ASCLL碼那部分都是不會亂碼的。)OK,接下來要解決這個問題也很簡單,將復制過來的字模刪掉,然后重新粘貼,因為這時keil5已經是用UTF-8解碼的了,所以是能夠正常顯示UTF-8編碼的中文了:
等等,我好像發現了什么,雖然復制過來的字模可以顯示成中文了,但是之前的中文注釋好像亂碼了:
好吧,因為我需要參考很多原子的例程,那么我們還是將keil5的解碼方式改回ANSI。那么又如何能正常顯示從字模軟件里拷貝過來的中文注釋呢,很簡單,只要轉換就好了啊,notepad++就有這個功能。我將拷貝的字模放在新建的文本文檔中,然后用notepad++打開,這時可以看到notepad++中用的是UTF-8編碼,並且能夠正常顯示。
這時我將文件轉為ANSI編碼:
然后再將轉換過后的文字復制進keil5,這時迷惑的事情來了,keil5中顯示的還是一個問號。經過核對之后能保證在notepad++中使用的已經是ANSI編碼了,而且keil5中也是使用ANSI解碼的,但為什么keil5中還是顯示問號呢,肯定是某個環節有問題。這時我做了個實驗,在keil5中將解碼方式設置成了UTF-8,然后再將notepad++中以ANSI編碼的漢字復制進keil5中,發現能正常顯示,這能說明notepad++沒有成功轉碼嗎?既然如此,我們再在notepad++上以UTF-8解碼,發現在notepad++上不能正常顯示中文:
這說明notepad++上的ANSI編碼和keil5上的ANSI解碼不一致???
經過查閱資料后發現尼瑪ANSI真的不是一種統一標准,但他們都會對應一種真實編碼,參考:
https://blog.csdn.net/weixin_30216561/article/details/99139847
而在網上搜“ANSI編碼表”也確實找不到具體的編碼表,這一點也可以佐證ANSI不是一種具體的編碼。但還有一個疑問就是,即使ANSI不是一種具體編碼,但在同一台電腦上那應該是同一種編碼吧。干脆用最直接的方式來驗證,notepadd++和keil5中使用的ANSI編碼到底對應了哪一種真實編碼。我們在notepad++和keil5中打開的文檔中都使用ANSI編碼,並且刪掉所有的內容,只留下一個“撥”字,然后分別保存這兩個文件,接下來用另一個強大的工具,winhex來打開他們,我們發現在keil5中編輯的“撥”字和notepad++中編輯的“撥”字,他們對應的編碼:
都是B2A6………………….(陷入沉思)
並且可以查到,B2A6如果代表的是漢字的“撥”,那么它對應的真實編碼就是GBK編碼:
好吧,這讓我很惆悵,想來想去,發現中間確實有一環是不嚴謹的,之前將notepad++和keil5都設置成ANSI編碼的時候,我是將notepad++中的字復制到keil5中發現顯示問號,這次我是直接在keil5中用鍵盤打出了“撥”這個字,因此我要將notepad++中的“撥”字復制到keil5中去。操作之后,發現在keil5中,真的就顯示成了一個問號,保存keil5中的文件再用winhex查看的時候,發現編碼已經變成3F了,而3F正是ASCLL碼表中的問號。
OK,既然這樣,我將keil5中的“撥”字拷貝到notepad++中會怎樣呢。結果,它變成了這樣:
什么?????keil5中用ANSI編碼的B2A6復制到notepad++中,notepad++也為ANSI編碼,結果卻變成了327C?那么B2A6和327C又有什么聯系呢。為了進一步驗證,我將keil5中的“寒武紀奧陶紀志留紀泥盆紀石炭紀侏羅紀”復制到notepad++中,發現它變成了這樣:
進一步驗證發現keil5中的一個漢字復制到notepad++中並不一定是2個字節對應2個字節,而且變化后的字節以問號居多,而從notepad++中拷貝到keil5中的漢字則全部變成問號。
總之一句話就是“你沒問題,我也沒問題,是復制粘貼這個操作有問題”,而且測試發現使用鍵盤復制和使用鼠標數字是一樣的結果。
經過了半個小時的休息,我想問題仍然在ANSI這種特殊編碼之上,如果我將編碼改為GBK編碼,是不是就好了呢,然鵝keil5中沒有GBK編碼的選項,只有GB2312編碼(這里需要提一下的是,GBK編碼比GB2312編碼收錄了更多的漢字,而且可以認為GB2312編碼是GBK編碼的子集,常用漢字用GB2312編碼就夠夠的了)將keil5中的編碼方式改為GB2312。發現原子的例程中文注釋並沒有亂碼,然后在字模軟件中將字模復制,在nodepad++中粘貼,注意這時notepad++中使用的是UTF-8編碼,然后再轉為ANSI編碼,然后再復制,再到keil5中粘貼,這時,便不再亂碼。更神奇的是,當keil5中使用GB2312編碼時,將取模軟件中的UTF-8編碼的漢字直接復制到keil5中,竟然直接被轉成了GB2312,好吧。。。
雖然問題解決了,但是用ANSI編碼的文件中的漢字不能互相復制粘貼的原因還是沒有找到。