LCD and Keyboard Sepehr Naimi www Nicer Land
LCD and Keyboard Sepehr Naimi www. Nicer. Land. com
About LCD n n Sometimes the embedded system needs to inform the user of something. There are different ways to inform the user, such as LEDs, 7 segments and LCDs. LCD is one of the most powerful ways; as you can display different texts and icons on it.
Topics: n n n LCD pin out LCD internal components How to use LCD n n Busy LCD commands Changing fonts (case study) additional references
LCD internal components n n CGRAM 40 H 41 H Data Register 42 H . . . n DDRAM (Data Display RAM) CGRAM (Character Generator RAM) Cursor (Address Counter) Data Register Command Register 7 EH 7 FH Cursor DDRAM 80 H 81 H 82 H . . . FEH FFH Command Register
DDRAM (Data Display RAM) n n n n CGRAM (Character Generator RAM) n n It is a 128 x 8 RAM (128 bytes of RAM) Contains the data that should be displayed on the LCD. If we write the ASCII code of a character into the RAM the character will be displayed on the LCD. It is a 64 x 8 RAM (64 bytes of RAM). The fonts of characters 00 H to 07 H are stored in the RAM. We can change the fonts of the 8 characters by writing into the RAM. Cursor (Address Counter) n Cursor is a register which points to a location of DDRAM or CGRAM.
DDRAM (Data Display RAM) n Data Register n n It is an 8 bit register. When we write a byte of data into the data register, the data will be written where the cursor points to. For example, if we write a byte of data into the data register while the cursor points to location 80 H of DDRAM, the contents of location 80 H will be changed to the data, we have written into the data register. Command Register n n We can command the LCD by writing into the command register. For example, we can ask the LCD, to set cursor location, or clean the screen, by writing into the command Register.
Writing to Data Register (Example) CGRAM 40 H 41 H Data Register 42 H . . . 50 H 7 EH 7 FH Cursor Command Register DDRAM 80 H 81 H 82 H . . . P FEH FFH
LCD commands n n We mentioned earlier that we can order the LCD by sending command codes to the command register. Some of the command codes are listed in the following table. Code Instruction (Hex) 1 Clear display screen Code Instruction (Hex) 2 Return home 10 Shift cursor position to left 14 Shift cursor position to right 18 Shift display left 1 C Shift display right 4 After displaying a character on the LCD, shift cursor to left 80 -FF Set cursor position 6 After displaying a character on the LCD, shift cursor to right 40 -7 F Set CG RAM address 8 Display off, cursor off A Display off, cursor on C Display on, cursor off E Display on, cursor on F Display on, cursor blinking 38 Initializing to 2 lines & 5 x 7 font
Clear Display Screen n If we write 01 H into the command register, LCD clears the display, and sets the cursor address to 0.
Display and Cursor n Display on cursor blinking (0 FH) n Hello world ! n Display on cursor off (0 CH) Hello world ! Display on cursor on (0 EH) n Display off cursor off (0 AH)
Return home n If we write 02 H into the command register, LCD sets the cursor address to 0. It also returns display to original position if being shifted.
Set cursor position (Set DDRAM address) n n n We mentioned earlier that each location of the DDRAM, retains the character that should be displayed in a location of LCD. The following figures, represent that if you want to display a character in each of the rooms of the LCD, you should write into which location of the DDRAM. (The numbers are in hex. ) To move the cursor to any location of the DDRAM, write the address of that location into the command register. Line 1 1 2 3 … 18 19 Line 1 80 81 82 … 91 92 93 Line 2 C 0 C 1 C 2 … D 1 D 2 D 3 Line 3 94 Line 4 D 4 95 96 … A 5 A 6 A 7 D 5 D 6 … E 5 E 6 E 7 1 2 3 … 18 19 80 81 82 … 91 92 20 1 2 3 … 18 19 20 Line 1 80 81 82 … 91 92 93 Line 2 C 0 C 1 C 2 … D 1 D 2 D 3 20 x 2 LCD 2 3 … 38 39 40 Line 1 80 81 82 … A 5 A 6 A 7 Line 2 C 0 C 1 C 2 … E 5 E 6 E 7 40 x 2 LCD 93 20 x 1 LCD 20 x 4 LCD 1 20 1 2 3 … 14 15 Line 1 80 81 82 … 8 D 8 E 8 F Line 2 C 0 C 1 C 2 … CD CE CF 16 x 2 LCD 16
Set cursor position (example) n We want to display a character in line 4 column 1 of a 20 x 4 LCD. What should we write to the command register to move the cursor to? Solution: We should move cursor to address D 4 H of the DDRAM. So, we should write D 4 H, into the command register. 1 2 3 … 18 19 20 Line 1 80 81 82 … 91 92 93 Line 2 C 0 C 1 C 2 … D 1 D 2 D 3 Line 3 94 95 96 … A 5 A 6 A 7 Line 4 D 5 D 6 … E 5 E 6 E 7
Decrease and increase Cursor n If you write a byte of data into the data register, the data will be written where the cursor points to, and cursor will be incremented, by default. n n If you want to make the LCD, to decrement the cursor, you should write 4 H into the command register. If you want to make the LCD, to reactivate the default (shift cursor to right) you should write 6 H into the command register. Hello Increment cursor Hello Decrement cursor
LCD pins D 7 D 6 D 5 D 4 D 3 D 2 D 1 D 0 E RW VEEVCCVSS RS In this section, you learn the functionalities of the LCD pins.
LCD pins D 7 D 6 D 5 D 4 D 3 D 2 D 1 D 0 E RW VEEVCCVSS RS + - n +5 VSS and VCC: These pins provide the energy to the LCD. We must connect them to +5 V.
LCD pins Hello world ! D 7 D 6 D 5 D 4 D 3 D 2 D 1 D 0 E RW VEEVCCVSS RS + - n +5 VEE: We control the contrast of the LCD by giving a voltage between 0 V and +5 V to the pin.
LCD pins D 7 D 6 D 5 D 4 D 3 D 2 D 1 D 0 E RW VEEVCCVSS RS n D 0 to D 7: LCD sends and receives data, through the 8 pins.
LCD pins D 7 D 6 D 5 D 4 D 3 D 2 D 1 D 0 E RW VEEVCCVSS RS n R/W (Read/Write): n n When we want to send (write) data to the LCD, we make the pin, low. When we want to receive (read) data from the LCD, we set the pin to high.
LCD pins D 7 D 6 D 5 D 4 D 3 D 2 D 1 D 0 E RW VEEVCCVSS RS n E (Enable): We activate the pin when we want to send or receive data from the LCD. n E When we want to send data to the LCD, we make the RW pin, low; and supply the data to data pins (D 0 to D 7); and then apply a high to low pulse to the Enable pin. When we want to receive data from the LCD, we make the RW pin, high; and then apply a low to high pulse to the Enable pin. LCD supplies data to the data pins (D 0 to D 7).
LCD pins D 7 D 6 D 5 D 4 D 3 D 2 D 1 D 0 E RW VEEVCCVSS RS n n n RS (Register select): There are two registers with names of command register and data register in the LCD. If RS = 1, whenever we send data to the LCD, the data will be located in the data register. If RS = 0, whenever we send data to the LCD, the data will be located in the command register Data Register RS Command Register 01
LCD Programming n Initialization n Sending commands to the LCD n n We must initialize the LCD before we use it. To initialize an LCD, for 5× 7 matrix and 8 -bit operation, 0 x 38, 0 x 0 E, and 0 x 01 are send to the command register. Make pins RS and R/W = 0 Put the command number on the data pins (D 0–D 7) Send a high-to-low pulse to the E pin to enable the internal latch of the LCD (wait about 100 us after each command) Sending data to the LCD n n n make pins RS = 1 and R/W = 0. put the data on the data pins (D 0–D 7) send a high-to-low pulse to the E pin (wait about 100 us)
Example n Write a program that displays ‘H’ on the LCD.
4 -bit mode
LCD Programming in 4 -bit mode n n To save pins of the MCU, we can use 4 -bit operating mode. In this mode, only D 4 -D 7 are used.
LCD initialization n The initialization of 4 -bit mode is somehow different: n In 4 -bit mode, we initialize the LCD with values 33, 32, and 28 in hex. n This represents nibbles 3, 3, 3, and 2, which tells the LCD to go into 4 -bit mode. The value 0 x 28 initializes the display for 5 × 7 matrix and 4 -bit operation void lcd_init() { GPIOA->ODR &= ~(1<<LCD_EN); /* LCD_EN = 0 */ delay_us(3000); /* wait 3 ms */ lcd_send. Command(0 x 33); /* send 0 x 33 for init. */ lcd_send. Command(0 x 32); /* send 0 x 32 for init. */ lcd_send. Command(0 x 28); /* init. LCD 2 line, 5 x 7 matrix */ }
Sending Command Data n First we should send the high nibble to D 4 -D 7, then, send the low nibble to D 4 -D 7 void lcd_put. Value(unsigned char value) { GPIOA->BRR = 0 x 0 F; /* clear PA 0 -PA 3 */ GPIOA->BSRR = (value>>4)&0 x 0 F; /* put high nibble on PA 0 -PA 3 */ GPIOA->ODR |= (1<<LCD_EN); /* EN = 1 for H-to-L pulse */ delay_us(1); /* make EN pulse wider */ GPIOA->ODR &= ~ (1<<LCD_EN); /* EN = 0 for H-to-L pulse */ delay_us(100); /* wait */ GPIOA->BRR = 0 x 0 F; /* clear PA 0 -PA 3 */ GPIOA->BSRR = value&0 x 0 F; /* put low nibble on PA 0 -PA 3 */ GPIOA->ODR |= (1<<LCD_EN); /* EN = 1 for H-to-L pulse */ delay_us(1); /* make EN pulse wider */ GPIOA->ODR &= ~(1<<LCD_EN); /* EN = 0 for H-to-L pulse */ delay_us(100); /* wait */ }
Changing Font
Changing fonts (Changing CGRAM) n D 7 D 6 D 5 D 4 Character 0 Character 1 n Each character LCD has a CGRAM (Character generator RAM). It stores the fonts of the first 8 characters (character 0 H to character 7 H). So, you can change the font of the 8 characters and define new characters, by writing into the CGRAM. Each byte of the CGRAM stores a row of a font. The fonts are stored respectively, in the CGRAM. For example, if you change the content of first byte of the CGRAM (whose address is 40 H), you have changed the highest row of character 0 H. Attention: in an LCD with 5 x 7 font, each font has actually 8 rows. The 8 th row is put aside for the cursor. You would better not set the bits of the 8 th row. D 3 D 2 D 1 D 0 0 1 1 0 40 0 1 0 0 0 1 41 0 0 0 1 42 0 0 0 1 1 0 43 0 0 0 1 0 0 44 0 0 0 1 0 45 0 0 0 1 46 0 0 0 0 47 0 0 0 1 48 0 0 1 0 49 0 0 0 1 1 1 4 A 0 0 0 1 0 0 4 B 0 0 0 1 1 1 4 C 0 0 0 1 0 0 4 D 0 0 0 1 0 0 0 0 0 4 E 4 F : CGRAM (Its first 16 bytes) :
Changing fonts To change a row of a font, you should follow the following direction: n 1. 2. n Set the cursor position to point to the location of the CGRAM that you want to change. Change the font of the selected row, by writing into data register. Attention: LCD has only one cursor. When you want to change the CGRAM you make it point to CGRAM and when you want to display something on the screen you make it point to a location of DDRAM. So, when you finished changing the fonts don’t forget to set the cursor position, so that, it points to DDRAM.
Setting CGRAM address n To make the cursor point to any location of CGRAM, or DDRAM, simply write the address of the location into the command register.
Setting CGRAM address (Example) n We want to change the font of the 4 th row of character 01 H. What should we write to the command register to make the cursor point to the relevant address. D 7 D 6 D 5 D 4 Solution: Character 1 As you can see in the figure, the address of the 4 th row of character 01 H is 4 BH. So, we should write 4 BH into the command register. Character 0 n D 3 D 2 D 1 D 0 0 1 1 0 40 0 1 0 0 0 1 41 0 0 0 1 42 0 0 0 1 1 0 43 0 0 0 1 0 0 44 0 0 0 1 0 45 0 0 0 1 46 0 0 0 0 47 0 0 0 1 0 49 0 0 0 1 1 1 4 A 0 0 0 1 0 0 4 B 0 0 0 1 1 1 4 C 0 0 0 1 0 0 4 D 0 0 0 1 0 0 4 E 0 0 0 0 4 F CGRAM (Its first 16 bytes) 48 : :
Keyboard
Bounce A key press may be considered as more than one click MCU PB 1 VCC Time
Debouncing (The correct way of reading keys) do{ while((GPIOB->IDR&1) == 0); delay_ms (20); }while((GPIOB->IDR&1) == 0); do{ while((GPIOB->IDR&1) == 1); delay_ms (20); }while((GPIOB->IDR&1) == 1); A++;
Using Keyboard If we connect each key to a pin of the MCU, we waste many pins. So we use scanning as shown in the next slide PA. 8 PA. 9 MCU PA. 10 PA. 11 PA. 12 PA. 13 PA. 14 PA. 15 PA. 4 PA. 5 PA. 6 PA. 7
Keyboard VCC 1 2 3 é 4 5 6 ç 7 8 9 è Cancel 0 OK ê D 0 D 1 D 2 D 3 D 2 D 1 D 0
Creating a Matrix keyboard VCC D 0 INPUT D 1 D 2 D 3 D 2 D 1 OUTPUT D 0
Connecting to AVR VCC D 0 MCU D 1 D 2 PB 13 PB 14 PB 15 PB 9 PB 8 PB 7 PB 6 D 3 D 2 D 1 D 0
Keyboard Programming n Writing programs for Matrix Keyboard n Key press detection n n Aim: detecting if any of the keys is pressed Key identification (scanning the keyboard) n Aim: identifying that which of the keys is pressed
Press detection (is any of the keys pressed) VCC D 3 D 2 D 1 D 0
Key identification VCC D 3 VCC D 2 VCC D 1 VCC D 0 D 3 D 2 D 1 D 0
Key identification VCC D 3 D 2 VCC D 1 VCC D 0 D 3 D 2 D 1 D 0
Key identification VCC D 3 VCC D 2 D 1 VCC D 0 D 3 D 2 D 1 D 0
Key identification VCC D 3 VCC D 2 VCC D 1 D 0 D 3 D 2 D 1 D 0
Example n Write a function, that waits for a key to be pressed and then returns the code of the pressed key. 1 2 3 é 4 5 6 ç 7 8 9 è Cancel 0 OK ê D 0 D 1 D 2 D 3 D 2 D 1 D 0
Solution Start Ground next row Ground all rows Read all columns No No Any key down? All keys open? Yes Wait for de-bounce Read all columns No Any key down? Yes Read all columns Key press in this row Yes Find which key is pressed Get code from table Return No
- Slides: 47