Får inte fart på en OLED (HD44780), mikroC

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
Greve Hamilton
EF Sponsor
Inlägg: 544
Blev medlem: 4 september 2004, 15:03:35
Ort: GBG

Får inte fart på en OLED (HD44780), mikroC

Inlägg av Greve Hamilton »

Hallå där.

Jag sitter och försöker få igång på en display, men det vill sig inte alls; det är bara svart.

Programmet körs på en PIC16F877A i 20MHz:

Kod: Markera allt

/*

    Display i 4-bit läge
    
    PORTD       LCD
    RD7   ->    D7
    RD6   ->    D6
    RD5   ->    D5
    RD4   ->    D4

    RD3   ->    E
    RD2   ->    RS

    WR på LCD är ansluten till GND.

*/

#define   E     PORTD.F3
#define   RS    PORTD.F2
#define   LEDG  PORTC.F7

void Lcd_Send4bit(char lcd_data) {
     E = 0;
     PORTD = (PORTD & 0x0F) | (lcd_data & 0xF0);      // Send upper nibble
     E = 1;
     delay_us(40);
     E = 0;
     PORTD = (PORTD & 0x0F) | (lcd_data << 4);        // Send lower nibble
     E = 1;
     delay_us(40);
}

void Lcd_Text(char ascii_) {
     RS = 1;                    // Send to LCD-DDRAM (Data)
     Lcd_Send4bit(ascii_);
}

void Init_Lcd() {

     delay_ms(40);            // Wait for LCD to power up

     RS = 0;                  // Instructions

     E = 0;
     PORTD = 0b00110000;      // 0x30
     E = 1;
     delay_ms(5);
     E = 0;
     PORTD = 0b00110000;      // 0x30
     E = 1;
     delay_us(100);
     E = 0;
     PORTD = 0b00110000;      // 0x30
     E = 1;
     delay_us(40);

     E = 0;
     PORTD = 0b00100000;      // set 4-bit
     E = 1;
     delay_us(40);

     Lcd_Send4bit(0b00101000);                       // 4-bit, 2 lines, 5x8

     Lcd_Send4bit(0b00010100);                       // Cursor move right

     Lcd_Send4bit(0b00001100);                       // LCD on, cursor/blink off

     Lcd_Send4bit(0b00000110);                       // Entry mode set

     Lcd_Send4bit(0b00000010);                       // Address=0 (return home)
     delay_ms(2);                                    // > 1.52 ms

     Lcd_Send4bit(0b00000001);                       // Clear display

     delay_ms(20);

}

void main () {

/* I/O Settings */

TRISA = 0b11111111;
TRISB = 0b11111111;
TRISC = 0b00010100;
TRISD = 0b00000001;
TRISE = 0b11111000;

PORTA = 0x00;
PORTB = 0x00;
PORTC = 0x00;
PORTD = 0x00;
PORTE = 0x00;

Init_Lcd();

Lcd_Text(0b01000011);               // Print "C"

while (1) {
    LEDG = 1;                       // Fastnade inte i init, således.
}

}
Någon som vet vad som kan vara knas? Hårdvaran är OK, då LCD:n fungerar med ett annat program. På det fungerande programmet skrev jag inte rutinerna till LCD:n själv.

EDIT: Ändrade rubrik: LCD -> OLED.

/GH
Senast redigerad av Greve Hamilton 15 oktober 2008, 23:01:25, redigerad totalt 2 gånger.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> det är bara svart.

Definiera "svart".
Är det en tvåraders ?
Fungerar kontrastjusteringen ?
Får du en grå och en blank rad ?
Användarvisningsbild
Greve Hamilton
EF Sponsor
Inlägg: 544
Blev medlem: 4 september 2004, 15:03:35
Ort: GBG

Inlägg av Greve Hamilton »

Egentligen är det en OLED, därav mitt slarviga ordval, ber om ursäkt. Jag menar att det inte blir några tecken på displayen alls.

Tvåraders OLED med fungerande kontrast (eftersom den fungerar bra med en annan programkod).
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Aha, OLED, glöm mina frågor, speciellt den sista...
Användarvisningsbild
slatte
Inlägg: 420
Blev medlem: 1 april 2008, 16:05:17
Ort: Jönköping

Inlägg av slatte »

Kör du inte initieringen för 8-bitars interface ser ut som det, hade för mig att 4-bit interfacet skickade man.
0011
(delay 5ms)
0011
0011
.
.
.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

