Arduino下LCD1602綜合探究(下)——如何減少1602的連線,LiquidCrystal庫,LiquidCrystal庫中bug的解決方法


本文為大大維原創,最早於博客園發表,轉載請注明出處!!!

 

一、前言:

  上文中,筆者系統的闡述了1602的兩種驅動方式,並簡單的提到了Arduino的LiquidCrystal庫。本文緊接上文,對以下兩個問題進行更加深入的探討:如何能夠使1602對Arduino的端口占用降到最少?LiquidCrystal庫到底應該如何學習?閑話少說,下面開始進入正文。

二、減少1602對Arduino的端口占用

<1>不使用I2C

  在上文中,筆者分別介紹八線和四線驅動的使用方法,給出了兩種接線方式。接線圖分別如下:

  在八線驅動模式下,總共占掉了Arduino 16個端口,四線驅動模式雖然比八線驅動模式少了四個端口,但也達到了驚人的12個。如果實驗只是用於驅動LCD1602還好,但在其他實際應用中,這是不能容忍的。為此,怎么能夠使端口占用達到最少呢?在上面兩張接線圖中,我們使用了兩種電源,+5V的VSS和+3.3V背光。其實,背光完全可以接到+5V,而且亮度還會更高。此為,我們在實際使用操作過程中,RW一般均為低電平寫。沒有什么特殊需求的話可以直接接地。另外,我們如果養成良好的接線習慣,將GND接在一起,這樣,只用占用一個GND端口。由於我們下文要用到Arduino中自帶的示例程序,為了與示例程序的電路連接相符,對相關引腳連線做了一定調整,調整后的連線圖如下:

  可以看到,這種接法下,Arduino端口的占用可以少去很多。尤其在四線驅動模式下,除去GND和+5V,LCD1602獨占的端口只有6個。

<1>使用I2C

  I2C是由以前的PHILIPS(現在的NXP)公司開發的一種通信協議,其目的就是減少芯片之間的連線。在使用了I2C之后,連接到Arduino上的線總共只有四條,獨占的端口只有兩個!!!

 

  但這種模式也有很多限制,羅列如下:

1.使用的LCD1602必須先焊接到LCD1602 I2C模塊

2.I2C模塊的SDA(串行數據)和SCL(串行時鍾)不可以隨便亂接。對於Arduino Uno來說,SDA必須接A4,SCL必須接A5

  盡管有這些限制,但無疑,它的確在很大程度上減少了芯片之間的連線。

  使用I2C需要遵循I2C協議。一般在Arduino中,通過導入LiquidCrystal_I2C庫來完成控制。由於筆者手邊沒有LCD1602 I2C模塊,因此,相關實驗在此略過,等有機會再進行補充。

三、LiquidCrystal庫到底應該如何學習?

  在Arduino IDE中,官方的示例程序足夠讓你完成對LiquidCrystal的學習,如下圖:(所有這些程序的硬件連接與上文的LCD1602四線驅動硬件連接簡化示意圖相同)

 

  此外,筆者分享一個不錯的LiquidCrystal文檔,可以當作LiquidCrystal說明手冊使用。連接如下:

 點擊查看

  當然,你如果想深究,打開Arduino文件夾中的libraries文件夾,找到LiquidCrystal.cpp和頭文件LiquidCrystal.h仔細研究(前提是你有良好的C++基礎)。

四、LiquidCrystal庫中的一個BUG以及相應的解決辦法

  筆者在學習LiquidCrystal庫的過程中,發現一處LiquidCrystal庫中的bug,記錄如下:

<1>BUG描述

  示例程序LiquidCrystal->CustomCharacter無論如何也編譯不過去,即使硬件一點毛病也沒有,編譯也還是報錯。如下圖:

報錯信息如下:

CustomCharacter.ino: In function 'void setup()':
CustomCharacter:119: error: call of overloaded 'write(int)' is ambiguous
E:\Arduino\libraries\LiquidCrystal/LiquidCrystal.h:82: note: candidates are: virtual size_t LiquidCrystal::write(uint8_t)
E:\Arduino\hardware\arduino\cores\arduino/Print.h:49: note:                 size_t Print::write(const char*)

 

error: call of overloaded 'write(int)' is ambiguous

