{"id":103,"date":"2020-09-04T03:31:05","date_gmt":"2020-09-04T03:31:05","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=103"},"modified":"2021-07-13T23:29:02","modified_gmt":"2021-07-13T23:29:02","slug":"working-with-character-lcds","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=103","title":{"rendered":"Working with Character LCDs"},"content":{"rendered":"\n<p>Character display LCD ares used in so many products we used daily. We can find them in &nbsp;Espresso machines, 3D printers, microwaves &nbsp;and printers and many other products. In this lesson we going to lean how to interface LCD\u2019s to our cortex- microcontroller board. This lessons covers just &nbsp;character display LCD\u2019s there is another lesson covering graphics display LCDs. Th most popular LCD controller currently on the market is the Hitachi HD44780, some other well-known ones include the Tinssharp\/Eon 1602A. The content of this lesson applies to all LCD controllers. Where there is a little difference, it shall be indicated.<\/p>\n\n\n\n<p><strong>LCD Pinout<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/bohobiom.com\/wp-content\/uploads\/2020\/01\/lcd_pinout-750x584-1.png\" alt=\"\" width=\"569\" height=\"442\"\/><\/figure>\n\n\n\n<p><strong>Things to know&nbsp;<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>LCD has&nbsp;<strong>two internal registers<\/strong>; instruction register and data register<\/li><li><strong>RS<\/strong>&nbsp;pin is used for selecting these register-<\/li><\/ul>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -RS = 0 : instruction command code select<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -RS = 1 &nbsp;: data command code select<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -RS &nbsp;=0 allows us to send commands such as clear screen, move cursor etc.<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -RS= 1 &nbsp;allows us to send data to be displayed or retrieve displayed data .<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>R\/W<\/strong>&nbsp;: Allows reading and writing information to LCD<\/li><\/ul>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -R\/W = 1 : reading<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -R\/W = 0 : writing<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>E<\/strong>&nbsp;: E is known as the enable pin. It us used by the LCD to secure information.<\/li><\/ul>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;\u2013 When data is supplied to the data pins a High-Low pulse must be applied &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;to the &nbsp;E pin in order to secure the data.&nbsp;Minimum width of pulse should&nbsp;be &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 230ns for the Hitachi and 140ns for the Tinsharp.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>D0-D7<\/strong>&nbsp;: &nbsp;These are known as the 8-bits data pins. They are used to transfer information to and from the LCDs<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/bohobiom.com\/wp-content\/uploads\/2020\/01\/LCD_Control-1024x579-1.png\" alt=\"\" width=\"751\" height=\"423\"\/><\/figure>\n\n\n\n<p><strong>LCD Pin Groupings&nbsp;<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/bohobiom.com\/wp-content\/uploads\/2020\/01\/LCD_PIN-GROUPS-1024x567-1.png\" alt=\"\" width=\"821\" height=\"454\"\/><\/figure>\n\n\n\n<p><strong>Programming the LCD<\/strong><\/p>\n\n\n\n<p><strong>Sending Commnd&nbsp;<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Set RS =0 to select command register<\/li><li>Send a High-Low pulse to E to secure command<\/li><\/ol>\n\n\n\n<p><strong>Sending Data<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Set RS=1 to select data register<\/li><li>Send a High-Low pulse to E to secure data<\/li><\/ol>\n\n\n\n<p>Two example source codes are presented in this lesson. The first program shows how to interface the LCD with 8-bits data line and the second example show how to interface the LCD with only 4-bits data line. There are &nbsp;also some function for processing characters into strings and performing other auxiliary tasks. Please leave a comment if you have any questions .<\/p>\n\n\n\n<p><strong>Program 1 : LCD 8-bits&nbsp;<\/strong><\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;darcula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;C&lt;br&gt;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;TM4C123.h&quot; \/\/ Device header\nvoid delay_milli(int n);\nvoid delay_micro(int n);\nvoid LCD_init(void);\nvoid LCD_Cmd(unsigned char command);\nvoid LCD_Data(unsigned char data);\nint main(){\nLCD_init();\n\/\/ while(1)\n\/\/ {\nLCD_Cmd(0x01);\nLCD_Cmd(0x80);\ndelay_milli(500);\nLCD_Data('C');\ndelay_milli(1);\nLCD_Data('O');\ndelay_milli(1);\nLCD_Data('R');\ndelay_milli(1);\nLCD_Data('T');\ndelay_milli(1);\nLCD_Data('E');\ndelay_milli(1);\nLCD_Data('X');\ndelay_milli(1);\nLCD_Data('-');\ndelay_milli(1);\nLCD_Data('M');\ndelay_milli(1);\nLCD_Data('.');\ndelay_milli(1);\nLCD_Data('C');\ndelay_milli(1);\nLCD_Data('O');\ndelay_milli(1);\nLCD_Data('M');\ndelay_milli(500);\n\/\/}\n}\nvoid LCD_init(void){\nSYSCTL-&gt;RCGCGPIO |= 0x01; \/\/PORTA clock\nSYSCTL-&gt;RCGCGPIO |= 0x02;\nGPIOA-&gt;DIR |=0xE0; \/\/PORTA controls RS,E and R\/W\nGPIOA-&gt;DEN |=0xE0;\nGPIOB-&gt;DIR |=0xFF; \/\/PORTB D0-D7\nGPIOB-&gt;DEN |=0xFF; \/\/PORTB D0-D7\nLCD_Cmd(0x38); \/\/8-bits,2 display lines, 5x7 font\nLCD_Cmd(0x06); \/\/increments automatically\nLCD_Cmd(0x0F); \/\/Turn on display\nLCD_Cmd(0x01); \/\/clear display\n \n}\n \nvoid LCD_Cmd(unsigned char command)\n{\nGPIOA-&gt;DATA = 0x00; \/\/RS =0, E=0, RW=0\nGPIOB-&gt;DATA =command;\nGPIOA-&gt;DATA =0x80; \/\/E=1 to secure command\ndelay_micro(0);\nGPIOA -&gt;DATA =0x00;\nif(command &lt;4) delay_milli(2); else delay_micro(37); } void LCD_Data(unsigned char data) { GPIOA -&gt;DATA =0x20; \/\/RS=1, E=0,RW=0\nGPIOB-&gt;DATA =data;\nGPIOA-&gt;DATA |= 0x80;\nGPIOA-&gt;DATA =0x00;\ndelay_micro(0);\n \n}\nvoid delay_milli(int n){\nint i,j;\nfor(i=0;i&lt;n;i++)\nfor(j=0;j&lt;3180;j++)\n{}\n}\n \nvoid delay_micro(int n){\nint i,j;\nfor(i=0;i&lt;n;i++)\nfor(j=0;j&lt;3;j++)\n{}\n}<\/pre><\/div>\n\n\n\n<p><strong>Program 2 : LCD 4-bits&nbsp;<\/strong><\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;darcula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;C&lt;br&gt;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;TM4C123.h&quot; \/\/ Device header\n \n#define LCD_CTRLP GPIOA\n#define LCD_DATAP GPIOB\n#define RS 0x20 \/* PORTA BIT5 mask *\/\n#define RW 0x40 \/* PORTA BIT6 mask *\/\n#define EN 0x80 \/* PORTA BIT7 mask *\/\n#define HIGH 1\n#define LOW 0\n \nvoid delay_milli(int n);\nvoid delay_micro(int n);\nvoid LCD_init(void);\nvoid LCD4bit_Cmd(unsigned char command);\nvoid LCD4bit_Data(unsigned char data);\n \nint main()\n{\n LCD_init();\n LCD4bit_Cmd(0x01);\n LCD4bit_Cmd(0x80);\n delay_milli(500);\n \n LCD4bit_Data('a');\n delay_micro(20);\n\/\/ LCD4bit_Data('E');\n delay_milli(500);\n\/\/ \n \n}\n \nvoid LCD_init(void)\n{\n SYSCTL-&gt;RCGCGPIO |=0x01;\n SYSCTL-&gt;RCGCGPIO |=0x02;\n LCD_DATAP -&gt;DIR |=0xF0;\n LCD_DATAP -&gt;DEN |=0xF0;\n LCD_CTRLP -&gt;DIR |=0xF0;\n LCD_CTRLP -&gt;DEN |=0xF0;\n \n LCD4bit_Cmd(0x20);\n LCD4bit_Cmd(0x28);\n LCD4bit_Cmd(0x06);\n LCD4bit_Cmd(0x01);\n LCD4bit_Cmd(0x0F);\n \n \/\/..\n \/\/...\n}\nvoid LCD4bit_Data(unsigned char data)\n{\n unsigned char temp;\n LCD_CTRLP-&gt;DATA = RS;\n temp = data;\n temp = temp&gt;&gt;4;\n LCD_DATAP-&gt;DATA = temp;\n LCD_CTRLP-&gt;DATA = RS |EN;\n delay_micro(10);\n LCD_CTRLP-&gt;DATA =RS;\n delay_micro(37);\n \n temp =data;\n \/\/LCD_CTRLP-&gt;DATA = RS;\n LCD_DATAP-&gt;DATA = temp;\n LCD_DATAP-&gt;DATA = RS |EN;\n delay_micro(10);\n LCD_CTRLP-&gt;DATA =0x00;\n delay_micro(37);\n \n}\n \nvoid LCD4bit_Cmd(unsigned char command)\n{\n unsigned char temp;\n LCD_CTRLP-&gt;DATA = 0x00;\n temp = command;\n temp = temp&gt;&gt;4;\n LCD_DATAP-&gt;DATA =temp;\n LCD_CTRLP-&gt;DATA = EN;\n delay_micro(0);\n LCD_CTRLP-&gt;DATA = 0x00;\n if(command &lt; 4) delay_milli(2); else delay_micro(37); temp = command; LCD_DATAP-&gt;DATA =temp;\n LCD_CTRLP-&gt;DATA = EN;\n delay_micro(0);\n LCD_CTRLP-&gt;DATA =0x00;\n \n}\n \nvoid delay_milli(int n)\n{\n int i,j;\n for(i=0;i&lt;n;i++)\n for(j=0;j&lt;3180;j++)\n {}\n}\n \nvoid delay_micro(int n)\n{\n int i,j;\n for(i=0;i&lt;n;i++)\n for(j=0;j&lt;3;j++)\n {}\n \n}<\/pre><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Character display LCD ares used in so many products we used daily. We can find them in &nbsp;Espresso machines, 3D printers, microwaves &nbsp;and printers and many other products. In this lesson we going to lean how to interface LCD\u2019s to our cortex- microcontroller board. This lessons covers just &nbsp;character display LCD\u2019s there is another lesson [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[19,11,17],"tags":[18,10,16],"class_list":["post-103","post","type-post","status-publish","format-standard","hentry","category-lcd","category-peripheral-drivers","category-tm4c123","tag-lcd","tag-peripheral-drivers","tag-tm4c123"],"_links":{"self":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/103"}],"collection":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=103"}],"version-history":[{"count":3,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/103\/revisions"}],"predecessor-version":[{"id":197,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/103\/revisions\/197"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=103"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=103"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=103"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}