"0011" är ju samma sak som "0011xxxx" om man inte använder "xxxx"...

Och innan man växlar till 4-bit så är själva LCD'n i 8-bits mode, oavsett
om man har kopplat 4 eller 8 trådar till den.
Användarvisningsbild
Greve Hamilton
EF Sponsor
Inlägg: 544
Blev medlem: 4 september 2004, 15:03:35
Ort: GBG

Inlägg av Greve Hamilton »

Slatte:

Men det blir väl samma sak eftersom D0-D3 på displayen är kopplade till GND och alltså kommer att tolkas som nollor de första gångerna fram tills att jag byter till 4-bit?

EDIT: SuperSodjan hann före.
Senast redigerad av Greve Hamilton 15 oktober 2008, 22:57:48, redigerad totalt 1 gång.
Användarvisningsbild
slatte
Inlägg: 420
Blev medlem: 1 april 2008, 16:05:17
Ort: Jönköping

Inlägg av slatte »

inte helt hundra att jag hänger med men skickar inte han
0011
0000
0011
0000
0011
0000

EDIT: BAH BAH sry nu såg jag oki jag hänger med sry !!!
Läste något som inte fanns där ;-)
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> ...eftersom D0-D3 på displayen är kopplade till GND

Har går uppfattningen lite isär. Jag tror att man ska lämna de oanvända
datalinjerna på LCD'n öppna, de har interna pullups på själva LCD modulen.
Anledningen är att man kan råka sätta den i "read-mode", speciellt innan
processorn har startat upp riktigt, och då kommer LCD'n att försöka
driva alla 8 datalinjerna vilket ger en kortis till GND på 4 av dom.

Det stämmer även övrens om man googlar lite eller kollar ett (original)
datablad för HD44780...

Så, lämna de bara "öppna"...
Användarvisningsbild
BEEP
EF Sponsor
Inlägg: 1593
Blev medlem: 21 januari 2006, 16:57:56
Ort: Mölndal

Inlägg av BEEP »

Har du kollat att alla fördröjningar är tillräckligt långa och rätt placerade?
Användarvisningsbild
Marta
EF Sponsor
Inlägg: 7487
Blev medlem: 30 mars 2005, 01:19:59
Ort: Landskrona
Kontakt:

Inlägg av Marta »

Funktionen som skickar 4-bit till displayen sänker ju inte E efter att den lagt ut tecknet. Det är den negativa flanken som låser data.

Vad genererar compilern för kod på alla de logiska operationerna och skiften? Nu är jag kanske ute på rejält hal is, men kan det vara så att den använder porten som temporärt register för dessa? I så fall går det käpprätt åt h-e eftersom E kommer att fladdra som ett höstlöv.
Användarvisningsbild
Greve Hamilton
EF Sponsor
Inlägg: 544
Blev medlem: 4 september 2004, 15:03:35
Ort: GBG

Inlägg av Greve Hamilton »

sodjan: OK, jag ska göra så. Just nu är dock kortet etsat, så jag får väl plocka fram dremeln och fräsa.

BEEP: Ja, vad jag kan se är alla fördröjningar korrekta, har trippelkollat.

Marta: Satan, det är ju den negativa flanken som låser. Jag fick för mig att det var på positiv flank. Jag ändrade i programmet nu, men det hjälpte inte alls.

Nu ser det ut så här:

Kod: Markera allt

/*

    OLED i 4-bit-läge:

    PORTD       LCD
    RD7   ->    D7
    RD6   ->    D6
    RD5   ->    D5
    RD4   ->    D4

    RD3   ->    E
    RD2   ->    RS

    WR på OLED är ansluten till GND.

*/

#define   E     PORTD.F3
#define   RS    PORTD.F2
#define   LEDG  PORTC.F7

void E_toggle() {
     E = 1;
     asm {
     nop 
     nop 
     nop
     };           // Delay 0,6us
     E = 0;
}

void Lcd_Send4bit(char lcd_data) {
     PORTD = (PORTD & 0x0F) | (lcd_data & 0xF0);      // Send upper nibble
     E_toggle();
     delay_us(40);
     PORTD = (PORTD & 0x0F) | (lcd_data << 4);        // Send lower nibble
     E_toggle();
     delay_us(40);
}

void Lcd_Text(char ascii_) {
     RS = 1;                    // Send to LCD-DDRAM (Data)
     Lcd_Send4bit(ascii_);
}