翻譯:write的重載是不明確的。//明顯是由於參數判斷不清楚導致的錯誤。
后面的意思是問題在LiquidCrystal::write(uint8_t)和size_t Print::write(const char*)兩個方法之間。

 

 原文代碼如下:

  1 #include <LiquidCrystal.h>
  2 
  3 #include <LiquidCrystal.h>
  4 
  5 /*
  6   LiquidCrystal Library - Custom Characters
  7  
  8  Demonstrates how to add custom characters on an LCD  display.  
  9  The LiquidCrystal library works with all LCD displays that are 
 10  compatible with the  Hitachi HD44780 driver. There are many of 
 11  them out there, and you can usually tell them by the 16-pin interface.
 12  
 13  This sketch prints "I <heart> Arduino!" and a little dancing man
 14  to the LCD.
 15  
 16   The circuit:
 17  * LCD RS pin to digital pin 12
 18  * LCD Enable pin to digital pin 11
 19  * LCD D4 pin to digital pin 5
 20  * LCD D5 pin to digital pin 4
 21  * LCD D6 pin to digital pin 3
 22  * LCD D7 pin to digital pin 2
 23  * LCD R/W pin to ground
 24  * 10K potentiometer:
 25  * ends to +5V and ground
 26  * wiper to LCD VO pin (pin 3)
 27  * 10K poterntiometer on pin A0
 28  
 29  created21 Mar 2011
 30  by Tom Igoe
 31  Based on Adafruit's example at
 32  https://github.com/adafruit/SPI_VFD/blob/master/examples/createChar/createChar.pde
 33  
 34  This example code is in the public domain.
 35  http://www.arduino.cc/en/Tutorial/LiquidCrystal
 36  
 37  Also useful:
 38  http://icontexto.com/charactercreator/
 39  
 40  */
 41 
 42 // include the library code:
 43 #include <LiquidCrystal.h>
 44 
 45 // initialize the library with the numbers of the interface pins
 46 LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
 47 
 48 // make some custom characters:
 49 byte heart[8] = {
 50   0b00000,
 51   0b01010,
 52   0b11111,
 53   0b11111,
 54   0b11111,
 55   0b01110,
 56   0b00100,
 57   0b00000
 58 };
 59 
 60 byte smiley[8] = {
 61   0b00000,
 62   0b00000,
 63   0b01010,
 64   0b00000,
 65   0b00000,
 66   0b10001,
 67   0b01110,
 68   0b00000
 69 };
 70 
 71 byte frownie[8] = {
 72   0b00000,
 73   0b00000,
 74   0b01010,
 75   0b00000,
 76   0b00000,
 77   0b00000,
 78   0b01110,
 79   0b10001
 80 };
 81 
 82 byte armsDown[8] = {
 83   0b00100,
 84   0b01010,
 85   0b00100,
 86   0b00100,
 87   0b01110,
 88   0b10101,
 89   0b00100,
 90   0b01010
 91 };
 92 
 93 byte armsUp[8] = {
 94   0b00100,
 95   0b01010,
 96   0b00100,
 97   0b10101,
 98   0b01110,
 99   0b00100,
100   0b00100,
101   0b01010
102 };
103 void setup() {
104   // create a new character
105   lcd.createChar(0, heart);//方法2:0改為5 106   // create a new character
107   lcd.createChar(1, smiley);
108   // create a new character
109   lcd.createChar(2, frownie);
110   // create a new character
111   lcd.createChar(3, armsDown);  
112   // create a new character
113   lcd.createChar(4, armsUp);  
114 
115   // set up the lcd's number of columns and rows: 
116   lcd.begin(16, 2);
117   // Print a message to the lcd.
118   lcd.print("I "); 
119   lcd.write(0);//方法一:改作lcd.write(0.0);
            //方法2: 0改為5
120 lcd.print(" Arduino! "); 121 lcd.write(1); 122 123 } 124 125 void loop() { 126 // read the potentiometer on A0: 127 int sensorReading = analogRead(A0); 128 // map the result to 200 - 1000: 129 int delayTime = map(sensorReading, 0, 1023, 200, 1000); 130 // set the cursor to the bottom row, 5th position: 131 lcd.setCursor(4, 1); 132 // draw the little man, arms down: 133 lcd.write(3); 134 delay(delayTime); 135 lcd.setCursor(4, 1); 136 // draw him arms up: 137 lcd.write(4); 138 delay(delayTime); 139 }

 

 筆者通過分析,和多處查閱資料。發現這是一個LiquidCrystal庫中的bug。原因與LiquidCrystal.h中關於unit8_t的定義有關。

<2>BUG的解決辦法

  目前為止,筆者通過自己研究和多方查找資料,發現了三種可行的辦法,分別介紹如下:

  1.將示例程序中119行中的lcd.write(0)改作lcd.write(0.0),在上文的實驗代碼中用紅字已經標注出。

  2.將示例程序中lcd.createChar()函數構造自定義字符時,編碼從1開始,放棄0編碼。即將105行和119行的0改作5。同樣在上文的實驗代碼中用藍字已經標注出。

  3.修改LiquidCrystal.h頭文件。這種方法雖然比較麻煩,但修改徹底,一勞永逸!示例代碼不用修改,實際應用也可直接從0開始編碼,強烈推薦這種方法!!!修改方法如下:

  打開LiquidCrystal.h頭文件,注釋掉第85行的using Print::write。

如下圖所示:(筆者用NotePad++打開):

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM