Initiera HD44780, AtMega16, 4-bit, lyckas inte...

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
gunne
Inlägg: 2088
Blev medlem: 17 juni 2004, 15:00:31
Ort: sthlm
Kontakt:

Initiera HD44780, AtMega16, 4-bit, lyckas inte...

Inlägg av gunne »

Jag försöker initiera en 20x4 LCD med en HD44780-kontroller till min AtMega16. Det finns bara en HD44780-krets på LCDn trots att den har 4 rader. Databladet till HD44780 finns här.
(Jag har redan tidigare disskuterat detta i "optokomponenter", men tråden blev lång och ohanterlig så jag gör ett nytt försök här. Stort tack till alla som har svarat där!:))

Pinnarna är kopplade så här:

Kod: Markera allt


D7 D6 D5 D4 D3 D2 D1 D0 E  R/W RS Vee Vcc GND
|  |  |  |  |  |  |  |  |   |  |   |   |   |
P3 P2 P1 P0 GNDGNGNDGND P4 GND P5 GND Vtg GND 

Bild
(Det till vänster är min 32,768kHz-kristall för tidtagning.)

Sen har jag kopplat det till mitt STK500 på port B.

Bild

Det här är min kod:

Kod: Markera allt

#include <avr/io.h>

void init_clock(void);
void delay(unsigned long int del);
void write_lcd(unsigned char byte);
void write_char(unsigned char byte);
void toggle_E(void);
void init_lcd(void);

#define LCD PORTB		// Port som LCDn sitter på
#define LCD_DDRX DDRB

// Sätter igång timer2 i asynkront läge med 32,768-kristall
void init_clock(void) {

	ASSR|=0x08;		//async mode
	TCCR2|=0x01;	//clear timer no prescaler
	TIFR=0x40;		//start timer
}

// Fördröjer med _del_ tusendelar av en sekund. För exakt en sekund använd del = 1024
void delay(unsigned long int del){
unsigned long int i=0;
unsigned char wait=0;

	for(i=0;i<del;i++) {		
		wait=TCNT2+31;
		while(wait!=TCNT2) {}	//Vänta på klockan
	}
}

//Skriver ut en halv byte till LCDn
void write_lcd(unsigned char byte) {

	LCD&=0xF0;		// Nollställ D7-D4
	LCD|=byte&0x0F;	// Lägg ut nedersta 4 bitarna

	toggle_E();   // toggla E
}

//Skriver ut en byte till LCDn
void write_char(unsigned char byte) {	
	write_lcd(byte>>4);	// Lägg ut översta 4 bitarna
	delay(1);
	write_lcd(byte);	// Lägg ut nedersta 4 bitarna
}

void toggle_E(void) {

	delay(1);		// Fördröj x tusendelar
	LCD|=0x10;		// Sätt E till 1
	delay(1);		// Fördröj x tusendelar
	LCD&=~0x10;		// Sätt E till 0
	delay(1);		// Fördröj x tusendelar
}


void init_lcd(void) {

	LCD_DDRX=0xFF;	// LCD-porten som utgång
	LCD=0x00;		// Alla pinnar på lcd till 0
	delay(25);		// Vänta lite med initieringen
	
	// initiera LCDn
	write_lcd(0x03); 	// 8-bitläge
	delay(6); 
	write_lcd(0x03); 	// 8-bitläge
	delay(2); 
	write_lcd(0x03); 	// 8-bitläge
	delay(1); 

	write_lcd(0x02); 	// 4-bitläge
	delay(1); 

	write_lcd(0x02); 	// 2 rader, 5x8-tecken 
	delay(1); 
	write_lcd(0x08); 
	delay(1); 

	write_lcd(0x00);	// display off
	delay(1); 
	write_lcd(0x08); 
	delay(1); 

	write_lcd(0x00);	// display clear
	delay(1); 
	write_lcd(0x01); 
	delay(1); 

	write_lcd(0x00); 	// increment
	delay(1); 
	write_lcd(0x06); 
	delay(1); 
}

int main(void) // main program starts
{
	DDRA=0xFF;	// PortA till utgång för felsökning med lysdioder

	init_clock();	// Starta timern
	init_lcd();		// Initiera lcd:n

	LCD|=0x20;		// RS =1 för att skicka data

	write_char(0x4C);	// Skriv ett L
	write_char(0x43);	// Skriv ett C
	write_char(0x44);	// Skriv ett D

	while(1) {} 
} 
Bild

Resultatet ser ut så här. Två svarta rader.

Jag har testat delay-funktionen genom att blinka dioder i exakt en Hz, ½ Hz osv och det funkar perfekt. En delay(1) ger således en fördröjning på lite under en tusendel.

Jag har testat att min write_lcd-funktion fungerar dels genom att kolla i debuggern och genom att mäta på pinnarna efter att jag kallat funktionen. T.ex. resulterar write_lcd(0x03) i att D7-D4 är 0011 när jag mäter på LCDn. På samma sätt har jag testat min toggle_E-funktion och att sätta RS.

Jag har även testat att dunka på en prescaler på timern för att fördröja allt ytterligare. Har till och med lagt på så mkt fördröjning att man kan följa initieringsprocessen genom att sätta en PORTA=LCD när portA är kopplat till lysdioder.

Vad är det som är galet? Konrasten funkar ju eftersom jag ser svarta rutor. Jag har även testat att löda på en likadan kontakt på en 16x2-LCD med samma resultat.

Alla tips mottages. Just nu har hela mitt projekt avstannat bara för att jag inte lyckas med nåt så trivialt som att initiera en LCD. :cry:
Användarvisningsbild
klasg
Inlägg: 187
Blev medlem: 29 juni 2005, 21:12:24

Inlägg av klasg »

Nu kan inte jag AVR, har inte heller kikat i databladet till displayen.
Men ett hett tips är att vänta ett tag mellan initieringen och skicka tecken till den.

EDIT: Skulle tre sidor vara en lång och ohanterlig tråd?
Användarvisningsbild
Icecap
Inlägg: 26648
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Kod: Markera allt

//Skriver ut en halv byte till LCDn
void write_lcd(unsigned char byte)
  {
   LCD&=0xF0;      // Nollställ D7-D4
   LCD|=byte&0x0F;   // Lägg ut nedersta 4 bitarna
   toggle_E();   // toggla E
  }

//Skriver ut en byte till LCDn
void write_char(unsigned char byte)
  {
  write_lcd(byte>>4);   // Lägg ut översta 4 bitarna
  delay(1);
  write_lcd(byte);   // Lägg ut nedersta 4 bitarna
  }
Först flyttar du datan till den låga nipple....varefter du nollar just databitsen....
Det ska väl vara:

Kod: Markera allt

void write_char(unsigned char data)
  {
  write_lcd(Data);   // Lägg ut översta 4 bitarna
  delay(1);
  write_lcd(Data << 4);   // Lägg ut nedersta 4 bitarna
  }
Användarvisningsbild
gunne
Inlägg: 2088
Blev medlem: 17 juni 2004, 15:00:31
Ort: sthlm
Kontakt:

Inlägg av gunne »

3 sidor är inte så långt. Men olika felskrivningar av mej ledde till onödigt snack om olika saker + att tråden passar bättre här i mC-delen.

Angående min funktion write_lcd så har jag tänkt så här:

Jag nollar pinnarna D7-D4 medans resten av pinnarna har kvar sitt ursprungliga läge. Detta för att kunna lägga ut ettorna på dessa pinnar med ett &.

ex:

Vi vill lägga ut 0011 på D7-D4
LCD är 1010 1100 säger vi, där de sista bitarna 1100 är D7-D4
LCD&=0xF0 gör att LCD blir 1010 0000
LCD|=0000 0011 gör sen att LCD blir 1010 0011

Jag nollar pinnarna på porten och inte bitarna i variabeln byte.

Rätta mej om jag har fel...
Användarvisningsbild
Porto
EF Sponsor
Inlägg: 437
Blev medlem: 27 mars 2004, 12:58:48

Inlägg av Porto »

gunne:
> Konrasten funkar ju eftersom jag ser svarta rutor

Du har ingen trimpot på kontrasten (mellan gnd och vcc) så att du kan justera lite - är den alldeles för mycket fel så kan det bli helsvart, delar av displayen svart eller helt grått. (Vissa displayer behöver ca -0,5v för att texten skall synas)

Sedan D0-D3 ska inte anslutas alls vid 4-bit mode, utan skall "hänga fritt".

>T.ex. resulterar write_lcd(0x03) i att D7-D4 är 0011 när jag mäter på LCDn

Har du även kollat att write_char fungerar som du tänkt med skiftningen av bitarna?

Port B har ju även SPI + interrupt ingång + komparator, har du kollat att spänningsnivåerna på port B stämmer (både ettor och nollor) eller prova att koppla displayen till en annan port.

Om man tar in din bild i photoshop och drar lite i kurvorna så ser det ut som det är text under de svarta raderna.
Bild
Senast redigerad av Porto 23 februari 2006, 22:03:40, redigerad totalt 2 gånger.
Kaggen
Inlägg: 432
Blev medlem: 29 januari 2005, 03:06:02

