/**************************************************************************** ** ** ** Hitachi Character-Type LCD Display ** ** ** ****************************************************************************/ // // NOTE: This is set up for 4 MHz oscillator // #define LCD_C // "I am LCD.C" #ifndef CLRWDT #include <pic.h> #endif #include "defs.h" #include "lcd.h" #include "delay.h" // Contains delay routines & macros const byte const LCD_ROW_ADDRESS[] = // Row/Column information for lcd_gotoxy() { #if LCD_MODE_1x8 0x00 #endif #if LCD_MODE_1x16_A 0x00 #endif #if LCD_MODE_1x16_B 0x00, 0x40 #endif #if LCD_MODE_1x40 0x00, #endif #if LCD_MODE_2x8 0x00, 0x40 #endif #if LCD_MODE_2x12 0x00, 0x40 #endif #if LCD_MODE_2x16 0x00, 0x40 #endif #if LCD_MODE_2x20 0x00, 0x40 #endif #if LCD_MODE_2x24 0x00, 0x40 #endif #if LCD_MODE_2x40 0x00, 0x40 #endif #if LCD_MODE_4x16 0x00, 0x40, 0x10, 0x50 #endif #if LCD_MODE_4x20 0x00, 0x40, 0x14, 0x54 #endif #if LCD_MODE_4x24 0x00, 0x40, 0x80, 0xc0 #endif }; const byte const LCD_INIT_STRING [] = // LCD Init String on powerup { 0b00000001, // Clear display 0b00000010, // Home cursor 0b00000100 // Entry Mode #if LCD_CURSOR_INCREMENT | 0b00000010 // Increment cursor #endif #if LCD_CURSOR_SHIFT | 0b00000001 // Shift on cursor #endif , // end 0b00001000 // Display Control #if LCD_DISPLAY_ON | 0b00000100 // Display on #endif #if LCD_CURSOR_ON | 0b00000010 // Cursor on #endif #if LCD_CURSOR_BLINK | 0b00000001 // Blink on #endif , // end 0b00100000 // Function Set #if LCD_8_BIT_MODE | 0b00010000 // 8-bit data bus #endif #if LCD_MULTI_LINE | 0b00001000 // 2-line refreshing #endif #if LCD_DISPLAY_5x10 | 0b00000100 // 5x10 matrix #endif }; #if LCD_4_BIT_MODE void lcd_putnybble (byte c) // Write nybble to port in current RS mode { c = c << LCD_D4_BIT; // Shift over to correct bit column c &= LCD_TRIS_DATAMASK; // Remove any extraneous bits LCD_DATA_PORT = (LCD_DATA_PORT & ~LCD_TRIS_DATAMASK) | c; // Write data bits to port delay_uS (1); LCD_E = 1; // Start to write it delay_uS (2); LCD_E = 0; // Finish write cycle } #endif byte lcd_getbyte (void) // Read byte at cursor (RS=1) or ready status (RS=0) { byte retval; #if LCD_4_BIT_MODE byte highbits; LCD_TRIS_PORT |= LCD_TRIS_DATAMASK; // Set port to read mode for data pins LCD_RW = 1; // Tell LCD we want to read delay_uS (1); LCD_E = 1; highbits = (((LCD_DATA_PORT & LCD_TRIS_DATAMASK) >> LCD_D4_BIT) << 4);// Grab high bits and shift to right place LCD_E = 0; delay_uS (1); LCD_E = 1; delay_uS (1); retval = ((LCD_DATA_PORT & LCD_TRIS_DATAMASK) >> LCD_D4_BIT); // Grab low bits LCD_E = 0; retval |= highbits; LCD_TRIS_PORT &= ~LCD_TRIS_DATAMASK; // Set port back to output mode #else LCD_TRIS_PORT = 0xFF; // Set port to all input LCD_RW = 1; // Tell LCD we want to read delay_uS (1); LCD_E = 1; // Do the read delay_uS (1); retval = LCD_DATA_PORT; LCD_E = 0; LCD_TRIS_PORT = 0x00; // Set port back to outputs #endif return (retval); // Give answer to caller } void lcd_putbyte (byte c) // Write byte to port in current RS mode { byte RS_Status; RS_Status = LCD_RS; // Get old pin state LCD_RS = 0; // Force into command mode to read state while (lcd_getbyte () & 0x80); // Wait for read state if (RS_Status) LCD_RS = 1; // Restore RS to old state delay_uS (1); LCD_RW = 0; // Set to write mode delay_uS (1); #if LCD_4_BIT_MODE lcd_putnybble (c >> 4); // Send the character out lcd_putnybble (c); #else LCD_DATA_PORT = c; // Send the character out #endif LCD_E = 1; delay_uS (1); LCD_E = 0; } void lcd_command (byte c) // Send command to LCD port { LCD_RS = 0; lcd_putbyte (c); } #if LCD_ALLOW_USER_CHARS void lcd_define_char (byte c, const byte *bitmap) // Define user-defined chars { byte i; lcd_command ((0b01000000) | (c << 3)); // Select char to define LCD_RS = 1; for (i = 0; i < 8; i++) lcd_putbyte (*bitmap++); // Put in each byte of memory } #endif byte lcd_lineof (byte CursorAddress) // Calculate cursor row from it's address { CursorAddress &= 0x50; // Strips out uniquely the address bits switch (CursorAddress) { case 0x00: // Note - this handles all cases except for some CursorAddress = 1; // of those unsupported displays listed in case 0x40: // lcd.h file. #if LCD_MODE_1x16_B CursorAddress = 1; // Only 1 row this type of display #else CursorAddress = 2; #endif case 0x10: CursorAddress = 3; case 0x50: CursorAddress = 4; default: CursorAddress = 1; } return (CursorAddress); } byte lcd_cursorpos (void) // Return address of cursor position { LCD_RS = 0; return (lcd_getbyte ()); // Get cursor position } void lcd_putc (byte c) // Write character to LCD { #if !LCD_ALLOW_USER_CHARS byte CursAddr; #endif #if LCD_ALLOW_USER_CHARS // Allow user-defined characters - no terminal mode LCD_RS = 1; lcd_putbyte (c); #else switch (c) { case '\b': // Backspace? lcd_command (LCD_COMMAND_BACKSPACE); // back cursor up #if LCD_DESTRUCTIVE_BS LCD_RS = 1; // set display mode lcd_putbyte (' '); // erase previous character lcd_command (LCD_COMMAND_BACKSPACE); // move cursor back again #endif break; case '\n': // Newline? RS = 0; CursAddr = lcd_getbyte (); // Get cursor position CursAddr = lcd_lineof (CursAddr); #if LCD_ENABLE_SCROLL if (CursAddr >= LCD_MAXROWS) // Bottom line? lcd_scroll (); // Yes, force scroll else // No, just go to start of next line lcd_gotoxy (CursAddr+1,1); #else lcd_gotoxy (CursAddr+1, 1); // Position cursor to start of line #endif break; case '\f': // Form Feed (clear screen)? lcd_command (LCD_COMMAND_CLEAR); // Erase screen lcd_gotoxy (1,1); // Position cursor to top of screen break; default: // Printable? LCD_RS = 1; // Set to display mode lcd_putbyte (c); // Send character out } #endif } #if LCD_ENABLE_GETC byte lcd_getc (void) // Read character at cursor { byte retval; LCD_RS = 1; retval = lcd_getbyte (); LCD_RS = 0; return (retval); } #endif #if LCD_ENABLE_GOTOXY void lcd_gotoxy (byte row, byte col) // Position cursor { #if LCD_MODE_1x16_B if (col > 7) // 1x16 is treated the same as 2x8 for addressing { row++; col -= 8; } if (col > 8) col = 8; if (row > 2) row = 2; #else if (row > LCD_MAXROWS) // Range limit row = LCD_MAXROWS; if (col > LCD_MAXCOLS) col = LCD_MAXCOLS; #endif row = LCD_ROW_ADDRESS[row-1]; // Get address of first byte on desired row row += col - 1; lcd_command (0x80 | row); // Write new cursor address } void lcd_getxy (byte *row, byte *col) // Return row and column of cursor position { byte rr, cc; cc = lcd_cursorpos (); rr = lcd_lineof (cc); // Get row of the cursor cc = (cc & 0x7f) - LCD_ROW_ADDRESS[rr-1]; // Find the column *row = rr; // Convert to lcd_gotoxy() units *col = cc; } #endif #if LCD_ENABLE_PRINTF void lcd_printf (const char* message) // Write message to LCD (C string type) { while (*message) // Look for end of string lcd_putc (*message++); // Show and bump } #endif #if LCD_ENABLE_SCROLL void lcd_scroll (void) // Scroll up one line { byte CursorPos, // Hold position of cursor Character, // Hold character being moved SrcAddr, // Source Address DestAddr, // Destination Address EndAddr; // Ending copy address (last address of Source) LCD_RS = 0; CursorPos = lcd_getbyte () | 0x80; // Get cursor position lcd_gotoxy (2,1); LCD_RS = 0; SrcAddr = lcd_getbyte () | 0x80; // Find address of copy start lcd_gotoxy (1,1); LCD_RS = 0; DestAddr = lcd_getbyte () | 0x80; // Find address of copy destination lcd_gotoxy (LCD_MAXROWS, LCD_MAXCOLS); LCD_RS = 0; EndAddr = lcd_getbyte () | 0x80; // Find address of last byte to copy over do { LCD_RS = 0; // Position to source of copy char lcd_putbyte (SrcAddr); LCD_RS = 1; Character = lcd_getbyte (); // Read the character there LCD_RS = 0; lcd_putbyte (DestAddr); // Move to the destination LCD_RS = 1; lcd_putbyte (Character); // Write it the char there SrcAddr++; DestAddr++; } while (SrcAddr <= EndAddr); // Loop through all memory for (Character = 1; Character <= LCD_MAXCOLS; Character++) { lcd_gotoxy (LCD_MAXROWS, Character); // Position on last line lcd_putc (' '); // Blank out the char } lcd_gotoxy (lcd_lineof (CursorPos) + 1,1); // Home cursor next line } #endif #if LCD_ENABLE_UNSCROLL void lcd_unscroll (void) // Roll scroll backwards one line { byte CursorPos, // Hold position of cursor Character, // Hold character being moved SrcAddr, // Source Address DestAddr; // Destination Address LCD_RS = 0; CursorPos = lcd_getbyte () | 0x80; // Get cursor position lcd_gotoxy (LCD_MAXROWS-1,LCD_MAXCOLS); LCD_RS = 0; SrcAddr = lcd_getbyte () | 0x80; // Find address of copy start lcd_gotoxy (LCD_MAXROWS,LCD_MAXCOLS); LCD_RS = 0; DestAddr = lcd_getbyte () | 0x80; // Find address of copy destination do { LCD_RS = 0; // Position to source of copy char lcd_putbyte (SrcAddr); LCD_RS = 1; Character = lcd_getbyte (); // Read the character there LCD_RS = 0; lcd_putbyte (DestAddr); // Move to the destination LCD_RS = 1; lcd_putbyte (Character); // Write it the char there SrcAddr--; DestAddr--; } while (SrcAddr != 0x80); // Loop through all memory for (Character = 0; Character < LCD_MAXCOLS; Character++) { lcd_gotoxy (1, Character); // Position on top row lcd_putc (' '); // Blank out the char } lcd_gotoxy (lcd_lineof (CursorPos),1); // Home cursor same line as before } #endif #if LCD_ENABLE_CLEAR void lcd_clear (void) // Clear LCD screen { lcd_command (LCD_COMMAND_CLEAR); } #endif void lcd_init (void) // Reset display from software { byte i; LCD_E = 0; // Set up control pin I/O LCD_TRIS_E = 0; LCD_RW = 0; // Write mode LCD_TRIS_RW = 0; LCD_RS = 0; // Command mode LCD_TRIS_RS = 0; LCD_TRIS_PORT &= ~LCD_TRIS_DATAMASK; // Set data bus to output LCD_E = 0; // Start talking to LCD delay_mS (15); // Wait a little while #if LCD_4_BIT_MODE // Set LCD into 4-bit mode lcd_putnybble (0b0011); // Select 8-bit mode delay_mS (5); // Spec calls for 4.1 mS lcd_putnybble (0b0011); // Do it again delay_uS (100); lcd_putnybble (0b0011); lcd_putnybble (0b0010); // Off and running... #else lcd_putbyte (0b00110000); // Select 8-bit mode delay_mS (5); // Spec calls for 4.1 mS lcd_putbyte (0b00110000); // Do it again delay_uS (100); lcd_putbyte (0b00110000); lcd_putbyte (0b00110000); // Off and running... #endif for (i = 0; i < sizeof(LCD_INIT_STRING); i++) // Send other LCD initialization stuff lcd_command (LCD_INIT_STRING[i]); }
Questions:
file: /Techref/microchip/language/c/io/lcd/hitachilcd-ak/lcd_c.htm, 52KB, , updated: 2006/6/13 09:00, local time: 2024/11/5 03:04,
3.133.129.97:LOG IN ©2024 PLEASE DON'T RIP! THIS SITE CLOSES OCT 28, 2024 SO LONG AND THANKS FOR ALL THE FISH!
|
©2024 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions? <A HREF="http://linistepper.com/Techref/microchip/language/c/io/lcd/hitachilcd-ak/lcd_c.htm"> Hitachi Character-Type LCD Display</A> |
Did you find what you needed? |