E

CCS C 4x20 Flexible driver

Başlatan Erata, 06 Kasım 2012, 05:08:08

Erata

CCS c

4x20  LCD  flexible  driver

// Flex_LCD420.c// These pins are for my Microchip PicDem2-Plus board,// which I used to test this driver.// An external 20x4 LCD is connected to these pins.// Change these pins to match your own board's connections.#define LCD_DB4   PIN_D4#define LCD_DB5   PIN_D5#define LCD_DB6   PIN_D6#define LCD_DB7   PIN_D7#define LCD_RS    PIN_E0#define LCD_RW    PIN_E1#define LCD_E     PIN_E2/*// To prove that the driver can be used with random// pins, I also tested it with these pins:#define LCD_DB4   PIN_D4#define LCD_DB5   PIN_B1#define LCD_DB6   PIN_C5#define LCD_DB7   PIN_B5#define LCD_RS    PIN_E2#define LCD_RW    PIN_B2#define LCD_E     PIN_D6*/// If you want only a 6-pin interface to your LCD, then// connect the R/W pin on the LCD to ground, and comment// out the following line.  Doing so will save one PIC// pin, but at the cost of losing the ability to read from// the LCD.  It also makes the write time a little longer// because a static delay must be used, instead of polling// the LCD's busy bit.  Normally a 6-pin interface is only// used if you are running out of PIC pins, and you need// to use as few as possible for the LCD.#define USE_RW_PIN   1     // These are the line addresses for most 4x20 LCDs.#define LCD_LINE_1_ADDRESS 0x00#define LCD_LINE_2_ADDRESS 0x40#define LCD_LINE_3_ADDRESS 0x14#define LCD_LINE_4_ADDRESS 0x54// These are the line addresses for LCD's which use// the Hitachi HD66712U controller chip./*#define LCD_LINE_1_ADDRESS 0x00#define LCD_LINE_2_ADDRESS 0x20#define LCD_LINE_3_ADDRESS 0x40#define LCD_LINE_4_ADDRESS 0x60*///========================================#define lcd_type 2   // 0=5x7, 1=5x10, 2=2 lines(or more)int8 lcd_line;int8 const LCD_INIT_STRING[4] ={ 0x20 | (lcd_type << 2),  // Set mode: 4-bit, 2+ lines, 5x8 dots 0xc,                     // Display on 1,                       // Clear display 6                        // Increment cursor };                             //-------------------------------------void lcd_send_nibble(int8 nibble){// Note:  !! converts an integer expression// to a boolean (1 or 0). output_bit(LCD_DB4, !!(nibble & 1)); output_bit(LCD_DB5, !!(nibble & 2)); output_bit(LCD_DB6, !!(nibble & 4));    output_bit(LCD_DB7, !!(nibble & 8));    delay_cycles(1); output_high(LCD_E); delay_us(2); output_low(LCD_E);}//-----------------------------------// This sub-routine is only called by lcd_read_byte().// It's not a stand-alone routine.  For example, the// R/W signal is set high by lcd_read_byte() before// this routine is called.     #ifdef USE_RW_PINint8 lcd_read_nibble(void){int8 retval;// Create bit variables so that we can easily set// individual bits in the retval variable.#bit retval_0 = retval.0#bit retval_1 = retval.1#bit retval_2 = retval.2#bit retval_3 = retval.3retval = 0;   output_high(LCD_E);delay_us(1);retval_0 = input(LCD_DB4);retval_1 = input(LCD_DB5);retval_2 = input(LCD_DB6);retval_3 = input(LCD_DB7); output_low(LCD_E);delay_us(1);   return(retval);   }   #endif//---------------------------------------// Read a byte from the LCD and return it.#ifdef USE_RW_PINint8 lcd_read_byte(void){int8 low;int8 high;output_high(LCD_RW);delay_cycles(1);high = lcd_read_nibble();low = lcd_read_nibble();return( (high<<4) | low);}#endif//----------------------------------------// Send a byte to the LCD.void lcd_send_byte(int8 address, int8 n){output_low(LCD_RS);#ifdef USE_RW_PINwhile(bit_test(lcd_read_byte(),7)) ;#elsedelay_us(60); #endifif(address)   output_high(LCD_RS);else   output_low(LCD_RS);      delay_cycles(1);#ifdef USE_RW_PINoutput_low(LCD_RW);delay_cycles(1);#endifoutput_low(LCD_E);lcd_send_nibble(n >> 4);lcd_send_nibble(n & 0xf);}//----------------------------void lcd_init(void){int8 i;lcd_line = 1;output_low(LCD_RS);#ifdef USE_RW_PINoutput_low(LCD_RW);#endifoutput_low(LCD_E);// Some LCDs require 15 ms minimum delay after// power-up.  Others require 30 ms.  I'm going// to set it to 35 ms, so it should work with// all of them.delay_ms(35);         for(i=0 ;i < 3; i++)   {    lcd_send_nibble(0x03);    delay_ms(5);   }lcd_send_nibble(0x02);for(i=0; i < sizeof(LCD_INIT_STRING); i++)   {    lcd_send_byte(0, LCD_INIT_STRING[i]);       // If the R/W signal is not used, then    // the busy bit can't be polled.  One of    // the init commands takes longer than    // the hard-coded delay of 50 us, so in    // that case, lets just do a 5 ms delay    // after all four of them.    #ifndef USE_RW_PIN    delay_ms(5);    #endif   }}//----------------------------void lcd_gotoxy(int8 x, int8 y){int8 address;switch(y)  {   case 1:     address = LCD_LINE_1_ADDRESS;     break;   case 2:     address = LCD_LINE_2_ADDRESS;     break;   case 3:     address = LCD_LINE_3_ADDRESS;     break;   case 4:     address = LCD_LINE_4_ADDRESS;     break;   default:     address = LCD_LINE_1_ADDRESS;     break;       }address += x-1;lcd_send_byte(0, 0x80 | address);}//-----------------------------void lcd_putc(char c){ switch(c)   {    case '\f':      lcd_send_byte(0,1);      lcd_line = 1;      delay_ms(2);      break;       case '\n':       lcd_gotoxy(1, ++lcd_line);       break;       case '\b':       lcd_send_byte(0,0x10);       break;       default:       lcd_send_byte(1,c);       break;   }}//------------------------------#ifdef USE_RW_PINchar lcd_getc(int8 x, int8 y){char value;lcd_gotoxy(x,y);// Wait until busy flag is low.while(bit_test(lcd_read_byte(),7)); output_high(LCD_RS);value = lcd_read_byte();output_low(LCD_RS);return(value);}#endif




