Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

lcm1602 i2c lcd driver 2x16 at 3.3V instead of 5V?

Status
Not open for further replies.

Alloy

Advanced Member level 4
Joined
Apr 3, 2016
Messages
116
Helped
0
Reputation
0
Reaction score
0
Trophy points
16
Activity points
1,003
Hey
I have this module:
i2c_backpack_01-1024x527.jpg
I want to run it from 3.3V logic levels (PIC32).
Do I just connected it all to 3.3V levels? Or it won't work?
 

If the LED module is designed for 5V, neither the LED backlight nor the contrast adjustment will work.
 

OK so I connected 5V+ to VCC and SDA/SCL to 3.3PIC.
It works partially, but...
lcd_i2c.jpg
Please take a look, that LCD works well with ARDUINO and I2C arduino library.
Is this bug in display related to the new hardware?
Or maybe mine I2C LCD communication code has some error ( I haven ttested it, its based on sources from web)
 

If you take the I2C level specifications for PCF8574 exactly, a 3.3V to 5V I2C level converter would be required. Typically it will work though. I rather guess that it's a code bug.
 

Hi,

We don't know if you wrote something to the second line, so we can only guess.

It seems the second line has some problems, one can only see the upper half. Then it is a defective display.

Klaus
 

Yes I write to second line.

It seems the second line has some problems, one can only see the upper half. Then it is a defective display.
No, it worked well with Arduino just 15 minutes before I connected it to the PIC.

Here is my code:
LCD:
Code:
#include <stdint.h>
       #include "lcd.h"
       
#define bit_test(var,pos) ((var) & (1<<(pos)))
                   
  uint8_t  LCD_BL_Status = 1;     // 1 for POSITIVE control, 0 for NEGATIVE control

uint8_t  pin_E;//   =    I2C_BYTE.2
uint8_t  pin_RW;//  =    I2C_BYTE.1
uint8_t  pin_RS;//  =    I2C_BYTE.0
uint8_t  pin_D4;//  =    I2C_BYTE.4
uint8_t  pin_D5;//  =    I2C_BYTE.5
uint8_t  pin_D6;//  =    I2C_BYTE.6
uint8_t  pin_D7;//  =    I2C_BYTE.7
uint8_t  pin_BL;//  =    I2C_BYTE.3

int LCD_Open()
{
    int status;
    I2C2_Stop();
    I2C2_Init(100000);
    ///SSPADD = 0x09;
    I2C2_Start();
    status = I2C2_Write(LCD_PIC_I2C_ADDR);          // Tell all I2C devices you are talking to LCD_PIC_I2C_ADDR
   return status == 0;
}
void LCD_Close()
{
    //IdleI2C();
    I2C2_Stop();
}

void LCD_BL(uint8_t status)
{
    LCD_BL_Status = status;
    LCD_Write_Byte(0x00, 0x00);
}

int LCD_Init()
{
    int s = LCD_Open();
     if(s == 0)
     return 0;
    // return 1;
    // Following bytes are all Command bytes, i.e. address = 0x00
    LCD_Write_Byte(0x00, 0x03);   // Write Nibble 0x03 three times (per HD44780U initialization spec)
    delay_ms(5);                // (per HD44780U initialization spec)
    LCD_Write_Byte(0x00, 0x03);   //
    delay_ms(5);                // (per HD44780U initialization spec)
    LCD_Write_Byte(0x00, 0x03);   //
    delay_ms(5);                // (per HD44780U initialization spec)
    LCD_Write_Byte(0x00, 0x02);   // Write Nibble 0x02 once (per HD44780U initialization spec)
    delay_ms(5);
    LCD_Write_Byte(0x00, 0x02);   // Write Nibble 0x02 once (per HD44780U initialization spec)
    delay_ms(5);                // (per HD44780U initialization spec)
    LCD_Write_Byte(0x00, 0x01);   // Set mode: 4-bit, 2+lines, 5x8 dots
    delay_ms(5);                // (per HD44780U initialization spec)
    LCD_Write_Byte(0x00, 0x0C);   // Display ON 0x0C
    delay_ms(5);                // (per HD44780U initialization spec)
    LCD_Write_Byte(0x00, 0x01);   // Clear display
    delay_ms(5);                // (per HD44780U initialization spec)
    LCD_Write_Byte(0x00, 0x06);   // Set cursor to increment
    delay_ms(5);                // (per HD44780U initialization spec)

  //  LCD_Close();
     return 1;
}

void LCD_Goto(uint8_t x, uint8_t y)
{
uint8_t address;

   switch(y)
     {
      case 1:
        address = LCD_PIC_LINE_1_ADDRESS;
        break;

      case 2:
        address = LCD_PIC_LINE_2_ADDRESS;
        break;

      case 3:
        address = LCD_PIC_LINE_3_ADDRESS;
        break;

      case 4:
        address = LCD_PIC_LINE_4_ADDRESS;
        break;

      default:
        address = LCD_PIC_LINE_1_ADDRESS;
        break;
     }

   address += x-1;
   LCD_Write_Byte(0, 0x80 | address);
}

