{"id":238,"date":"2017-05-02T20:19:29","date_gmt":"2017-05-02T20:19:29","guid":{"rendered":"https:\/\/daqdesign.wordpress.com\/?p=238"},"modified":"2024-10-23T14:56:09","modified_gmt":"2024-10-23T14:56:09","slug":"hitachi-hd44780-lcd-character-display","status":"publish","type":"post","link":"https:\/\/daq-design.co.uk\/blog\/?p=238","title":{"rendered":"Hitachi HD44780 LCD Character Display"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">I finally got round to writing my own &#8216;Hello World!&#8217; for an LCD connected to an Arduino Nano. So what! I hear you all cry. Well, I wanted to do it <strong>without<\/strong> the Arduino LCD library. Why? Well, it&#8217;s a challenge isn&#8217;t it!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">First off, the following PDFs are invaluable in understanding the controller on the majority of the LCD on the market utilising the ubiquitous Hitachi HD44780 controller.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"http:\/\/lcd-linux.sourceforge.net\/pdfdocs\/lcd1.pdf\">LCD Controller part 1<\/a><br><a href=\"http:\/\/lcd-linux.sourceforge.net\/pdfdocs\/lcd2.pdf\">LCD Controller part 2<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Oh, in 4-bit mode only!<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define LCD_ENABLE (0x00 &lt;&lt; 2)\n#define LCD_CLEAR (0x01 &lt;&lt; 2)\n#define LCD_HOME (0x02 &lt;&lt; 2)\n#define LCD_DISP_ON_UNDERLINE_BLINK (0x0f &lt;>2)\n#define LCD_8BITMODE (0x30 >>2)\n#define LCD_RESET 0x38\n\n#define LCD_RS_COMMAND_MODE 0x00\n#define LCD_RS_DATA_MODE 0x01\n\nint RS=A0;\nint RW=A1;\nint ENABLE=A2;\n\nvoid setup()\n{\ndelay(100); \/\/ power on delay\nDDRD=B11111100; \/\/ set bits on D2-D7 as outputs\nPORTD=0;\n\npinMode (ENABLE,OUTPUT);\npinMode (RW,OUTPUT);\npinMode (RS,OUTPUT);\ndigitalWrite (RW,LOW);\n\n}\n\n<\/code><\/pre>\n\n\n\n<p class=\"is-style-plain wp-block-paragraph\">wire D2 to LCD D4<br>wire D3 to LCD D5<br>wire D4 to LCD D6<br>wire D5 to LCD D7<br>wire A2 to LCD Enable pin<br>wire A1 to LCD R\/W pin<br>wire A0 to LCD RS pin<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The basic sequence of operation is as follows:<br>Once the LCD had powered on the init sequence should be:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>set the read\/write line permanently low to write as we won&#8217;t be reading from the display &#8211; or tie to 0V<\/li>\n\n\n\n<li>set command mode (RS pin) (logic 0)<\/li>\n\n\n\n<li>set 8 bit mode X 3<\/li>\n\n\n\n<li>set the data lines;<\/li>\n\n\n\n<li>pulse the enable line (high to low transition and back to low again<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>\n#define LCD_ENABLE (0x00 &lt;&lt; 2)\n#define LCD_CLEAR  (0x01 &lt;&lt; 2)\n#define LCD_HOME   (0x02 &lt;&lt; 2)\n#define LCD_DISP_ON_UNDERLINE_BLINK (0x0f &lt;&gt;2)\n#define LCD_8BITMODE (0x30 &gt;&gt;2)\n#define LCD_RESET 0x38\n#define LCD_RS_COMMAND_MODE 0x00\n#define LCD_RS_DATA_MODE 0x01\nint RS=A0;\nint RW=A1;\nint ENABLE=A2;\nvoid setup()\n{\n delay(100); \/\/ power on delay\n DDRD=B11111100; \/\/ set bits on D2-D7 as outputs\n PORTD=0;\n pinMode (ENABLE,OUTPUT);\n pinMode (RW,OUTPUT);\n pinMode (RS,OUTPUT);\n digitalWrite (RW,LOW);\n}\n\nwire D2 to LCD D4\nwire D3 to LCD D5\nwire D4 to LCD D6\nwire D5 to LCD D7\nwire A2 to LCD Enable pin\nwire A1 to LCD R\/W pin\nwire A0 to LCD RS pin\nThe basic sequence of operation is as follows:\nOnce the LCD had powered on the init sequence should be:\nset the read\/write line permanently low to write as we won't be reading from the display - or tie to 0V\nset command mode (RS pin) (logic 0)\nset 8 bit mode X 3\nset the data lines;\npulse the enable line (high to low transition and back to low again\n\nvoid hd44780_init() \/\/ it's recommended that the 8-bit mode be sent 3 times to ensure full initialisation of the LCD controller\n{\n  for (int poweron=0; poweron&lt;3; poweron++)\n   {\n    digitalWrite(RS,LCD_RS_COMMAND_MODE); \/\/ switch LCD into COMMAND_MODE\n    PORTD=LCD_8BITMODE;\n    pulse(); \n    }\n}\nvoid init_4bitmode()\n{\n  delay(5);\n  digitalWrite(RS,LCD_RS_COMMAND_MODE);\n  PORTD=LCD_4BITMODE;\n  delay(5);\n  pulse();\n}\nvoid lcd_clear()\n{\n  digitalWrite(RS,LCD_RS_COMMAND_MODE);\n  PORTD=(0 &lt;&lt;2);\n  pulse();\n  PORTD=(1 &lt;&lt;2);\n  pulse();\n  delay(200);\n}\nvoid lcd_2linemode()\n{\n  digitalWrite(RS,LCD_RS_COMMAND_MODE);\n  PORTD=(2 &lt;&lt;2);\n  pulse();\n  PORTD=(8 &lt;&lt;2);\n  pulse();\n}\nvoid lcd_displayon() \/\/ also cursor underline and blink\n{\n  digitalWrite(RS,LCD_RS_COMMAND_MODE);\n  PORTD=(0 &lt;&lt;2);\n  pulse();\n  PORTD=(0xf &lt;&lt;2);\n  pulse();\n}\nvoid pulse()\n{\n  digitalWrite(ENABLE,HIGH);\n  delayMicroseconds(40);\n  digitalWrite(ENABLE,LOW);\n  delayMicroseconds(40);\n}\nvoid lcd_print_char(char *nextchar)\n{\ndigitalWrite(RS,LCD_RS_DATA_MODE);\n  while (*nextchar !='\\0')\n   {\n    char lower=(*nextchar &amp; 0x0f);\n    char upper=(*nextchar &gt;&gt; 4) &amp;0x0f;\n    char shiftup=(upper &lt;&lt; 2);\n    char shiftlow=(lower &lt;&lt; 2);\n    PORTD=shiftup;\n    delay(5);\n    pulse();\n    PORTD=shiftlow;\n    delay(5);\n    pulse();\n    nextchar++;\n   }\n}\nvoid loop()\n{\nhd44780_init();  \/\/ post power-on-reset send 8 bit mode three times to ensure reset\ninit_4bitmode(); \/\/ now switch to 4-bit mode\nlcd_clear();     \/\/ clear the display and set cursor position to home\nlcd_2linemode(); \/\/ set two line mode for the 2X16 HD44780 DEM controller\nlcd_displayon(); \/\/ finally, turn the LCD's display on so we can see this!!!!\nlcd_print_char(\"Hello World!\");\nwhile (1==1)\n {\n }\n}<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>I finally got round to writing my own &#8216;Hello World!&#8217; for an LCD connected to an Arduino Nano. So what! I hear you all cry. Well, I wanted to do it without the Arduino LCD library. Why? Well, it&#8217;s a &hellip; <a href=\"https:\/\/daq-design.co.uk\/blog\/?p=238\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-238","post","type-post","status-publish","format-standard","hentry","category-arduino"],"_links":{"self":[{"href":"https:\/\/daq-design.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/238","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/daq-design.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/daq-design.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/daq-design.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/daq-design.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=238"}],"version-history":[{"count":7,"href":"https:\/\/daq-design.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/238\/revisions"}],"predecessor-version":[{"id":445,"href":"https:\/\/daq-design.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/238\/revisions\/445"}],"wp:attachment":[{"href":"https:\/\/daq-design.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=238"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/daq-design.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=238"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/daq-design.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=238"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}