Inlägg av Kaggen »

> LCD är 1010 1100 säger vi, där de sista bitarna 1100 är D7-D4

Vet inte om jag missat något, men är inte bitarna 1100 D3-D0? Mest signifikanta biten eller nibbeln brukar vara längst till vänster och lägst signifikanta längst till höger.

Å andra sidan kanske du har pinkonfigurationen omvänt kopplad?

Mats
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

En kontrollfråga bara...

LCD'er kan ha de 14 kontakterna både ovanför och under själva
displayen. Du har inte vänt den upp och ner ? Står "1" tydligt
angivet på mönsterkortet ?

Sen så...

> Det finns bara en HD44780-krets på LCDn trots att den har 4 rader...

Det är *40x4* (eller 80x2) displayer som har dubbla HD44780.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

En sak till, jag har en *svag* aning om att det är
rad 1 och 3 (inte 2 och 4) som brukar bli grå, men jag
kanske minns helt fel... :-)
Användarvisningsbild
JimmyAndersson
Inlägg: 26579
Blev medlem: 6 augusti 2005, 21:23:33
Ort: Oskarshamn (En bit utanför)
Kontakt:

Inlägg av JimmyAndersson »

Laddade in bilden på LCD'n i Photshop och ökade kontrasten:

Bild

Antingen är det tecken som "bränts" fast eller så har du helt enkelt ställt in för hög kontrast till LCD'n. Visst, den kan vara felinitierad iallafall, men inte helt "oinitierad" (konstigt ord, jag vet..) :)



edit: hahaha, Porto, du gjorde likadant i din edit. Samtidigt dessutom! :D
Användarvisningsbild
vfr
EF Sponsor
Inlägg: 3515
Blev medlem: 31 mars 2005, 17:55:45
Ort: Kungsbacka

Inlägg av vfr »

sodjan skrev:En sak till, jag har en *svag* aning om att det är
rad 1 och 3 (inte 2 och 4) som brukar bli grå, men jag
kanske minns helt fel... :-)
Visst har du rätt! Han har förmodligen LCD:n upp o ner.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Lite sent kanske, men det viktigaste av allt...

Vad heter LCD modulen ?
Länk till datablad ?
Användarvisningsbild
gunne
Inlägg: 2088
Blev medlem: 17 juni 2004, 15:00:31
Ort: sthlm
Kontakt:

Inlägg av gunne »

Smart det där med att kolla kontrasteni photoshop. Men eftersom jag bara har skrivit tre tecken borde det inte va bokstäver under alla? Ska testa med en trimpot i eftermiddag. Har tyvärr ingen inverter att testa med, ska leta efter en sån... Jag tyckte att alla rader borde bli lika svarta/vita om den är initierad rätt. Är det inte så?


När jag säger att LCD är 1010 1100 menar jag att porten som jag kopplat LCDn till är 1010 1100. Detta gör då att de lägsta bitarna ligger på D7-D4 och de andra ligger på RS, E osv enligt pinkonfigurationen i mitt första inlägg.

Jag har inte kopplat kontakterna bakåfram. Har kollat att GND (pin1) har kontakt med LCDns ram.

>Sedan D0-D3 ska inte anslutas alls vid 4-bit mode, utan skall "hänga fritt".
Som jag har förstått det ska de anslutars till jord?

Jag har testat att ansluta den till olika portar (A, B, och D tror jag...)

>Har du även kollat att write_char fungerar som du tänkt med skiftningen av bitarna?
Jajamen!

Jag hade den bara liggandes i en hög när jag tog fotot, det kändes som att orienteringen på bordet hade mindre betydelse för mej...

Här finns datablad för displayen som heter LM044L.
Användarvisningsbild
DeVille
Inlägg: 2361
Blev medlem: 29 mars 2004, 15:04:22
Ort: Dalsländska skogen.
Kontakt:

Inlägg av DeVille »

Efter att du "slagit på" displayen, så ska du vänta ca 10ms gör du det?

Har C kod liggande till en 16x2 display tillsammans med en AT90S8515 om det är intressant.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

I databladet har modulen anslutningarna *upptill*...
Användarvisningsbild
gunne
Inlägg: 2088
Blev medlem: 17 juni 2004, 15:00:31
Ort: sthlm
Kontakt:

Inlägg av gunne »

Jag misstänker att de "tecken" som man ser i era kontrastförhöjda bilder är resultatet av jpeg-komprimeringen. Om LCDn var initierad och visade tecken borde väl alla rader se likadana ut? Att den har varannan rad svart och varannan vit betyder väl att den är oinitierad?
Skriv svar