void Init_Lcd() {

     delay_ms(40);              // Wait for LCD to power up

     RS = 0;                    // Instructions

     PORTD = 0b00110000;        // 0x30
     E_toggle();
     delay_ms(5);
     PORTD = 0b00110000;        // 0x30
     E_toggle();
     delay_us(100);
     PORTD = 0b00110000;        // 0x30
     E_toggle();
     delay_us(40);

     PORTD = 0b00100000;        // Set 4-bit
     E_toggle();
     delay_us(40);

     Lcd_Send4bit(0b00101000);           // 4-bit, 2 lines, 5x8

     Lcd_Send4bit(0b00010100);           // Cursor move right

     Lcd_Send4bit(0b00001100);           // LCD on, cursor/blink off

     Lcd_Send4bit(0b00000110);           // Entry mode set

     Lcd_Send4bit(0b00000010);           // Address=0 (return home)
     delay_ms(2);                        // Delay > 1.52 ms

     Lcd_Send4bit(0b00000001);           // Clear display

     delay_ms(20);

}

void main () {

/* I/O Settings */

TRISA = 0b11111111;
TRISB = 0b11111111;
TRISC = 0b00010100;
TRISD = 0b00000001;
TRISE = 0b11111000;

PORTA = 0x00;
PORTB = 0x00;
PORTC = 0x00;
PORTD = 0x00;
PORTE = 0x00;

Init_Lcd();

Lcd_Text(0b01000011);               // Print "C"

while (1) {
    LEDG = 1;                       // Fastnade inte i init, således.
}

}
Jag har mycket begränsade kunskaper i assembler, men så här ser koden ut för de logiska funktionerna i rutinen Lcd_Send4bit.

Kod: Markera allt

// PORTD = (PORTD & 0x0F) | (lcd_data & 0xF0);

MOVLW	15
BCF	STATUS, RP1
BCF	STATUS, RP0
ANDWF	PORTD, 0
MOVWF	STACK_1
MOVLW	240
ANDWF	FARG_Lcd_Send4bit+0, 0
MOVWF	STACK_0
MOVF	STACK_0, 0
IORWF	STACK_1, 0
MOVWF	PORTD
och...

Kod: Markera allt

// PORTD = (PORTD & 0x0F) | (lcd_data << 4);

MOVLW	15
ANDWF	PORTD, 0
MOVWF	STACK_2
MOVF	FARG_Lcd_Send4bit+0, 0
MOVWF	STACK_0
RLF	STACK_0, 1
BCF	STACK_0, 0
RLF	STACK_0, 1
BCF	STACK_0, 0
RLF	STACK_0, 1
BCF	STACK_0, 0
RLF	STACK_0, 1
BCF	STACK_0, 0
MOVF	STACK_0, 0
IORWF	STACK_2, 0
MOVWF	PORTD
Jag testade att byta ur PORTD just inne i maskningen till en temporär variabel i stil med:

Kod: Markera allt

void Lcd_Send4bit(char lcd_data) {
     char temp_portd = PORTD;
     PORTD = (temp_portd & 0x0F) | (lcd_data & 0xF0);
     ...
     ...
     PORTD = (temp_portd & 0x0F) | (lcd_data << 4);
     ...
     ...
}
Men det hjälpte inte.
Senast redigerad av Greve Hamilton 16 oktober 2008, 14:47:55, redigerad totalt 1 gång.
Användarvisningsbild
Marta
EF Sponsor
Inlägg: 7487
Blev medlem: 30 mars 2005, 01:19:59
Ort: Landskrona
Kontakt:

Inlägg av Marta »

Förfärligt ineffektiv kod som compilern skapar, men den gör det den skall och använder en temporär adress och något annat var väl inte hellre väntat.

Är initieringen OK, med alla analoga saker o.dyl. avstängda, om där nu finns sådant?
Användarvisningsbild
Icecap
Inlägg: 26659
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Jag skulle föreslå att du sänker hastigheten våldsamt och faktisk kollar medelst 4 st LED + en till vardera Enable och R/S och ser om handskakningen och data är korrekt.
Användarvisningsbild
Greve Hamilton
EF Sponsor
Inlägg: 544
Blev medlem: 4 september 2004, 15:03:35
Ort: GBG

Inlägg av Greve Hamilton »

Tack Marta, du ledde mig in på rätt spår.

Jag hade råkat sätta TRISE så att PSPMODE aktiverades, vilket använder PORTD.

"TRISE = 0b00000000;" blir rätt.

Tack för hjälpen, nu fungerar det.
Skriv svar