Trilskandes display (Powertip PC 1602-F, PIC18F2515, LÖST)

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
xarragon
Inlägg: 88
Blev medlem: 3 maj 2006, 14:10:35
Skype: xarragon
Ort: Halmstad
Kontakt:

Trilskandes display (Powertip PC 1602-F, PIC18F2515, LÖST)

Inlägg av xarragon »

Hejsan elektronikvänner, jag har sedan en tid arbetat med en HD44780-kompatibel display från Powertip, PC1602F. Jag har fortfarande inte utrönat exakt vilket kontrollerchip som sitter i denna display ifråga men enligt Farnells datablad verkar det vara en Sitronix ST7066U (http://www.farnell.com/datasheets/55557.pdf), vilken har en helt annan initieringssekvens än vad som står på Powertips egna hemsida.

Koden nedan startar inte upp displayen korrekt alls (har för tillfället inte ens försökt ändra till 2-radersläge), och är baserad EF's wiki för HD44780.

Jag har tidigare försökt initera enligt det länkade databladet, enligt Hitachis HD44780-datablad, enligt Samsungs KS0066U och enligt instruktionerna på
Powertips hemsida. Inget fungerar, den koden var implementerad med SourceBoost-kompilatorn.

Programmeraren är en MPLAB ICD2 USB, Utvecklingsmiljön är MPLAB 8.00, kompilatorn MPLAB C18 3.15a (studentutgåva), kretsen en PIC18F2515 med displayens dataledare D4-D7 ansluten till PortA[0-3] (stigande), enable på PortC[1], register select på PortA[5], read/write på PortC[0].

Hårdvarukopplingen har bevisligen fungerat tidigare, det är i felet mjukvaran ligger såvida ren glappkontakt inte uppstått.

Pic:en har en 10 Mhz kristall och kör med HS-PLL:enablat och fördröjningarna är baserat på 40 Mhz / 10 MIPS, verifierat genom att dra en pinne upp ner med 50 ms fördröjning och kontrollmätt på oscillioskop.

Ingen av de båda initieringsrutinerna verkar fungera. Displayen visar endast den övre radens teckenrutor som massiva block. Ingen text skrivs ut.
Någon med erfarenhet av displayeländet ifråga som har några visdomsord?

Med vänliga hälsningar,
Martin "xarragon" Persson

Kod: Markera allt

#include <p18f2515.h>
#include <delays.h>

// Pin mappings / register mappings
#define DISPLAY_D4 LATAbits.LATA0
#define DISPLAY_D5 LATAbits.LATA1
#define DISPLAY_D6 LATAbits.LATA2
#define DISPLAY_D7 LATAbits.LATA3

#define DISPLAY_E  LATCbits.LATC1
#define DISPLAY_RS LATAbits.LATA5
#define DISPLAY_RW LATCbits.LATC0

void init_elektronikforumet (void);
void init_sitronix (void);

void send_command (unsigned char command);
void delay_us (unsigned char microseconds);
void delay_ms (unsigned char milliseconds);
void display_write_character (unsigned char character);

void main (void)
{
	DDRA = 0x00;
	DDRC = 0x00;
	LATA = 0x00;
	LATC = 0x00;

	//init_elektronikforumet();
	init_sitronix();

	display_write_character('c');

	while (1);	
}

void init_elektronikforumet (void)
{
	delay_ms(250);

	DISPLAY_E = 0;
	DISPLAY_RS = 0;
	DISPLAY_RW = 0;

	send_command(0x03);

	delay_ms(6);

	send_command(0x03);

	delay_us(120);

	send_command(0x03);
	send_command(0x02);
	delay_us(50);

	send_command(0x02);
	send_command(0x08);
	delay_us(50);

	send_command(0x00);
	send_command(0x80);

	send_command(0x00);
	send_command(0x01);
	delay_us(50);

	send_command(0x00);
	send_command(0x06);
	delay_us(50);
}

void init_sitronix (void)
{
	delay_ms(250);

	DISPLAY_E = 0;
	DISPLAY_RS = 0;
	DISPLAY_RW = 0;

	send_command(0x03);

	delay_us(50);

	send_command(0x02);
	send_command(0x02);

	delay_us(50);

	send_command(0x02);
	send_command(0x02);

	delay_us(50);

	send_command(0x00);
	send_command(0x0c);

	delay_us(50);

	send_command(0x00);
	send_command(0x01);

	delay_us(50);

	send_command(0x00);
	send_command(0x06);

	delay_us(50);
}

void send_command (unsigned char command)
{
	unsigned char temp;

	temp = LATA & 0xf0;
	temp |= command & 0x0f;
	LATA = temp;
	delay_us(2);

	DISPLAY_E = 1;
	delay_us(6);
	DISPLAY_E = 0;
	delay_us(6);
}

void delay_us (unsigned char microseconds)
{
	Delay10TCYx(microseconds);
}

void delay_ms (unsigned char milliseconds)
{
	Delay10KTCYx(milliseconds);
}

void display_write_character (unsigned char character)
{
	unsigned char temp;

	DISPLAY_RS = 1;
	DISPLAY_RW = 1;
	delay_us(2);

	temp = LATA;
	temp &= (character >> 4) | 0xf0;
	temp |= (character >> 4) & 0x0f;
	LATA = temp;

	DISPLAY_E = 1;
	delay_us(6);
	DISPLAY_E = 0;
	delay_us(6);

	temp = LATA;
	temp &= character | 0xf0;
	temp |= character & 0x0f;
	LATA = temp;

	DISPLAY_E = 1;
	delay_us(6);
	DISPLAY_E = 0;
	delay_us(6);

	delay_us(50);
}
Senast redigerad av xarragon 26 mars 2008, 15:29:48, redigerad totalt 1 gång.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> Hårdvarukopplingen har bevisligen fungerat tidigare,

Hur menar du då ? Vad är beviset ? Har samma LCD fungerat tidigare ?

Stänger C18 själv av de analoga funktioner på pinnar ? Utan att man
behöver göra något i koden ?
xarragon
Inlägg: 88
Blev medlem: 3 maj 2006, 14:10:35
Skype: xarragon
Ort: Halmstad
Kontakt:

Inlägg av xarragon »

Det är en hårdvaruplattform, exakt den här displayen har fungerat med exakt den här plattformen tidigare. Hårdvaran är oförändrad. Jag har satt PortB till digitalläge med konfigurationsbitarna för AD-omvandlaren.

Jag testkörde den tidigare koden med ett gäng lysdioder på utgångarna och de visade ett korrekt bitmönster, det borde väl tyda på att ingen analog funktion är aktiv på pinnarna? Jag är ärligt talat mer van vid AVR-processorer. En bekant till mig som är van vid PIC satt till och med och debuggade med mig. Han hade varnat mig för AD-omvandlaren på PortB med sade inget om övriga kringdetaljer.

Jag kollar i databladet här, sidan 95. Står ju att de confas som analoga pinnar som standard. Dock justerar jag ju TRISA på första raden i main(), DDRA är definerat som ett alias till TRISA i headerfilen, och TRISA är satt korrekt enligt ICD2-debuggern.

Jag är som sagt ny på PIC, är det någon magisk funktion jag missat? Jag ska gå igenom standardvärdena för alla portregister i databladet...
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> DDRA är definerat som ett alias till TRISA i headerfilen,

Varför i jösse namn då ??? Det verar helkorkat. Fungerar inte TRISx ??

> Jag har satt PortB till digitalläge med konfigurationsbitarna för AD-omvandlaren.

Menar du PBADEN i CONFIG3H ?
Men du använder ju inte PORTB alls, så vad spelar det för roll ??

> Dock justerar jag ju TRISA på första raden i main()...

Det har inte ett smack med digital/analog inställningen att göra.
Du får läsa om sidan 95 ett par gånger till, speciellt kodexemplet...
xarragon
Inlägg: 88
Blev medlem: 3 maj 2006, 14:10:35
Skype: xarragon
Ort: Halmstad
Kontakt:

Inlägg av xarragon »

Tack för ditt snabba svar Sodjan. Jag har testat att ändra till TRISx istället för DDRx, och det verkar ge samma resultat, TRISx-registrena sätts till nollor oavsett vilken variant man fördrar. Dock kunde jag inte finna min påstådda #define-rad i varken länkscriptet eller headerfilen, så jag undrar var jag fick den idé ifrån?

Anledningen till att jag föredrog DDRx-namnet är helt enkelt att det är det namn som AVR-kretsarna har på motsvarande register, och dessutom tycker jag personligen att det är ett tydligare namn.
The TRISA register controls the direction of the PORTA
pins, even when they are being used as analog inputs.
Från sanningstabellen sidan 96 for RC0/RA0-pinnen:
A/D input channel 0 and Comparator C1- input. Default input
configuration on POR; does not affect digital output.
Enligt de två raderna så verkar det ju som A/D-omvandlaren sitter som ingång även på mina PortA-ingångar. Dock har de flesta kodexempel jag sett inte gjort mycket mer än ändrat TRISx-registrena när de ska blinka med LEDs, men å andra sidan så brukar ju det oftast vara mesigare PIC-kretsar som kanske inte har en A/D-omvandlare.

Jag ska testa att försöka slå om pinnen till ren digital och se om det gör någon skillnad.
xarragon
Inlägg: 88
Blev medlem: 3 maj 2006, 14:10:35
Skype: xarragon
Ort: Halmstad
Kontakt:

Inlägg av xarragon »

Jahapp, jag har nu modifierat koden så att den ser ut på följande vis:

Kod: Markera allt

void main (void)
{
	TRISA = 0x00;
	TRISC = 0x00;
	LATA = 0x00;
	LATC = 0x00;
	ADCON1 |= 0x0f;

	//init_elektronikforumet();
	init_sitronix();

	display_write_character('c');

	while (1);	
}
Enligt vad jag kan förstå så är det enbart A/D-modulen som är aktiv från POR, de andra funktionerna verkar inte vara påslagna som standard. Enligt databladet ska nu samtliga analoga ingångar på PortA[0-12] vara konfigurerade som rent digitala utgångar.

Men inte tusan behagar displayen fungera.

Några fler förslag?

Tack på förhand,
Martin Persson
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Själv nyckel är att en analog pinne alltid *läses* som "0" helt oavsett
hur TRIS är satt. Och när du gör dina kommandon som sätter/clearar
RS, E och RW så kommer de andra att nollas eftersom en bit-operation
alltid först läser hela porten (d.v.s med analoga pinnar som "0") innan
den aktuella biten ändras och skrivs tillbaka.

Så i detta fall :

DISPLAY_RS = 1;
DISPLAY_RW = 1;

så kommer först RS att bli "1", sedan på den andra raden
kommer RS = "0" och RW = "1".

Så, för digitala I/O, stäng av analoga funktioner !

Visst, om man läser i komparatorkapitlet så står det att de ska vara
"off" vid POR, men so what ? Se till att stänga av dom i alla fall. En annan
regel säger att inte lita på defaults... :-)

