+ Post New Thread
Results 1 to 8 of 8
  1. #1
    Member level 1
    Points: 594, Level: 5

    Join Date
    Oct 2012
    Posts
    41
    Helped
    0 / 0
    Points
    594
    Level
    5

    Logic Contention(s) Detected on data lines of LCD [Proteus Error]

    I am getting a logic contention detected error on proteus i am writing simple program using driver flexlcd16x4

    My Code
    Code:
    #include <16F877A.h>
    #fuses XT,NOWDT,NOPROTECT,NOLVP
    #use delay(clock=4000000)
    
    #include 
    
    void main() 
    {
       
       lcd_init();
       delay_ms(6);
       lcd_gotoxy(6,1);
       printf(lcd_putc,"Welcome");
       lcd_gotoxy(4,2);
       printf(lcd_putc,"To The World");
       lcd_gotoxy(8,3);
       printf(lcd_putc,"Of");
       lcd_gotoxy(6,4);
       printf(lcd_putc,"CSS C");
       while(1);
    }
    Driver Code 16x4
    Code:
    // Flex_LCD416.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 16x4 Hitach LM041L 
    #define LCD_LINE_1_ADDRESS 0x80 
    #define LCD_LINE_2_ADDRESS 0xC0 
    #define LCD_LINE_3_ADDRESS 0x90 
    #define LCD_LINE_4_ADDRESS 0xD0 
    
    // 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_PIN 
    int8 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.3 
    
    retval = 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_PIN 
    int8 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_PIN 
    while(bit_test(lcd_read_byte(),7)) ; 
    #else 
    delay_us(60); 
    #endif 
    
    if(address) 
       output_high(LCD_RS); 
    else 
       output_low(LCD_RS); 
          
     delay_cycles(1); 
    
    #ifdef USE_RW_PIN 
    output_low(LCD_RW); 
    delay_cycles(1); 
    #endif 
    
    output_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_PIN 
    output_low(LCD_RW); 
    #endif 
    
    output_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_PIN 
    char 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

    •   AltAdvertisment

        
       

  2. #2
    Full Member level 1
    Points: 2,617, Level: 11
    Achievements:
    7 years registered

    Join Date
    Oct 2007
    Location
    Lahore
    Posts
    107
    Helped
    29 / 29
    Points
    2,617
    Level
    11

    Re: Logic Contention(s) Detected on data lines of LCD [Proteus Error]

    Quote Originally Posted by armghan11 View Post
    I am getting a logic contention detected error on proteus i am writing simple program using driver flexlcd16x4
    This error occurs when in proteus Nets so wired as to be likely to result in contentions - i.e. two outputs trying to drive in different directions, resulting in a large flow of current.
    So check your connection in proteus. or attach your proteus file.



    •   AltAdvertisment

        
       

  3. #3
    Member level 1
    Points: 594, Level: 5

    Join Date
    Oct 2012
    Posts
    41
    Helped
    0 / 0
    Points
    594
    Level
    5

    Re: Logic Contention(s) Detected on data lines of LCD [Proteus Error]

    Quote Originally Posted by iukhan View Post
    This error occurs when in proteus Nets so wired as to be likely to result in contentions - i.e. two outputs trying to drive in different directions, resulting in a large flow of current.
    So check your connection in proteus. or attach your proteus file.
    here is the attachment



    •   AltAdvertisment

        
       

  4. #4
    Advanced Member level 1
    Points: 5,693, Level: 17

    Join Date
    Jul 2004
    Location
    Hungary
    Posts
    476
    Helped
    189 / 189
    Points
    5,693
    Level
    17

    Re: Logic Contention(s) Detected on data lines of LCD [Proteus Error]

    While you read any data from the LCD, have to change temporarily the direction of the used pins (RD4...7).



  5. #5
    Full Member level 1
    Points: 2,617, Level: 11
    Achievements:
    7 years registered

    Join Date
    Oct 2007
    Location
    Lahore
    Posts
    107
    Helped
    29 / 29
    Points
    2,617
    Level
    11

    Re: Logic Contention(s) Detected on data lines of LCD [Proteus Error]

    Quote Originally Posted by armghan11 View Post
    here is the attachment
    Use this Driver Code 16x4
    Code:
    // Flex_LCD416.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 16x4 Hitach LM041L 
    #define LCD_LINE_1_ADDRESS 0x80 
    #define LCD_LINE_2_ADDRESS 0xC0 
    #define LCD_LINE_3_ADDRESS 0x90 
    #define LCD_LINE_4_ADDRESS 0xD0 
    
    // 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_PIN 
    int8 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.3 
    
    retval = 0; 
    
    input(LCD_DB4); 
    input(LCD_DB5); 
    input(LCD_DB6); 
    input(LCD_DB7); 
    
    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_PIN 
    int8 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_PIN 
    while(bit_test(lcd_read_byte(),7)) ; 
    #else 
    delay_us(60); 
    #endif 
    
    if(address) 
       output_high(LCD_RS); 
    else 
       output_low(LCD_RS); 
          
     delay_cycles(1); 
    
    #ifdef USE_RW_PIN 
    output_low(LCD_RW); 
    delay_cycles(1); 
    #endif 
    
    output_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_PIN 
    output_low(LCD_RW); 
    #endif 
    
    output_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_PIN 
    char 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



  6. #6
    Banned
    Points: 23,048, Level: 36

    Join Date
    Dec 2012
    Location
    Bangalore, India
    Posts
    4,294
    Helped
    830 / 830
    Points
    23,048
    Level
    36

    Re: Logic Contention(s) Detected on data lines of LCD [Proteus Error]

    Maybe you have defined the LCD pins as input pins somewhere or you have not done the tris setting for output.



    •   AltAdvertisment

        
       

  7. #7
    Member level 1
    Points: 594, Level: 5

    Join Date
    Oct 2012
    Posts
    41
    Helped
    0 / 0
    Points
    594
    Level
    5

    Re: Logic Contention(s) Detected on data lines of LCD [Proteus Error]

    Quote Originally Posted by iukhan View Post
    Use this Driver Code 16x4
    Code:
    // Flex_LCD416.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 16x4 Hitach LM041L 
    #define LCD_LINE_1_ADDRESS 0x80 
    #define LCD_LINE_2_ADDRESS 0xC0 
    #define LCD_LINE_3_ADDRESS 0x90 
    #define LCD_LINE_4_ADDRESS 0xD0 
    
    // 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_PIN 
    int8 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.3 
    
    retval = 0; 
    
    input(LCD_DB4); 
    input(LCD_DB5); 
    input(LCD_DB6); 
    input(LCD_DB7); 
    
    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_PIN 
    int8 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_PIN 
    while(bit_test(lcd_read_byte(),7)) ; 
    #else 
    delay_us(60); 
    #endif 
    
    if(address) 
       output_high(LCD_RS); 
    else 
       output_low(LCD_RS); 
          
     delay_cycles(1); 
    
    #ifdef USE_RW_PIN 
    output_low(LCD_RW); 
    delay_cycles(1); 
    #endif 
    
    output_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_PIN 
    output_low(LCD_RW); 
    #endif 
    
    output_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_PIN 
    char 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
    yes its working fine now :) thanks
    please tell me what was i doing wrong? i would like to know



  8. #8
    Full Member level 1
    Points: 2,617, Level: 11
    Achievements:
    7 years registered

    Join Date
    Oct 2007
    Location
    Lahore
    Posts
    107
    Helped
    29 / 29
    Points
    2,617
    Level
    11

    Re: Logic Contention(s) Detected on data lines of LCD [Proteus Error]

    Quote Originally Posted by armghan11 View Post
    yes its working fine now :) thanks
    please tell me what was i doing wrong? i would like to know
    Since you are using R/W pin, the driver code read the LCD busy bit while(bit_test(lcd_read_byte(),7)); before sending data. the direction of (LCD_DB4 - 7) microcontroller is set to output. The direction of LCD data pins are also output in read mode. - i.e. two outputs trying to drive in different directions, resulting in a large flow of current and causing Logic Contention Detected.

    I just changed the direction of controller pins to inputs before enabling LCD_E in lcd_read_byte() function. input(LCD_DB4); input(LCD_DB5); input(LCD_DB6);input(LCD_DB7);

    Note: CCS compiler automatically change the direction to input or output with input() and output_Low/high statements provided that fast_IO directive is not used.



--[[ ]]--