Line 327: Line 327:
 
===Schematic===
 
===Schematic===
 
[[File:8051 LCD8BIT Interface.PNG|Fig 3: Schematic LCD 8 bit mode]]  
 
[[File:8051 LCD8BIT Interface.PNG|Fig 3: Schematic LCD 8 bit mode]]  
===Code===
+
==Code==
==The main file main.c===
+
===The main file main.c===
 
<syntaxhighlight>
 
<syntaxhighlight>
 
/* Reg51.h contains the defnition of all ports and SFRs */
 
/* Reg51.h contains the defnition of all ports and SFRs */
Line 355: Line 355:
  
 
===lcd_8_bit.c: 8 bit lcd library file===
 
===lcd_8_bit.c: 8 bit lcd library file===
{{scroll box|text=
+
{{scroll box|width=150px|height=800px|text=
 
<syntaxhighlight>
 
<syntaxhighlight>
 
#include<reg51.h>
 
#include<reg51.h>

Revision as of 16:21, 21 December 2013


Introduction:LCD

Liquid Crystal Display(LCDs) provide a cost effective way to put a text output unit for a microcontroller. As we have seen in the previous tutorial, LEDs or 7 Segments do no have the flexibility to display informative messages. This display has 2 lines and can display 16 characters on each line. Nonetheless, when it is interfaced with the micrcontroller, we can scroll the messages with software to display information which is more than 16 characters in length.

LCD Internal Controller

Fig 1: LCD Block diagram


The LCD is a simple device to use but the internal details are complex. Most of the 16x2 LCDs use a Hitachi HD44780 or a compatible controller. Yes, a micrcontroller is present inside a Liquid crystal display as shown in figure 1.

The Display Controller takes commands and data from a external microcontroller and drivers the LCD panel(LCDP). It takes a ASCII value as input and generate a patter for the dot matrix. E.g., to display letter 'A', it takes its value 0X41(hex) or 65(dec) decodes it into a dot matrix of 5x8 as shown in figure 2.

Basic Commands

The LCD controller uses RS and RW lines along with E to operate the LCD.

  • Resister Select (RS): Determines weather a command(RS = 0) is sent (to set up the display) or actual data(RS=1) is sent.
  • Read/Write RW=0; writes to the LCD. RW=1;Reads from the LCD.

The commonly used instructions are shown in the instruction set below. Observe the Bit names: I/D, S, D, C etc at the bottom of instruction set to decode the instructions completely.

  • Clear Display
  • Cursor Home
  • Set Entry Mode
  • Display on/off control
  • Cursor/display shift
  • Function Set
  • Read Busy Flag
  • Data Read
  • Data Write

Instruction Set

HD44780U based instruction set
Instruction Code Description
RS R/W B7 B6 B5 B4 B3 B2 B1 B0
Clear display 0 0 0 0 0 0 0 0 0 1 Clears display and returns cursor to the home position (address 0).
Cursor home 0 0 0 0 0 0 0 0 1 * Returns cursor to home position. Also returns display being shifted to the original position. DDRAM content remains unchanged.


Entry mode set 0 0 0 0 0 0 0 1 I/D S Sets cursor move direction (I/D); specifies to shift the display (S). These operations are performed during data read/write.


Display on/off control 0 0 0 0 0 0 1 D C B Sets on/off of all display (D), cursor on/off (C), and blink of cursor position character (B).


Cursor/display shift 0 0 0 0 0 1 S/C R/L * * Sets cursor-move or display-shift (S/C), shift direction (R/L). DDRAM content remains unchanged.


Function set 0 0 0 0 1 DL N F * * Sets interface data length (DL), number of display line (N), and character font (F).
Read busy flag &
address counter
0 1 BF CGRAM/DDRAM address Reads busy flag (BF) indicating internal operation being performed and reads CGRAM or DDRAM address counter contents (depending on previous instruction).
Write CGRAM or
DDRAM
1 0 Write Data Write data to CGRAM or DDRAM.
Write CGRAM or
DDRAM
1 0 Write Data Write data to CGRAM or DDRAM.
Instruction bit names —

I/D - 0 = decrement cursor position, 1 = increment cursor position;

S - 0 = no display shift, 1 = display shift;
D - 0 = display off, 1 = display on;
C - 0 = cursor off, 1 = cursor on;
B - 0 = cursor blink off, 1 = cursor blink on ;
S/C - 0 = move cursor, 1 = shift display;
R/L - 0 = shift left, 1 = shift right;
DL - 0 = 4-bit interface, 1 = 8-bit interface;
N - 0 = 1/8 or 1/11 duty (1 line), 1 = 1/16 duty (2 lines);
F - 0 = 5×8 dots, 1 = 5×10 dots;
BF - 0 = can accept instruction, 1 = internal operation in progress.

LCD UNIT

Fig2: LCD_turn_on

Let us look at a pin diagram of a commercially available LCD like JHD162 which uses a HD44780 controller and then describe its operation. All the pins are identically to the lcd internal controller discussed above







PIN NUMBER FUNCTION
1 Ground
2 VCC
3 Contrast adjustment (VO)
4 Register Select (RS). RS=0: Command, RS=1: Data
5 Read/Write (R/W). R/W=0: Write, R/W=1: Read
6 Clock (Enable). Falling edge triggered
7 Bit 0 (Not used in 4-bit operation)
8 Bit 1 (Not used in 4-bit operation)
9 Bit 2 (Not used in 4-bit operation)
10 Bit 3 (Not used in 4-bit operation)
11 Bit 4
12 Bit 5
13 Bit 6
14 Bit 7
15 Back-light Anode(+)
16 Back-Light Cathode(-)





Interfacing LCD with 8051

LCD can be interfaced with the 8051 micrcontroller in two modes, 8 bit and 4 bit. Let us Interface it in 8 bit mode first.

8 bit Mode

Schematic

Fig 3: Schematic LCD 8 bit mode

Code

The main file main.c

  1. /* Reg51.h contains the defnition of all ports and SFRs */
  2. #include <reg51.h>
  3.  
  4. #include "lcd.h" //Xplore labz LCD library
  5. #include "delay.h" //Xplore Labz Delay library
  6.  
  7. /* start the main program */
  8. void main()
  9. {
  10.  
  11. /* Initilize the lcd before displaying any thing on the lcd */
  12. LCD_Init();
  13.  
  14. /* Display "hello, world" on first line*/
  15. LCD_DisplayString("hello, world");
  16.  
  17. /*Go to second line and display "good morning" */
  18. LCD_GoToLineTwo();
  19. LCD_DisplayString("good morning");
  20.  
  21. while(1);
  22. }

lcd_8_bit.c: 8 bit lcd library file

  1. #include<reg51.h>
  2. #include "delay.h"
  3. #include "lcd.h"
  4.  
  5. #define databus P2 // LCD databus connected to PORT2
  6.  
  7. sbit rs= P0^0; // Register select pin connected to P0.0
  8. sbit rw= P0^1; // Read Write pin connected to P0.1
  9. sbit en= P0^2; // Enable pin connected to P0.2
  10.  
  11.  
  12. /* 16x2 LCD Specification */
  13. #define LCDMaxLines 2
  14. #define LCDMaxChars 16
  15. #define LineOne 0x80
  16. #define LineTwo 0xc0
  17.  
  18. #define BlankSpace ' '
  19.  
  20.  
  21. /*---------------------------------------------------------------------------------
  22. void LCD_Init()
  23. ----------------------------------------------------------------------------------
  24. * Function name: LCD_Init()
  25. * I/P Arguments: none.
  26. * Return value : none
  27.  
  28. * description  :This function is used to initialize the lcd in 8-bit mode
  29.  
  30. -----------------------------------------------------------------------------------*/
  31. void LCD_Init()
  32. {
  33. delay_us(5000);
  34. LCD_CmdWrite(0x38); // LCD 2lines, 5*7 matrix
  35. LCD_CmdWrite(0x0E); // Display ON cursor ON Blinking off
  36. LCD_CmdWrite(0x01); // Clear the LCD
  37. LCD_CmdWrite(0x80); // Move the Cursor to First line First Position
  38.  
  39. }
  40.  
  41.  
  42.  
  43.  
  44. /*---------------------------------------------------------------------------------
  45. void LCD_Clear()
  46. ----------------------------------------------------------------------------------
  47. * I/P Arguments: none.
  48. * Return value : none
  49.  
  50. * description  :This function clears the LCD and moves the cursor to first Position
  51.  
  52. -----------------------------------------------------------------------------------*/
  53. void LCD_Clear()
  54. {
  55. LCD_CmdWrite(0x01); // Clear the LCD and go to First line First Position
  56. LCD_CmdWrite(LineOne);
  57. }
  58.  
  59.  
  60.  
  61.  
  62.  
  63. /*---------------------------------------------------------------------------------
  64. void LCD_GoToLineOne()
  65. ----------------------------------------------------------------------------------
  66. * I/P Arguments: none.
  67. * Return value : none
  68.  
  69. * description  :This function moves the Cursor to First line First Position
  70.  
  71. -----------------------------------------------------------------------------------*/
  72. void LCD_GoToLineOne()
  73. {
  74. LCD_CmdWrite(LineOne); // Move the Cursor to First line First Position
  75. }
  76.  
  77.  
  78.  
  79.  
  80. /*---------------------------------------------------------------------------------
  81. void LCD_GoToLineTwo()
  82. ----------------------------------------------------------------------------------
  83. * I/P Arguments: none.
  84. * Return value : none
  85.  
  86. * description  :This function moves the Cursor to Second line First Position
  87.  
  88. -----------------------------------------------------------------------------------*/
  89. void LCD_GoToLineTwo()
  90. {
  91. LCD_CmdWrite(LineTwo); // Move the Cursor to Second line First Position
  92. }
  93.  
  94.  
  95.  
  96.  
  97. /*---------------------------------------------------------------------------------
  98. void LCD_GoToXY(char row,char col)
  99. ----------------------------------------------------------------------------------
  100. * I/P Arguments: char row,char col
  101. row -> line number(line1=0, line2=1),
  102. For 2line LCD the I/P argument should be either 0 or 1.
  103. col -> char number.
  104. For 16-char LCD the I/P argument should be betwen 0-15.
  105. * Return value : none
  106.  
  107. * description  :This function moves the Cursor to specified position
  108.  
  109. -----------------------------------------------------------------------------------*/
  110. void LCD_GoToXY(char row, char col)
  111. {
  112. char pos;
  113.  
  114. if(row<LCDMaxLines)
  115. {
  116. pos= LineOne | (row << 6); // take the line number
  117. //row0->pos=0x80 row1->pos=0xc0
  118.  
  119. if(col<LCDMaxChars)
  120. pos= pos+col; //take the char number
  121. //now pos points to the given XY pos
  122.  
  123. LCD_CmdWrite(pos); // Move the Cursor to specified Position
  124. }
  125. }
  126.  
  127.  
  128.  
  129.  
  130.  
  131.  
  132.  
  133. /*---------------------------------------------------------------------------------
  134. void LCD_CmdWrite( char cmd)
  135. * ---------------------------------------------------------------------------------
  136. * I/P Arguments: 8-bit command supported by LCD.
  137. * Return value : none
  138.  
  139. * description :This function sends a command to LCD in the following steps.
  140. step1: Send the I/P command to LCD.
  141. step2: Select the Control Register by making RS low.
  142. step3: Select Write operation making RW low.
  143. step4: Send a High-to-Low pulse on Enable PIN with some delay_us.
  144. ----------------------------------------------------------------------------------*/
  145. void LCD_CmdWrite( char cmd)
  146. {
  147.  
  148. databus=cmd; // Send the command to LCD
  149. rs=0; // Select the Command Register by pulling RS LOW
  150. rw=0; // Select the Write Operation by pulling RW LOW
  151. en=1; // Send a High-to-Low Pusle at Enable Pin
  152. delay_us(10);
  153. en=0;
  154.  
  155. delay_ms(1);
  156. }
  157.  
  158.  
  159.  
  160.  
  161.  
  162. /*---------------------------------------------------------------------------------
  163. void LCD_DataWrite( char dat)
  164. ----------------------------------------------------------------------------------
  165. * I/P Arguments: ASCII value of the char to be displayed.
  166. * Return value : none
  167.  
  168. * description  :
  169. This function sends a character to be displayed on LCD in the following steps.
  170. step1: Send the character to LCD.
  171. step2: Select the Data Register by making RS high.
  172. step3: Select Write operation making RW low.
  173. step4: Send a High-to-Low pulse on Enable PIN with some delay_us.
  174.  
  175. -----------------------------------------------------------------------------------*/
  176. void LCD_DataWrite( char dat)
  177. {
  178.  
  179.  
  180. databus=dat; // Send the data to LCD
  181. rs=1; // Select the Data Register by pulling RS HIGH
  182. rw=0; // Select the Write Operation by pulling RW LOW
  183. en=1; // Send a High-to-Low Pusle at Enable Pin
  184. delay_us(10);
  185. en=0;
  186.  
  187. delay_ms(1);
  188.  
  189. }
  190.  
  191.  
  192.  
  193.  
  194.  
  195.  
  196. /*---------------------------------------------------------------------------------
  197. void LCD_DisplayString(char *string_ptr)
  198. ----------------------------------------------------------------------------------
  199. * I/P Arguments: String(Address of the string) to be displayed.
  200. * Return value : none
  201.  
  202. * description  :
  203. This function is used to display the ASCII string on the lcd.
  204. 1.The string_ptr points to the first char of the string
  205. and traverses till the end(NULL CHAR).
  206. 2.Each time a char is sent to LCD_DataWrite funtion to display.
  207. -----------------------------------------------------------------------------------*/
  208. void LCD_DisplayString(char *string_ptr)
  209. {
  210. while(*string_ptr)
  211. LCD_DataWrite(*string_ptr++);
  212. }
  213.  
  214.  
  215.  
  216.  
  217.  
  218. /*---------------------------------------------------------------------------------
  219. void LCD_DisplayNumber(unsigned int num)
  220. ----------------------------------------------------------------------------------
  221. * Function name: LCD_DisplayNumber()
  222. * I/P Arguments: unsigned int.
  223. * Return value : none
  224.  
  225. * description  :This function is used to display a 5-digit integer(0-65535).
  226. ex: if the number is 12345 then 12345 is displayed.
  227. if the number is 123 then 00123 is displayed.
  228.  
  229.  
  230. __________Take 1 by dividing by 10000 and add 0X30 to obtain the ASCII value,
  231. | then take the 4-digit remainder(2345).
  232. |
  233. | _________Take 2 by dividing by 1000 and add 0X30 to obtain the ASCII value,
  234. || then take the 3-digit remainder(345)
  235. ||
  236. || ________Take 3 by dividing by 100 and add 0X30 to obtain the ASCII value,
  237. ||| then take the 2-digit remainder(45).
  238. |||
  239. ||| _______Take 4 by dividing by 10 and add 0X30 to obtain the ASCII value,
  240. |||| ______Take 5 the remainder of 45 and add 0X30 to obtain the ASCII value,.
  241. |||||
  242. 12345
  243. -----------------------------------------------------------------------------------*/
  244. void LCD_DisplayNumber(unsigned int num)
  245. {
  246. LCD_DataWrite((num/10000)+0x30);
  247. num=num%10000;
  248.  
  249. LCD_DataWrite((num/1000)+0x30);
  250. num=num%1000;
  251.  
  252. LCD_DataWrite((num/100)+0x30);
  253. num=num%100;
  254.  
  255. LCD_DataWrite((num/10)+0x30);
  256.  
  257. LCD_DataWrite((num%10)+0x30);
  258.  
  259. }
  260.  
  261.  
  262.  
  263.  
  264.  
  265. /*---------------------------------------------------------------------------------
  266. void LCD_ScrollMessage(char *msg_ptr)
  267. ----------------------------------------------------------------------------------
  268. * I/P Arguments: char *msg_ptr
  269. msg_ptr -> pointer to the string to be scrolled
  270.  
  271. * Return value : none
  272.  
  273. * description  :This function scrolls the given message on the first line.
  274. 1.16 chars are displayed at atime.
  275. 2.Pointer is incremented to skip a char each time to give the illusion of
  276. moving chars
  277. 3.If the chars are less than 16, then the BlankSpaces are displayed.
  278.  
  279. -----------------------------------------------------------------------------------*/
  280.  
  281. void LCD_ScrollMessage(char *msg_ptr)
  282. {
  283. unsigned char i,j;
  284. LCD_CmdWrite(0x0c); //Disable the Cursor
  285. for(i=0;msg_ptr[i];i++) //Loop to display the complete string
  286. { //each time 16 chars are displayed and
  287. //pointer is incremented to point to next char
  288.  
  289. LCD_GoToLineOne(); //Move the Cursor to first line
  290.  
  291. for(j=0;j<LCDMaxChars && msg_ptr[i+j];j++) //loop to Display first 16 Chars
  292. LCD_DataWrite(msg_ptr[i+j]); //or till Null char
  293.  
  294. for(j=j; j<LCDMaxChars; j++) //If the chars are below 16
  295. LCD_DataWrite(BlankSpace); //then display blank spaces
  296.  
  297. delay_ms(125);
  298. }
  299. LCD_CmdWrite(0x0E); //Enable the Cursor
  300. }
  301.  
  302.  
  303.  
  304.  
  305.  
  306. /*---------------------------------------------------------------------------------
  307. void LCD_DisplayRtcTime(char hour,char min,char sec)
  308. ----------------------------------------------------------------------------------
  309. * I/P Arguments: char hour,char min,char sec
  310. hour,min,sec should be packed BCD format, as read from DS1307
  311.  
  312. * Return value : none
  313.  
  314. * description  :This function display hour,min,sec read from DS1307.
  315.  
  316. ___________ Display the higher nibble of hour after adding 0x30(ASCII conversion)
  317. | Display the lower nibble of hour after adding 0x30(ASCII conversion)
  318. |
  319. | ________ Display the higher nibble of min after adding 0x30(ASCII conversion)
  320. | | Display the lower nibble of min after adding 0x30(ASCII conversion)
  321. | |
  322. | | _____ Display the higher nibble of sec after adding 0x30(ASCII conversion)
  323. | | | Display the lower nibble of sec after adding 0x30(ASCII conversion)
  324. | | |
  325. 10;10;40
  326.  
  327. -----------------------------------------------------------------------------------*/
  328. void LCD_DisplayRtcTime(char hour,char min,char sec)
  329. {
  330. LCD_DataWrite(((hour>>4) & 0x0f) + 0x30);
  331. LCD_DataWrite((hour & 0x0f) + 0x30);
  332. LCD_DataWrite(':');
  333.  
  334. LCD_DataWrite(((min>>4) & 0x0f) + 0x30);
  335. LCD_DataWrite((min & 0x0f) + 0x30);
  336. LCD_DataWrite(':');
  337.  
  338. LCD_DataWrite(((sec>>4) & 0x0f) + 0x30);
  339. LCD_DataWrite((sec & 0x0f) + 0x30);
  340.  
  341. }
  342.  
  343.  
  344.  
  345.  
  346.  
  347.  
  348. /*---------------------------------------------------------------------------------
  349. LCD_DisplayRtcDate(char day,char month,char year)
  350. ----------------------------------------------------------------------------------
  351. * I/P Arguments: char day,char month,char year
  352. day,month,year should be packed BCD format, as read from DS1307
  353.  
  354. * Return value : none
  355.  
  356. * description  :This function display day,month,year read from DS1307.
  357.  
  358. ___________ Display the higher nibble of day after adding 0x30(ASCII conversion)
  359. | Display the lower nibble of day after adding 0x30(ASCII conversion)
  360. |
  361. | ________ Display the higher nibble of month after adding 0x30(ASCII conversion)
  362. | | Display the lower nibble of month after adding 0x30(ASCII conversion)
  363. | |
  364. | | _____ Display the higher nibble of year after adding 0x30(ASCII conversion)
  365. | | | Display the lower nibble of year after adding 0x30(ASCII conversion)
  366. | | |
  367. 01/01/12 (1st-Jan 2012)
  368.  
  369. -----------------------------------------------------------------------------------*/
  370. void LCD_DisplayRtcDate(char day,char month,char year)
  371. {
  372. LCD_DataWrite(((day>>4) & 0x0f) + 0x30);
  373. LCD_DataWrite((day & 0x0f) + 0x30);
  374. LCD_DataWrite('/');
  375.  
  376. LCD_DataWrite(((month>>4) & 0x0f) + 0x30);
  377. LCD_DataWrite((month & 0x0f) + 0x30);
  378. LCD_DataWrite('/');
  379.  
  380. LCD_DataWrite(((year>>4) & 0x0f) + 0x30);
  381. LCD_DataWrite((year & 0x0f) + 0x30);
  382.  
  383. }

4 bit Mode

Fig 4: Schematic LCD 4 bit mode