Enklast är att göra som i "EXAMPLE 9-1: INITIALIZING PORTA" så slipper
vi denna diskussion.

> Enligt vad jag kan förstå så är det enbart A/D-modulen som är aktiv från POR,
The other PORTA pins are multiplexed with analog
inputs, the analog VREF+ and VREF- inputs and the comparator
voltage reference output. The operation of pins
RA3:RA0 and RA5 as A/D converter inputs is selected
by clearing or setting the control bits in the ADCON1
register (A/D Control Register 1).

Pins RA0 through RA5 may also be used as comparator
inputs or outputs by setting the appropriate bits in the
CMCON register. To use RA3:RA0 as digital inputs, it is
also necessary to turn off the comparators.
Tolkningen av ovanstående är inte helt tydlig.
"Digital inputs" är lite lurigt, men notera att vid alla bit-operationer
mot pinnarna som kommer de andra 7 bitarna att *läsas* även om de
används som "digital outputs"...

Regeln är, ska man inte köra analogt, stäng av *alla* analoga funktioner.
Och gör det i koden, oavsett vad eventuella POR-defaults säger.

Jag vet inte om detta kommer att få displayen att hoppa igång, men
se det som lite allmän info kring initieringen av portar.

Har du någon bra länk till ett datablad ?

> Enligt databladet ska nu samtliga analoga ingångar på PortA[0-12]

