通過看LCD1602A中文手冊,其實也是一知半解的。
有關於自定義顯示字符的想法,來源於用51、PIC測溫度的時候,想顯示°C發現並沒有對應ASCII碼,那麼對於LCD1602A自然是顯示不了的。但是通過看手冊,我瞭解到‘a'-~'Z','0'~'9'等字符之所以可以這麼方便被LCD顯示,是因爲內部有字符發生器ROM,只讀存儲寄存器,存儲了必要的字符碼。
看自定義產生字符的CGRAM (Character Generate )的相關內容,又看的似懂非懂,好在有熱心老哥的一篇博客,讓我茅塞頓開。鏈接如下:https://blog.csdn.net/ppptalk/article/details/79190426
遺憾的是沒有相關的代碼,故在他的基礎上我實現了相應的代碼。
這裏他的一句話很重要,引用下:
“簡單的講就是先‘填空’, ‘填空’之後就和藍色部分一樣了。
而‘填空’的這個字符可以是任意的,也就是說屬於‘自定義字符’。”
先解釋下8、,也就是通常用到的指令爲
LCD1602cmd(0x80)顯示在2*16的第一行最左邊,
LCD1602cmd(0xC0)顯示在2*16的第二行最左邊。
那麼關於LCD1602的自定義字符其實只有八個,7、裏的000-111選擇八個空間裏某一個進行填充自定義字符碼位置。而則對應於要顯示的字符0-7行號。比如第一行,那麼就要送一個字節(8位)過去,第二行也送一個字節,直至第七行就可以形成自定義的字符。
DB5-DB0即以下表格CG RAM中的b5-b0。
字符字模數據0-4位有用,那麼b7-b5賦0,對應的取模軟件新建的圖像 因爲寬必須是8的倍數,高可以任意,所以不能生成5*7直接對應於LCD的,因爲一個字節8位,所以取模就按上面博客鏈接裏的8*8圖像大小。取模圖如下:
可以看出我的取模是靠右上的,這樣程序編寫出來顯示才正常。
直接上代碼:
來個最終效果圖:
以上是關於自定義生成字符部分。
/***************************************/
有關移位指令,手冊裏有兩種方法,
第一種,一定要寫入要顯示的數據,然後整體才移位。
寫一個才移一位,要想整體左移或右移兩位的話又不要寫入其他不想關的字符數據,就寫入’ ‘空格,反正也看不出來。
實現起來大概也就是這樣子,先設置移位的模式下,至於AC光標移動來移動去,具體再考究。
第二種方法:
只需要 LCD1602Cmd(0x1c);即可。
順便湊湊字數,加入LCD具體初始化,寫數據,寫命令,以及自定義顯示字符串和自定義顯示數字的函數吧。
//定義個全局數組,用以自定義顯示數字用。
有關後續的從LCD1602比如讀取我寫入的字符數據或者ROM裏的數據
然後通過串口發送給電腦。
更新:
發現剛開始自己想當然了,首先字符發生器裏的ROM看手冊是讀不出裏面的數據的,這樣其實這些函數沒什麼必要應用,感覺用途並不大。畢竟只是對程序裏寫的數據重新讀出來。
另外EN使能信號的上升沿可以讀取或者寫入數據進DDRAM或者CGRAM ,給下實現的代碼:
1.
之前對DDRAM不太理解,
現在的理解大概是顯示數據緩存寄存器,直觀上來說相當於一個容器,容量爲80個字節.寫數據LCD1602Data();的時候ROM裏面的各種字形碼不知道什麼原理可以顯示到LCD屏上.....有點難以組織,還是不太明白裏面的講究,存疑,可能看看自定義的CGRAM會理解。
記錄下我對RAM的抽象理解:
RAM相當於一幢大廈,裏面住着不同的用戶,那麼爲了管理利用大廈的空間,每個用戶被分配到相應的樓層,房間,房間門牌號即爲RAM的地址。
那麼之前的CG RAM地址裏的b5 - b3代表某一字形碼,b2-b0代表這一字形碼的行號,所以地址的裏的這些位有複用的感覺,而不只是地址,能解讀出東西的。類似於2105門牌號,意味着21樓層第五個住戶。
樓層代表要顯示出什麼字符,比如’a',第幾個住戶代表這個字符,比如‘a'的第一行。
CGRAM能理解,那關於DDRAM與ROM裏的關聯,還是存疑。
2.同時讀取數據的時候,數據端口DATAPORT 還得賦予0XFF,有點不理解,百度上說
“那麼問題來了,你P0端如果全是低電平他怎麼發送數據,單片機接收的都是全被拉低的數據吧,也就是還是低電平”
爲什麼P0端全是低電平不能發送數據呢?存疑。
當前的猜測是內部LCDP0端口要想某個位輸出1,不能由0變爲1,
而是賦值1若想輸出1就保持1這個狀態,要輸出0就拉低這個位。