{"id":600,"date":"2021-11-29T05:35:16","date_gmt":"2021-11-29T05:35:16","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=600"},"modified":"2021-11-29T05:35:19","modified_gmt":"2021-11-29T05:35:19","slug":"working-with-stm32-and-liquid-crystal-display-4-bit-mode","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=600","title":{"rendered":"Working with STM32 and Liquid Crystal display: 4-bit mode"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"768\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/11\/IMG_7258-1024x768.jpg\" alt=\"\" class=\"wp-image-602\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/11\/IMG_7258-1024x768.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/11\/IMG_7258-300x225.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/11\/IMG_7258-768x576.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/11\/IMG_7258-1536x1152.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/11\/IMG_7258-2048x1536.jpg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/11\/IMG_7258-1150x863.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/11\/IMG_7258-750x563.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/11\/IMG_7258-400x300.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/11\/IMG_7258-250x188.jpg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>In this guide, we shall see how to use alphanumeric display.<\/p>\n\n\n\n<p>In this guide, we shall cover the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Liquid Crystal display <\/li><li>Initializing sequence<\/li><li>Parts and connection<\/li><li>Code<\/li><li>Demo<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">1. Liquid Crystal Display <\/h2>\n\n\n\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<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/bohobiom.com\/wp-content\/uploads\/2020\/01\/lcd_pinout-750x584-1.png\" alt=\"\" \/><\/figure><\/div>\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\"><img decoding=\"async\" src=\"https:\/\/bohobiom.com\/wp-content\/uploads\/2020\/01\/LCD_Control-1024x579-1.png\" alt=\"\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">2. Initializing Sequence:<\/h2>\n\n\n\n<p>In order to Initialize the LCD, the following is steps is required<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Send 0x01 command<\/li><li>Wait for 1millisecond<\/li><li>Send 0x02 command<\/li><li>Wait for 1 millisecond<\/li><li>Send 0x28 command<\/li><li>Wait for 4 milliseconds<\/li><li>Send 0x06 command<\/li><li>wait for 1 millisecond<\/li><li>Send 0x0c command<\/li><li>wait for 1 millisecond<\/li><li>Send 0x80 command<\/li><li>wait for 4 milliseconds<\/li><\/ul>\n\n\n\n<p>it takes about 100 milliseconds to initialize the lcd<\/p>\n\n\n\n<p>In order to send either data or command, we need to send those data as set of 2 4-bit command using nibble method. <\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. Required parts and connection:<\/h2>\n\n\n\n<p>In this guide, we need the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>STM32F446RE Nucleo-64<\/li><li>Liquid Crystal display 20 character by 4 lines<\/li><li>1KOhm potentiometer <\/li><li>Hook-up wires<\/li><\/ul>\n\n\n\n<p>The connection shall be as the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>RS pin to PB5<\/li><li>R\/W pin to GND<\/li><li>EN pin to PB7<\/li><li>D4 to D7 from PC4 to PC7<\/li><\/ul>\n\n\n\n<p>Figure below shows the connection for the LCD using STM32F446RE Nucleo-64<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"730\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/11\/Screen-Shot-2021-11-29-at-7.51.41-AM-1024x730.png\" alt=\"\" class=\"wp-image-604\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/11\/Screen-Shot-2021-11-29-at-7.51.41-AM-1024x730.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/11\/Screen-Shot-2021-11-29-at-7.51.41-AM-300x214.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/11\/Screen-Shot-2021-11-29-at-7.51.41-AM-768x548.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/11\/Screen-Shot-2021-11-29-at-7.51.41-AM-1536x1095.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/11\/Screen-Shot-2021-11-29-at-7.51.41-AM-2048x1460.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/11\/Screen-Shot-2021-11-29-at-7.51.41-AM-1150x820.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/11\/Screen-Shot-2021-11-29-at-7.51.41-AM-750x535.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/11\/Screen-Shot-2021-11-29-at-7.51.41-AM-400x285.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/11\/Screen-Shot-2021-11-29-at-7.51.41-AM-250x178.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">4. Code:<\/h2>\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;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\/\/interface hitachi lcd with stm32 using bare metal\n\/\/PC4 through PC7 for 4-bit data line\n\n\/\/PB5 as RS pin\n\/\/PB7 as enable pin\n\/\/-----------------------\n#define RS 0x20\n#define RW 0x40\n#define EN 0x80\n\n\/\/ commands\n#define LCD_CLEARDISPLAY 0x01\n#define LCD_RETURNHOME 0x02\n#define LCD_ENTRYMODESET 0x04\n#define LCD_DISPLAYCONTROL 0x08\n#define LCD_CURSORSHIFT 0x10\n#define LCD_FUNCTIONSET 0x20\n#define LCD_SETCGRAMADDR 0x40\n#define LCD_SETDDRAMADDR 0x80\n\n\/\/ flags for display entry mode\n#define LCD_ENTRYRIGHT 0x00\n#define LCD_ENTRYLEFT 0x02\n#define LCD_ENTRYSHIFTINCREMENT 0x01\n#define LCD_ENTRYSHIFTDECREMENT 0x00\n\n\/\/ flags for display on\/off control\n#define LCD_DISPLAYON 0x04\n#define LCD_DISPLAYOFF 0x00\n#define LCD_CURSORON 0x02\n#define LCD_CURSOROFF 0x00\n#define LCD_BLINKON 0x01\n#define LCD_BLINKOFF 0x00\n\n\/\/ flags for display\/cursor shift\n#define LCD_DISPLAYMOVE 0x08\n#define LCD_CURSORMOVE 0x00\n#define LCD_MOVERIGHT 0x04\n#define LCD_MOVELEFT 0x00\n\n\/\/ flags for function set\n#define LCD_8BITMODE 0x10\n#define LCD_4BITMODE 0x00\n#define LCD_2LINE 0x08\n#define LCD_1LINE 0x00\n#define LCD_5x10DOTS 0x04\n#define LCD_5x8DOTS 0x00\n\/\/-------------\n#include &quot;stm32f4xx.h&quot;                  \/\/ Device header\n#include &quot;stdio.h&quot;\n\/\/#include &quot;String&quot;\nvoid delay(int delayms);\nvoid LCD_init(void);\nvoid GPIO_init(void);\nvoid display(void);\nvoid lcd_com(unsigned char c);\nvoid lcd_data(char c);\nvoid setCursor(int a, int b);\nvoid setRowOffsets(int row0, int row1, int row2, int row3);\nvoid LCD_Disp( char *p);\nvoid lcd_nibble_write(char data, unsigned char control);\n\/\/--------\nunsigned int _displayfunction;\nunsigned int _displaycontrol;\nunsigned int _displaymode;\nunsigned int _initialized;\nunsigned int _numlines;\nunsigned int _row_offsets[4];\nunsigned long seconds=0;\nchar str[10000];\nvoid delay(int ms);\nvoid LCD_init(void);\n\nint main(void)\n{\n\ndelay(500);\nGPIO_init();\nLCD_init();\t\ndelay(100);\n\t\nsetCursor(7,0);LCD_Disp(&quot;STM32&quot;);\nsetCursor(0,1);LCD_Disp(&quot;EmbeddedExpert.io&quot;);\nsetCursor(7,2);LCD_Disp(&quot;LCD20x4&quot;);\n\n\twhile(1)\n{\nsprintf(str,&quot;%lu&quot;,seconds);\nseconds++;\nsetCursor(0,3);LCD_Disp(str);\t\ndelay(1000);\n}\n}\n\n\/\/initialize the lcd\nvoid LCD_init(void)\n{\n\nlcd_com(0x01);\ndelay(1);\nlcd_com(0x02);\ndelay(1);\nlcd_com(0x28);\ndelay(4);\nlcd_com(0x06);\ndelay(1);\nlcd_com(4);\ndelay(1);\nlcd_com(0x80);\ndelay(4);\n}\n\/\/initialize the gpio pins for the lcd\nvoid GPIO_init(void){\nRCC-&gt;AHB1ENR=RCC_AHB1ENR_GPIOBEN|RCC_AHB1ENR_GPIOCEN;\nGPIOB-&gt;MODER|=GPIO_MODER_MODER5_0|GPIO_MODER_MODER7_0;\nGPIOB-&gt;BSRR=(RS&lt;&lt;16)|(EN&lt;&lt;16);;\nGPIOC-&gt;MODER|=GPIO_MODER_MODER4_0|GPIO_MODER_MODER5_0|GPIO_MODER_MODER6_0|GPIO_MODER_MODER7_0;\n}\nvoid lcd_nibble_write(char data, unsigned char control)\n{\nGPIOC-&gt;BSRR|=0x00F00000; \/\/clear data pins\nGPIOC-&gt;BSRR=data&amp;0xF0;\nif(control &amp;RS)\n{\nGPIOB-&gt;BSRR=RS;\n}\nelse{GPIOB-&gt;BSRR=RS&lt;&lt;16;}\n\nGPIOB-&gt;BSRR=EN;\ndelay(0);\nGPIOB-&gt;BSRR=(EN&lt;&lt;16);\ndelay(0);\n}\n\nvoid delay(int ms)\n{\n\tSysTick-&gt;LOAD=16000-1;\n\tSysTick-&gt;VAL=0;\n\tSysTick-&gt;CTRL=0x5;\n\t\tfor (int i=0;i&lt;ms;i++)\n\t\t{\n\t\t\twhile(!(SysTick-&gt;CTRL &amp;0x10000)){}\n\t\t}\n\tSysTick-&gt;CTRL=0;\n}\n\/\/lcd commands\nvoid lcd_com(unsigned char c)\n\t{\nlcd_nibble_write(c&amp;0xF0,0); \/\/upper data\nlcd_nibble_write(c&lt;&lt;4,0); \/\/lower data\nif(c&lt;4){delay(2);}\nelse{delay(1);}\n}\n\/\/ send command to the lcd\nvoid lcd_data(char c)\n\t{\nlcd_nibble_write(c&amp;0xF0,RS);\nlcd_nibble_write(c&lt;&lt;4,RS);\ndelay(1);\n}\n\nvoid setCursor(int a, int b)\n{\n\tint i=0;\n\tswitch(b){\n\tcase 0:lcd_com(0x80);break;\n\tcase 1:lcd_com(0xC0);break;\n\tcase 2:lcd_com(0x94);break;\n\tcase 3:lcd_com(0xd4);break;}\n\tfor(i=0;i&lt;a;i++)\n\tlcd_com(0x14);\n}\nvoid LCD_Disp( char *p)\n{\n\twhile(*p!='\\0')\n\t{\n\t\tlcd_data(*p);\n\t\tp++; delay(1);\n\t}\n}<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">5. Demo<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-video\"><video src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/11\/IMG_7259.mp4\"><\/video><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>In this guide, we shall see how to use alphanumeric display. In this guide, we shall cover the following: Liquid Crystal display Initializing sequence Parts and connection Code Demo 1. Liquid Crystal Display Character display LCD ares used in so many products we used daily. We can find them in &nbsp;Espresso machines, 3D printers, microwaves [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,19,11,12],"tags":[],"class_list":["post-600","post","type-post","status-publish","format-standard","hentry","category-embedded-systems","category-lcd","category-peripheral-drivers","category-stm32"],"_links":{"self":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/600"}],"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\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=600"}],"version-history":[{"count":2,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/600\/revisions"}],"predecessor-version":[{"id":606,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/600\/revisions\/606"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=600"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=600"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=600"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}