12 ?

> Några fler förslag?

Det behövs ett tydligt datablad. Och sedan lite vanlig felsökning.
Skriv ett testprog som kör "rakt" ut till displayen från main() utan
krussiduller.
xarragon
Inlägg: 88
Blev medlem: 3 maj 2006, 14:10:35
Skype: xarragon
Ort: Halmstad
Kontakt:

Inlägg av xarragon »

Har faktiskt kopplat upp en atmega88 på ett testdäck med kablar och nästan gjort färdigt programmet för avr-libc med nu, för att kontrollera att displayen fungerar och initierar som jag tänkt mig. Har dessutom fått en extra display levererad. Det troligaste är ju att det är mina bristande PIC-kunskaper som är orsaken till det hela.

Däremot är det lite oroande att man "inte kan lita på defaults" som du uttrycker det...
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> Däremot är det lite oroande att man "inte kan lita på defaults" som du uttrycker det...

*Varför* ska man göra det ??
Sätt rellevanta register som du vill ha dom, oavsett vad som är default vid power-on.
D.v.s *rellevanta* register, de som kan ha påverkan på applikationer
om de inte är rätt satta. Alla andra register kan du låta vara som de är.
xarragon
Inlägg: 88
Blev medlem: 3 maj 2006, 14:10:35
Skype: xarragon
Ort: Halmstad
Kontakt:

Inlägg av xarragon »

Jahapp, vi har fakiskt en fungerande display nu, med en AVR-prolle istället (naturligtvis). Nu är det så att anledningen till att displayeländet fungerar ingalunda beror på varken min (in)kompetens eller på valet av processor.

Först och främst bildbevis ("Picture or it didn't happen!"):

Bild

Anledningen till att jag ens fick igång skiten berodde på att en kille i ##electronics på irc.freenode.net hade råkat hitta rät initieringssekvens av en slump. Det står alltså HELT FEL i databladet; det fungerade inte för honom heller med den sekvens som stod angivet. Eller så har både han och jag tydit databladet helt fel. Databladet är i detta fall för en Samsung KS0070U och en KS0066U, båda har samma sekvens angivet.

Jag har fortfarande problem med att den inte konsekvent startar upp i det här läget; den missar det kanske var fjärde gång. Så det är inget avslutat kapitel än. Men det här ska fanimig dokumenteras...
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Jag vet inte om du kanske har funderat på det redan,
men varför inte byta display ??
spaderkung
Inlägg: 138
Blev medlem: 12 maj 2007, 11:24:24
Ort: Sjöbo

Inlägg av spaderkung »

Har en 8x2 med KS0066U som även den har fel i databladet. Vid initiering med just 4-bit databus. Det var roligt att lösa.
xarragon
Inlägg: 88
Blev medlem: 3 maj 2006, 14:10:35
Skype: xarragon
Ort: Halmstad
Kontakt:

Inlägg av xarragon »

Här är i alla fall AVR-koden som delvis lyckas initiera displayen.

Kod: Markera allt

