0
\$\begingroup\$

I am using a PCI1602F-B from Powertip as an LCD and an ATmega8 to communicate with it.

Connection:

-PORT D of ATmega8 with data-bus of LCD

-PORT B0 of ATmega8 with Rs pin

-PORT B1 of ATmega8 with R/W pin

-PORT B2 of ATmega8 with Eneble (E) pin

-I potentiometer is connected to the Contrast Adjust pin (Vo) and I can give it 0 volt to 5 volt.

-The Backlight LED works fine.

-I also give 5 volt to Vss-Vpp

My code is as followes:

#define F_CPU 1000000UL  // 1 MHz

#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>


void En(int bit)
{
    if (bit==0)
        PORTB |= 0b00000100;
    else
        PORTB &= ~0b0000100;
}

void RS(int bit)
{
    if (bit==0)
        PORTB |= 0b00000001;
    else
        PORTB &= ~0b0000001;
}

void RW(int bit)
{
    if (bit==0)
        PORTB |= 0b00000010;
    else
        PORTB &= ~0b0000010;
}

void is_busy (void)
{
    DDRD = 0b00000000;
    RW(1);
    RS(0);
    En(1);
    while (PORTD == 0b10000000)
    {
        En(0);
        _delay_ms(1);
        En(1);
    }
    DDRD = 0b11111111;
}

void send_command(unsigned char command)
{
    is_busy();
    PORTD = command;
    RW(0);
    RS(0);
    En(1);
    _delay_ms(2);
    En(0);
    PORTD = 0b00000000;
}

void send_char(unsigned char character)
{
    is_busy();
    PORTD = character;
    RW(0);
    RS(1);
    En(1);
    _delay_ms(2);
    En(0);
    PORTD = 0b00000000;
}

void init(void)
{
    En(0);
    _delay_ms(100);
    send_command(0b00110000);
    _delay_ms(30);
    send_command(0b00110000);
    _delay_ms(10);
    send_command(0b00110000);
    _delay_ms(10);
    send_command(0b00111000); //Function Set - DL=N=1, F=0
    is_busy();
    send_command(0b00000001); //Clear Display
    is_busy();
    send_command(0b00010100); //Cursor of Display Shift - S/C=0, R/L=1
    is_busy();
    send_command(0b00001100); //Display ON/OFF - D=1, C=B=0
    is_busy();
    send_command(0b00000110); //Entry Mode Set - I/D=1, S=0
}

int main(void)
{
    init();
    send_char(0x81);
    while(1)
    {
    }

    return(0);
}

As you can see I am only trying to print one letter. The letter I am trying to print it "Q". I am sending the Hex ASCII code immediately to the microcontroller.

The LCD does not show anything, have I done something wrong? Is the initialization correct?

\$\endgroup\$
  • 1
    \$\begingroup\$ Schematic is required. \$\endgroup\$ – Leon Heller Jan 18 '15 at 12:27
  • \$\begingroup\$ One thing is it looks to me as though your logic is inverted, RW for example should be low for writing so RW(0) looks OK, but in the function you're setting the pin high. \$\endgroup\$ – PeterJ Jan 18 '15 at 12:49
  • \$\begingroup\$ When you power the LCD up there should be 8 dark squares in the first 8 positions. If not there is probably something wrong with the power and/or the contrast voltage. \$\endgroup\$ – Wouter van Ooijen Jan 18 '15 at 13:02
1
\$\begingroup\$

Some general remarks: First verify that the panel bias is correct. When you turn the potentiometer, you should get absolutely clear LCD in one end and dark blocks in the other end. If you don't get dark blocks then your bias doesn't go low enough. Large LCDs (2x40 chars and bigger) may require up to -10 volts of panel bias (contrast) voltage.


Edit: Your LCD datasheet states maximum bias voltage of 13 volts and it's referenced to VDD. so if you VDD is 5 volts then the minimum voltage at the contrast voltage pin is 5-13 = -8 volts. A good voltage may be somewhere around -5 volts. You can test with another power supply or with some batteries with the + side connected to GND how much negative voltage you need.


When you get the dark blocks by turning the potentiometer, then you can start working with your software; Put also the init in the loop and measure with oscilloscope that all signals are going high and low.

\$\endgroup\$
  • \$\begingroup\$ The LCD bias voltage seems to be the most common reason people have problems with these things because the datasheets are almost all written poorly. This one, for instance, refers to Vee but then lists it as Vo on the pinout. \$\endgroup\$ – Edward Jan 18 '15 at 14:01
  • \$\begingroup\$ @Edward, a good observation: Just to clarify for the original asker: Pin 0 is ground. Pin 1 is logic supply voltage (Vdd), 5V. Pin 2 is the panel bias voltage (Vee), -5V or something like that, marked as Vo on the datasheet. \$\endgroup\$ – PkP Jan 18 '15 at 15:53
0
\$\begingroup\$

I would check all connections, make sure everything is getting the proper current, voltage, and ohms resistance. Also double check your codes. could be a wrong code value wrong code. You say you used a potentiometer it is possible you may have put to many volts to the microprocessor. check it to see if it puts out the correct volts/mA. Also if the board smells burnt then something is definitely fried. make sure all components are not getting too hot. Hope this helps

\$\endgroup\$
0
\$\begingroup\$

All three of your control line subroutines are written incorrectly. They need to be changed as follows:

void En(int bit)
{
    if (bit != 00)
        PORTB |= 0b00000100;
    else
        PORTB &= ~0b0000100;
}

void RS(int bit)
{
    if (bit != 0)
        PORTB |= 0b00000001;
    else
        PORTB &= ~0b0000001;
}

void RW(int bit)
{
    if (bit != 0)
        PORTB |= 0b00000010;
    else
        PORTB &= ~0b0000010;
}
\$\endgroup\$
  • \$\begingroup\$ I'd suggest using macros such as #define CLR(port,pin) port &= ~(pin) and #define SET(port,pin) port |= (pin) and named values such as const int LCD_RW = 2; would greatly improve this code. \$\endgroup\$ – Edward Jan 18 '15 at 16:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.