test program :


#include <16F877.H>#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP#use delay(clock = 4000000)#include <Flex_LCD420.c>   //===================================void main(){int8 i;int8 b1, b2, b3, b4;// The lcd_init() function should always be called once,// near the start of your program.lcd_init();// Clear the LCD.printf(lcd_putc, "\f");delay_ms(500);while(1)  {   // Test the clear screen and newline commands.   // Also test that we can write to all 4 lines.   printf(lcd_putc, "\fThis is the 1st line");   printf(lcd_putc, "\nNext is the 2nd line");   printf(lcd_putc, "\nThis is the 3rd line");   printf(lcd_putc, "\nFinally the 4th line");   delay_ms(3000);   // Test some additional characters.   printf(lcd_putc, "\fABCDEFGHIJKLMNOPQRST");   printf(lcd_putc, "\nabcdefghijklmnopqrst");   printf(lcd_putc, "\n12345678901234567890");   printf(lcd_putc, "\n!@#$^&*(){}[]:;<>?/=");   delay_ms(3000);   // Clear the LCD.   printf(lcd_putc, "\f");   delay_ms(500);   // Test that lcd_gotoxy() works.  Go to each of   // the four corners and put a number in each one,   // in a clockwise direction, starting with the upper   // left corner.   lcd_gotoxy(4, 2);          printf(lcd_putc, "Put a number in");      lcd_gotoxy(4, 3);          printf(lcd_putc, "each corner.");      lcd_gotoxy(1, 1);          printf(lcd_putc, "1");      lcd_gotoxy(20, 1);          printf(lcd_putc, "2");      lcd_gotoxy(20, 4);          printf(lcd_putc, "3");      lcd_gotoxy(1, 4);          printf(lcd_putc, "4");      delay_ms(3000);// Read the character that was written in each corner// of the LCD and display it.   This tests the lcd_getc()// function.   // The following test can only be done if we can read// from the LCD.  If the RW pin is not used, then the// LCD is in write-only mode, and we can't do this test.// The #ifdef statement will prevent the code from// being compiled, in that case.#ifdef USE_RW_PIN      // Test if lcd_getc() can read   // a byte from each corner.   b1 = lcd_getc(1,1);      b2 = lcd_getc(20,1);      b3 = lcd_getc(20,4);      b4 = lcd_getc(1,4);      lcd_gotoxy(1, 1);          printf(lcd_putc, "\fRead these bytes\n");   printf(lcd_putc, "from the 4 corners:\n\n");   printf(lcd_putc, "     %c %c %c %c", b1, b2, b3, b4);          delay_ms(3000);#endif   // Type some characters and backspace over them.   printf(lcd_putc, "\fType characters and\n");   printf(lcd_putc,   "backspace over them.");   delay_ms(2000);   // Go to end of 2nd line.   lcd_gotoxy(20, 2);          // Backspace over 2nd line.   for(i = 0; i < 20; i++)      {       printf(lcd_putc," \b\b");       delay_ms(150);      }   // Go to end of first line.                  lcd_gotoxy(20, 1);          // Backspace over first line.   for(i = 0; i < 20; i++)      {       printf(lcd_putc," \b\b");       delay_ms(150);      }           }   }






alıntıdır


Powered by EzPortal