void init_bsdfox (void)
{
	_delay_ms(250);
	_delay_ms(250);

	send_command(0x03);

	_delay_ms(5);

	send_command(0x03);

	_delay_us(120);

	send_command(0x03);

	_delay_ms(5);

	_delay_us(50);

	send_command(0x02);
	send_command(0x02);

	_delay_us(50);

	send_command(0x00);
	send_command(0x0c);

	_delay_ms(5);

	send_command(0x01);
	send_command(0x06);

	_delay_us(50);

}
Det har nu visat sig att Samsungs datablad inte är HELT fel. Följande PIC-kod initierar displayen korrekt.

Kod: Markera allt

#define DISPLAY_D4_DDR trisa.RA0
#define DISPLAY_D5_DDR trisa.RA1
#define DISPLAY_D6_DDR trisa.RA2
#define DISPLAY_D7_DDR trisa.RA3
#define DISPLAY_RS_DDR trisa.RA5
#define DISPLAY_RW_DDR trisc.RC0
#define DISPLAY_E_DDR trisc.RC1

#define DISPLAY_D4 lata.RA0
#define DISPLAY_D5 lata.RA1
#define DISPLAY_D6 lata.RA2
#define DISPLAY_D7 lata.RA3
#define DISPLAY_RS lata.RA5
#define DISPLAY_RW latc.RC0
#define DISPLAY_E latc.RC1

#define DISPLAY_DATA lata

void main (void)
{
	// Configure I/O pins.
	DISPLAY_D4_DDR = 0;
	DISPLAY_D5_DDR = 0;
	DISPLAY_D6_DDR = 0;
	DISPLAY_D7_DDR = 0;

	DISPLAY_E_DDR = 0;
	DISPLAY_RS_DDR = 0;
	DISPLAY_RW_DDR = 0;
	
	DISPLAY_RS = 0;
	DISPLAY_RW = 0;
	DISPLAY_E = 0;

	delay_us(2);

	// Issue 'function set' in 8-bit mode, but change bit length to 4.
	display_4bit_write_nibble(0x02);
	delay_us(60); // This delay is missing in the Samsung datasheet.

	// Issue 'function set' in 4-bit mode, change display lines to 2.
	display_4bit_write_nibble(0x02);
	display_4bit_write_nibble(0x08);
	delay_us(60);

	// Since we have changed the number of lines the display must be
	// be restarted (for some reason).
	display_4bit_write_nibble(0x00);
	display_4bit_write_nibble(0x0c);
	delay_us(60);

	// Test with some text!
	for (i = 0; i < 0x80; ++i) {
		display_4bit_write_character('x');
	}

	while(1);
}
Sekvensen ovan är snarlik Samsungs initieringssekvens efter det att mjukvarureseten triggats. Men i deras datablad saknas fördröjningen efter
det första 8-bitars anropet. Det verkar också som att displayen automatiskt
slås av efter det att man ändrat antalet rader, och därför måste vi använda
kommandot 'display on' för att aktivera den.

Samsungkontrollerna verkar till skillnad från HD44780:n inte ha någon mjukvarureset som triggas av tre upprepade skrivningar av 0x03 med varierande fördröjningar. Så det är antagligen därför som min AVR-kod (som inkluderar denna) trilskas. Dock påstår Powertip på sin hemsida att man ska köra denna för att trigga initialisering.

Så hur lyder er dom? Rent SBS-fel, eller otydliga datablad? :-)
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> Rent SBS-fel, eller otydliga datablad?

Verkar i detta fall mera var det andra... :-)
xarragon
Inlägg: 88
Blev medlem: 3 maj 2006, 14:10:35
Skype: xarragon
Ort: Halmstad
Kontakt:

Inlägg av xarragon »

Upptäckte att jag faktiskt slår av displayen explicit i 'function set'-anropet. Den tredje biten styr på en HD44780-display vilken font som skall användas, men på en ST0066U så styr den istället 'display on/off'. Dock vägrar displayen fungera om man inte kör en 'display on' efter att ha ändrat antalet linjer på skärmen. Så i det fallet verkar inte biten spela någon roll.
Skriv svar