//===================================
void LCD_Write_String(const char *str)
{
   // Writes a string text[] to LCD via I2C
   pin_RS  = 1;
   pin_RW  = 0;
   pin_E   = 0;
   pin_BL  = LCD_BL_Status;

   while (*str)
   {
        // Send upper nibble
        _LCD_Write_Upper_Nibble(*str);

        // Send lower nibble
        _LCD_Write_Lower_Nibble(*str);

        str++;
   }
}

void LCD_Write_Char(char c)
{
    LCD_Write_Byte(0x01,c);
}

void LCD_Write_Int(int32_t num)
{
    uint8_t number[10];
    int i;
    uint8_t num_count = 0;
    
    if (num < 0) { LCD_Write_String("-"); num *= -1; }


    do {
        number[num_count] = num % 10;
        num_count++;
        num /= 10;
    } while (num > 0);

    for ( i = num_count-1; i>= 0; i--)
    {
        LCD_Write_Char(number[i] + 0b00110000);
    }
}

//===================================
void LCD_Write_Byte(uint8_t address, uint8_t n)
{
    if (address)
    {
        pin_RS=1;   // Data
    }
    else
    {
        pin_RS=0;   // Command
    }

    pin_RW  = 0;
    pin_E   = 0;
    pin_BL  = LCD_BL_Status;

    // Send upper nibble
   _LCD_Write_Upper_Nibble(n);

    // Send lower nibble
   _LCD_Write_Lower_Nibble(n);
}

void LCD_Clear()
{
    LCD_Write_Byte(0x00,0x01);
    delay_ms(5);
}

void LCD_Clear_Line(uint8_t line)
{
    int i;
    LCD_Goto(1,line);
    for (i = 0; i<20; i++)
    {
        LCD_Write_String(" ");
    }
    LCD_Goto(1,line);
}

void _LCD_Write_Upper_Nibble(uint8_t u)
{
    // Send upper nibble
    if(bit_test(u,7))
        pin_D7=1;
    else
        pin_D7=0;

    if(bit_test(u,6))
        pin_D6=1;
    else
        pin_D6=0;

    if(bit_test(u,5))
        pin_D5=1;
    else
        pin_D5=0;

    if(bit_test(u,4))
        pin_D4=1;
    else
        pin_D4=0;

   pin_E = 0;
   I2C2_Write(_LCD_Build_Byte());
   pin_E = 1;
   I2C2_Write(_LCD_Build_Byte());
   pin_E = 0;
   I2C2_Write(_LCD_Build_Byte());
}

void _LCD_Write_Lower_Nibble(uint8_t l)
{
    // Send lower nibble
    if(bit_test(l,3))
        pin_D7=1;
    else
        pin_D7=0;

    if(bit_test(l,2))
        pin_D6=1;
    else
        pin_D6=0;

    if(bit_test(l,1))
        pin_D5=1;
    else
        pin_D5=0;

    if(bit_test(l,0))
        pin_D4=1;
    else
        pin_D4=0;

    pin_E = 0;
    I2C2_Write(_LCD_Build_Byte());
    pin_E = 1;
    I2C2_Write(_LCD_Build_Byte());
    pin_E = 0;
    I2C2_Write(_LCD_Build_Byte());
}

uint8_t _LCD_Build_Byte()
{
    uint8_t ret = 0x00;

    ret |= pin_E    << 2;
    ret |= pin_RW   << 1;
    ret |= pin_RS   << 0;
    ret |= pin_D4   << 4;
    ret |= pin_D5   << 5;
    ret |= pin_D6   << 6;
    ret |= pin_D7   << 7;
    ret |= pin_BL   << 3;

    return ret;
}
MAIN:
Code:
 #include <stdint.h>
 #include "lcd.h"

void main() {
  JTAGEN_bit = 0;        // Disable JTAG
  /* ADC Digital Mode */
  ANSELA = 0;
  ANSELB = 0;
  TRISA = 0;             // Initialize PORTA as output
  TRISB = 0;             // Initialize PORTB as output
  LATA = 0;              // Set PORTA to zero
  LATB = 0;              // Set PORTB to zero
  
  while(LCD_Init()==0)
  {
    LATA = ~PORTA;       // Invert PORTA value
    LATB = ~PORTB;       // Invert PORTB value
    Delay_ms(100);
  }
 LCD_Clear();
 
  LCD_Write_String("Hello");
    Delay_ms(10);
  LCD_Goto(9,1);
    Delay_ms(10);
  LCD_Write_String("Aaa");
    Delay_ms(10);
  LCD_Goto(1,2);
    Delay_ms(10);
  LCD_Write_String("TEST");
    Delay_ms(10);
  LCD_Goto(5,2);
    Delay_ms(10);
  LCD_Write_String("Row2");
    Delay_ms(10);

    /////Delay_ms(10000);
  while(1) {
    LATA = ~PORTA;       // Invert PORTA value
    LATB = ~PORTB;       // Invert PORTB value
    LCD_BL(0);
    Delay_ms(1000);
    LATA = ~PORTA;       // Invert PORTA value
    LATB = ~PORTB;       // Invert PORTB value
    LCD_BL(1);
    Delay_ms(1000);
  }
}
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top