ST7920 display grafikläge, hur??

Lysdioder, Optiska sensorer, Fiberoptik, Displayer, Lasrar, Optiska kopplare
Speedsoda
Inlägg: 20
Blev medlem: 24 maj 2011, 19:35:26

ST7920 display grafikläge, hur??

Inlägg av Speedsoda »

Har köpt en display(128x64 pixlar, med ST7920 som driver den) på ebay(ebay.com/12864-128x64-Graphic-LCD-Display-module-Free-pin-header som jag tänkte bygga hastighetsmätare av, och jag har lyckats skriva tecken i den med en pic och fått den att fungera, men nu vill jag ge mig på grafikläget som jag hoppas ska ge mig lite mer kontroll över designen av bilden. Jag tror att jag har lyckats aktivera grafikläget, men jag förstår inte alls hur jag ska kunna rita någonting på den. Det jag har försökt är att skriva till GDRAM, som jag har uppfattat det som att det motsvarar pixlarna på displayen typ, men det blir mest random pixlar och två feta vertikala ränder. Det blir samma bild oavsett vad jag försöker skriva till GDRAM. Databladet hjälper inte riktigt, för jag fattar inte alls hur det är meningen att man ska göra.http://www.newhavendisplay.com/app_notes/ST7920.pdf Där är databladet.


Koden:

Kod: Markera allt

 
 #include <htc.h>

#define EN PORTB,RB5 //ENABLE TRIGGER
#define RS PORTB,RB7 //REGISTER SELECT
#define RW PORTA,RA5 //READ/WRITE 1/0
#define RST PORTB,RB6 //RESET CHIP

void delayms(unsigned int); //Inte mer än 1000 ms.
void LCD_write(int, unsigned char);

unsigned int PORTAVAR;
void main (void){
	unsigned int poopoo = 0xA0;
	unsigned int poo1   = 0xA1;
	SSPCON = 0; //Stäng av seriell komm och frigör portar
	ADCON1 = 0;
	ANSEL = 0;
	ANSELH = 0;
	PORTA = 0;
	PORTAVAR = 0;
	PORTC = 0;
	TRISC = 0;
	TRISA = 0;
	TRISB = 0;
	
	delayms(500);
		

	RST = 1;
	
   
   LCD_write(0, 0x30); 

   // once more (I don't understand why, but every example uses this line twice) 
  LCD_write(0, 0x30); 

   // turn LCD ON, cursor ON & character blink ON 
  LCD_write(0, 0b00001111); 
      
   // clear display 
  LCD_write(0, 0x01); 
  
   // cursor moves to the right, insert OFF 
  LCD_write(0, 0x06); 
  
  //Set extended instruction set
  LCD_write(0, 0b00110110);
  LCD_write(0, 0b00110110);
  
  //CLEAR DISPLAY
  LCD_write(0, 0x01);
  delayms(300);
  
  //SET GRAPHIC RAM ADDRESS
  	LCD_write(0, 0b10000001);
  	LCD_write(0, 0b10001011);
  
	while(1);
}

void delayms(unsigned int x){
	//64000 = 1s;
	x = x * 64;
	for (int i = 0; i<x; i++){
	}
}

void LCD_write(int rs, unsigned char d){
	RS = rs; 
  //	delayms(1); 
  	RW = 0; 
  //	delayms(1); 
	EN = 0;
   	PORTC = d; 
  //	delayms(1); 
  	EN = 1; // tells the LCD that the uC wants to say something 
  	delayms(1); 
   	EN = 0;
   //	delayms(1); 
}	
Hoppas att någon vill ta sig tid att hjälpa till. Tack!
Senast redigerad av blueint 26 maj 2011, 23:16:05, redigerad totalt 1 gång.
Anledning: För lång URL!
labmaster
Inlägg: 2919
Blev medlem: 5 april 2011, 01:10:25

Re: ST7920 display grafikläge, hur??

Inlägg av labmaster »

De där rackarns grafiska displayerna kan vara lite knepiga att traktera. Man får som regel gräva djupt i databladet innan man kommer på hur man skall kommunicera med displayen. Om du inte har läst databladet ett par timmar redan nu så har du för dåligt tålamod :-).

Det bästa brukar vara att söka efter en kodsnutt på nätet som man kan försöka sig på att tolka. Har du tur så har någon redan uppfunnit hjulet.

Hur som helst databladet stipulerar nedanstående process:

Graphic Display RAM has 64x256 bits bit-mapped memory space. GDRAM address is set by writing 2 consecutive bytes of vertical address and horizontal address. Two-byte data (16 bits) configures one GDRAM horizontal address.

The Address Counter (AC) will be increased by one automatically after receiving the 16-bit data for the next operation.

After the horizontal address reaching 0FH, the horizontal address will be set to 00H and the vertical address will not change. The procedure is summarized below:

1. Set vertical address (Y) for GDRAM
2. Set horizontal address (X) for GDRAM
3. Write D15~D8 to GDRAM (first byte)
4. Write D7~D0 to GDRAM (second byte)
Speedsoda
Inlägg: 20
Blev medlem: 24 maj 2011, 19:35:26

Re: ST7920 display grafikläge, hur??

Inlägg av Speedsoda »

Eh ja, och det är sällan någon tänker på att utforma databladet speciellt pedagogiskt... Förstår inte varför det ska vara så krångligt.

Ja, jag har försökt hitta lämpliga kodsnuttar och stirrat mig tokig på databladet, men inget har lett någonstans tyvärr.


Det verkar som om jag lyckas ställa in X. Kanske. Y verkar inte funka. Kanske, jag vet inte. D0-D15 fattar jag inte ens vad det ska vara? Dessutom är som sagt displayen täckt med random pixlar. Det här blajet dyker upp så fort jag försöker skriva första instruktionen till grafiken, dvs set vertical address. Varför?

Vad betyder det här: Set GDRAM address to address counter (AC)?
Det är den instruktionen jag försöker använda. (sida 17 i databladet). Jag ska "set"a GDRAM address, men vad är address counter och varför nämns den?
Speedsoda
Inlägg: 20
Blev medlem: 24 maj 2011, 19:35:26

Re: ST7920 display grafikläge, hur??

Inlägg av Speedsoda »

Om någon fattar hur man ska ställa in "cursor"-position (för textläget) uppskattas det också...
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: ST7920 display grafikläge, hur??

Inlägg av sodjan »

Processor ??? Osc frekvens ?
Fungerar det *med* de bortkommenterade delayms() anropen ?

Har du följt initierings exemplen i databladet ? Jag får inte ihop
din kod med vad databladet säger, så det är svårt att veta om
du ens har kollat. Var får du "// once more..." från ?

> D0-D15 fattar jag inte ens vad det ska vara?

Vad menar du med "ska vara" ? Det beror ju på vad du ska visa på skärmen !?
Se "Table 7".

> Jag ska "set"a GDRAM address, men vad är address counter och varför nämns den?

Det finns två "address counters", en för X och en för Y, se "Table 7".
Du sätter dom till var/där du ska skriva med just den instruktionen.

> //CLEAR DISPLAY
> LCD_write(0, 0x01);

Verkar vara "Standby". Är det det du vill ha ?

EDIT:
Verkar lite snabbt vara en trevlig display med både HD44780 och ett
full-grafiskt läge i samma enhet ! Jag har inte kollat om det går att
köra både samtidigt, d.v.s visa viss text med HD44780 kommandon
och samtidigt använda bitmap grafik till andra delar av samma display.
Men trevligt *om* det går... :-)
labmaster
Inlägg: 2919
Blev medlem: 5 april 2011, 01:10:25

Re: ST7920 display grafikläge, hur??

Inlägg av labmaster »

Jag hakar på Sodjans inlägg.

När du satt adressen i AC där du vill skriva behöver du inte sätta ett nytt värde då du skall skriva nästa pixel omedelbart efter den du nyss har skrivit. Den flyttar automatiskt AC till nästa pixel då du skriver till dispayen.

Hårt arbete är det som gäller när man skall använde en ny display man aldrig varit på tidigare. Det betyder att man läser och försöker tolka databladet. Därefter testar man om det blev som man tolkat genom att skriva till displayen. Funkar det inte får man läsa igen och se om man kan hitta en ny infallsvinkel. Så får man hålla på tills poletten trillar ned.
Speedsoda
Inlägg: 20
Blev medlem: 24 maj 2011, 19:35:26

Re: ST7920 display grafikläge, hur??

Inlägg av Speedsoda »

Processor är PIC16F690. Osc. frekvens är jag inte hundra på, kör interna oscillatorn som jag tror defaultar på 4MHz.

Ja, det har jag gjort. Har lyckats initiera displayen, det funkar prima att skriva ut både 16x8 tecken och 16x16 tecken.
init.gif
Det är den jag har följt för initiering av displayen, och det väl exakt så jag har gjort?

Kod: Markera allt

//POWER ON här då.
 delayms(500);      

   RST = 1;   //Reset går hög.
   
   LCD_write(0, 0x30);  //Function set.

   // En gång till. Det var två bitar där som inte kan ställas samtidigt, så man får göra det i två svep.
   // Engelskakommentarerna var inte mina, utan hamnade där när jag trodde jag hade initierat fel och copypastade lite, sen
   // fick dom va kvar.
  LCD_write(0, 0x30); 

   // DISPLAY On/Off control
  LCD_write(0, 0b00001111); 
      
   // Display Clear
  LCD_write(0, 0x01); 
  
   // Entry Mode set
  LCD_write(0, 0x06);
Jag ser inga skillnader i alla fall. Det är alltså 8-bitars parallell överföring jag kör med. Någon initiering för grafiken hittar jag inte, så jag gjorde mitt bästa utifrån vad jag förstod, och det verkar som sagt inte funka.

"Vad menar du med "ska vara" ? Det beror ju på vad du ska visa på skärmen !?
Se "Table 7"."

Men jag är inte säker på att jag fattar. Skriver man till en horisontell rad på 1x16 pixlar i taget, där man bestämmer vilka pixlar som ska sättas med d0-d15, eller? Det funkar i alla fall inte. Såg nu att jag hade råkat sätta i fel ordning, dvs horizontal innan vertical, men jag ändrade det och det blev ingen skillnad.


>Det finns två "address counters", en för X och en för Y, se "Table 7".
>Du sätter dom till var/där du ska skriva med just den instruktionen.

Så att sätta address counter är samma sak som att sätta GDRAM address, eller?

>Verkar vara "Standby". Är det det du vill ha ?

Nej, det ville jag inte. Missade att instruktionen inte betyder samma sak i extended set.


Så jag har verkligen försökt nu, fixat några grejer som var fel, men jag får ingen skillnad i resultat.
Såhär blir displayen:
display.jpg
Fast det lyckades jag fixa nu.
Felet låg i Function Set-instruktionen LCD_write(0, 0b00110110);, där jag byter till extended instruction set. Har jag förstått fel om jag har tolkat det som att "X" i beskrivningen av instruktionen betyder att det inte spelar någon roll vad den biten är? För när jag skrev LCD_write(0, 0b00110110); så fick jag det där tramset på skärmen. Bytte ut bit1 mot en nolla så var det borta.
Edit: Jaha. Den biten bestämmer om grafiken är av eller på. Kollade fel tydligen. Grafik av, displayen ser normal ut. Grafik på = ful grafik som jag inte kan påverka.

Dock så ritar den inte ut något alls med koden:

Kod: Markera allt

 
//Set extended instruction set
  LCD_write(0, 0b00110100);
  LCD_write(0, 0b00110100);

  //SET GRAPHIC RAM ADDRESS
  LCD_write(0, 0b10101001); //Set vertical address
  LCD_write(0, 0b10000101); //Set horizontal address
  LCD_write(0, 0b11111111); //d15-d8
  LCD_write(0, 0b11111111); //d7-d0
Om jag fattat rätt borde det där bli en horisontell linje vid 41 pixlar vertikalt, och 5:e pixelgruppen från vänster? Blir inget hur jag än testar i alla fall.

Labmaster: Nästa pixel? Skriver man inte 16 pixlar med d15-d0? Jag fattar inte riktigt.
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Speedsoda
Inlägg: 20
Blev medlem: 24 maj 2011, 19:35:26

Re: ST7920 display grafikläge, hur??

Inlägg av Speedsoda »

JAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA!! :idea:

FÖRST ställer jag in GDRAM adressen, SEN skriver jag till ramminnet med en helt annan instruktion! Det var det som var fel. "Skräpet" var väl bara det som råkade ligga i minnet. Fantistiskt. Kan rita ränder och allt möjligt.

Tack för all hjälp! Utan er hade det tagit mycket längre tid att hitta alla småmissar. :)
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: ST7920 display grafikläge, hur??

Inlägg av sodjan »

> FÖRST ställer jag in GDRAM adressen, SEN skriver jag till ramminnet

Ja, det var ju inte så lätt att förstå att det var just *det* som du inte fattade... :-)

Nedanstående från databladet sidan 12 är ju ändå rellativt tydligt.
Hade du inte läst det alls ? Eller hade du läst det men inte förstått ?

The procedure is summarized below:
1. Set vertical address (Y) for GDRAM
2. Set horizontal address (X) for GDRAM
3. Write D15~D8 to GDRAM (first byte)
4. Write D7~D0 to GDRAM (second byte)
Speedsoda
Inlägg: 20
Blev medlem: 24 maj 2011, 19:35:26

Re: ST7920 display grafikläge, hur??

Inlägg av Speedsoda »

Nä, det är klart, jag visste inte heller att det var det jag inte fattade. :wink:

Jo, jag läste det, men jag satt ju och stirrade på "Set graphics RAM address" och tänkte att det är den man skriver till GDRAM med, inte att "skrivtillram"-instruktionen gällde alla ramminnen. Nu känns det ju helt självklart logiskt, men när man sitter där i förvirringen och frustrationen är det inte lätt att veta vad som är in eller ut.

Nu kommer nästa problem... Läsa från GDRAM. Det känns också knepigt. Får se hur det går. :tumupp:
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: ST7920 display grafikläge, hur??

Inlägg av sodjan »

OK. :-)

> Läsa från GDRAM.

Kanske inte är något annat än att ändra R/W pinnen.
D.v.s byta mellan "write RAM" och "read RAM" i tabellen
på sidan 16.
Speedsoda
Inlägg: 20
Blev medlem: 24 maj 2011, 19:35:26

Re: ST7920 display grafikläge, hur??

Inlägg av Speedsoda »

Det verkar ju så enkelt, får se imorgon. Jag har inga höga förhoppningar. :roll: Försöker koncentrera mig på att skriva bra utritningsfunktioner nu. Tydligen så är min display 256x32 pixlar, eller så blir den i alla fall behandlad av ST7920:n. Den nedre halvan av skärmen beter sig exakt som om den vore en förlängning åt höger av den övre. Försöker jag gå till en vertikal nivå > 31 börjar den om från toppen igen. Lite konstigt, men så kan det väl vara ibland med elektronik...
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: ST7920 display grafikläge, hur??

Inlägg av sodjan »

Märkligt. Det är inget i databladet som direkt förklarar det.
Däremot har det enkla bladet för modulen displayen uppdelad
i två 32 bitarns områden.
http://www.satistronics.com/myfiles/fil ... 2864ZB.pdf.
Ser "misstänkt" ut. Vänta lite, displayen är ju 128x64. men databladet för
kontrollern talar om 256x64. De kan ha mappat den högra delen av
displayen som rad 32-63. Kan du skriva på den högra delen av displayen ?
Du får helt enkelt göra ett testprogram som loopar igenom hela adressarean
X:0-15 och Y:0-63 och se var det hamnar.
Speedsoda
Inlägg: 20
Blev medlem: 24 maj 2011, 19:35:26

Re: ST7920 display grafikläge, hur??

Inlägg av Speedsoda »

Ja, skriver man bara på börjar den högst upp till vänster i displayen, när utrymmet tar slut fortsätter den på övre halvan av nedre halvan(tredje raden så att säga). När det utrymmet tar slut fortsätter den skriva på rad två, och hamnar till slut på rad 4. Ser skitdumt ut.
Det är precis vad jag har gjort, har testat att fylla displayen med pixlar och den beter sig precis som om displayen var en avklippt 256x32-bitars display. Y-värden mellan 32-63 är helt värdelösa, då börjar den bara om.
Speedsoda
Inlägg: 20
Blev medlem: 24 maj 2011, 19:35:26

Re: ST7920 display grafikläge, hur??

Inlägg av Speedsoda »

Fan vad svårt allt är. Försöker ju läsa från GDRam nu, så att jag kan peta ut pixlar samtidigt som jag har kvar den nuvarande bilden, dvs bitwise-or:a in pixlar. Då krävs ju en avläsning av GDRam, och sen kör jag bitwise OR med pixlar jag vill sätta in, och så skickar jag tillbaks det till GDRam. Det är väl rätt tänkt?

Jag försöker hålla mig till enkla saker för att minimera felkällorna, det är därför jag gjort koden som jag gjort, det kan tyckas lite ineffektivt men jag tänker så här: Jag förbereder GDRam för avläsning genom att ställa in adressen samt ställa SR och RW hög, och ställa mina buss till ingångar, den här funktionen kör även en "dummy-read" som om jag tolkat rätt databladet säger att man ska göra. Sedan kör jag en funktion som hämtar nästa värde från ramminnet och returnerar som en char(byte). Jag kör sedan den igen för att få nästa byte(Är detta rätt tänkt? Måste ju ha 16 bitar för en "rad" i GDRam), och passar då på att avsluta "läsningssessionen" genom att skicka med en etta till denna funktion som betyder "nu är jag klar med läsningen, ställ tillbaks TRISC, SR och RW till normalt läge."

För det första verkar inte avläsningen funka så bra. När jag lägger in avläsningen i min paintPixel-funktion ritar den ut en streckkodsliknande bild. Om jag tänker rätt borde bilden bli helt fylld av pixlar, utan luckor, eftersom jag hela tiden OR:ar in nya pixlar. Detta är problem nr 1.
Problem nr2 är att displayen ballar ur fullständigt efter ett tag. Jag har testat att kommentera bort kod och se vad som orsakar det här, och det verkar som att det är instruktionen "orgdatah = readNextGDRam(1)" som orsakar skiten, dvs avläsningen från ramminnet där jag säger att jag är klar och den ställer ner TRISC, RW och RS. Raden innan kör jag orgdatav = readNextGDRam(0);, dvs en vanlig avläsning. Den orsakar inga problem, kan köra readNextGDRam(0) flera gånger utan att några problem uppstår, men så fort jag kör den med en etta (done) så går det åt pipan, fast inte från början. Den kör hela första halvan av displayen utan problem, dvs y=0-31 och x=0-127, men när den kommer till den nedra halvan(den som behandlas som om den vore högra halvan av displayen, så att säga) blir den helt bananas. Det börjar med att det flimrar till, sen ritar den ut ett kinesiskt tecken(lite skräckfilm över det här :roll: ), sen börjar den rulla hela bilden uppåt, och det slutar med en rätt stökig bild.

Alltså: 1. Det verkar inte som att jag lyckas läsa av GDRam korrekt.
2. readNextGDRam(1)(men inte readNextGDRam(0)) orsakar kaos i displayen när x > 127.

Hjälp? Själva paintPixel() funkar som förväntat, om jag inte blandar in avläsningen av GDRam.

Kod: Markera allt

#include <htc.h>

#define EN PORTB,RB5//RA4//PORTAbits.RA4 //ENABLE TRIGGER
#define RS PORTB,RB7//RA0//RTAbits.RA0 //REGISTER SELECT
#define RW PORTA,RA5//RA1//PORTAbits.RA1 //READ/WRITE 1/0
#define RST PORTB,RB6//RA2//PORTAbits.RA2 //RESET CHIP

void delayms(unsigned int); //Inte mer än 1000 ms.
void delay64ms(unsigned int x); //64dels ms. Väldigt ungefärligt.
void LCD_write(int, unsigned char); //Skicka värden till LCDn.
void writeSpeed(unsigned char);
void paintPixel(unsigned char, unsigned char); //rita pixel 0-127, 0-63(egentligen 0-255, 0-31.)
void clearGraphics();						//Rita tomt.
void setReadGDRam(unsigned char, unsigned char);	//Förbered för GDRam avläsning
void commandLCD();							//Skicka en EN-puls, som berättar displayen att vi vill kommunicera
unsigned char readNextGDRam(unsigned char done); //Läs nästa byte från GDRam. om done = 1 återställs TRISC och R/W inställningar.

unsigned int PORTAVAR;
void main (void){
	unsigned int poopoo = 0xA0;
	unsigned int poo1   = 0xA1;
	SSPCON = 0; //Stäng av seriell komm och frigör portar
	ADCON1 = 0;
	ANSEL = 0;
	ANSELH = 0;
	PORTA = 0;
	PORTAVAR = 0;
	PORTC = 0;
	TRISC = 0;
	TRISA = 0;
	TRISB = 0;
	
	delayms(500);
		

	RST = 1;
	
   
   LCD_write(0, 0x30); 

   // once more (I don't understand why, but every example uses this line twice) 
  LCD_write(0, 0x30); 

   // turn LCD ON, cursor ON & character blink ON 
  LCD_write(0, 0b00001100); 
      
   // clear display 
  LCD_write(0, 0x01); 
  
   // cursor moves to the right, insert OFF 
  LCD_write(0, 0b00000110); 
  
  /*for (int i = 0; i<100; i++){
	  LCD_write(0, 0x01);
	  writeSpeed(i);
	  delayms(60);
	} 
   for (int i = 100; i>0; i--){
	  LCD_write(0, 0x01);
	  writeSpeed(i);
	  delayms(60);
   } */
   
  //CLEAR DISPLAY
  LCD_write(0, 0x01);
  delayms(300);
  
   //Set extended instruction set, Graphics on
  LCD_write(0, 0b00110110);
  
  //clearGraphics();
  
  for (unsigned char x = 0; x < 255; x++){ //Rita pixlar överallt!
	  for (unsigned char y = 0; y < 31; y++){
		  paintPixel(x, y);
      }
  }  
	while(1);
}

void delayms(unsigned int x){
	//64000 = 1s;
	x = x * 64;
	for (int i = 0; i<x; i++){
	}
}

void delay64ms(unsigned int x){
	//64000 = 1s;
	for (int i = 0; i<x; i++){
	}
}

void clearGraphics(){	
	
	for (int i = 0b10000000; i <= 0b10011111; i++){
	  for (int x = 0b10000000; x <= 0b10001011; x++){
		  LCD_write(0, 0b00110110);//Extended Instruction, Grapihcs on
		  LCD_write(0,i);	//sätt adress till gdram
		  LCD_write(0,x);	//sätt adress till gdram
		  
		  LCD_write(0, 0b00110010); //basic instructions, graphics on
		  LCD_write(1, 0b00000000);	//skriv blankt till gdram
		  LCD_write(1, 0b00000000); //skriv blankt till gdram
		  
		 } 
	  
	 }
}	

void paintPixel(unsigned char x,unsigned char y){
	unsigned char ver = 0b10000000 + y;			//Instruktionen för vertikal adress + verikal position
	unsigned char hor = 0b10000000 + (x / 16);  //Samma fast för x, som är uppdelad i 16-bitars sektioner
	unsigned char xpos = x % 16;				//Var i 16-bitars-sektionen ska pixeln ligga?
	unsigned char datav, datah;					//Detta är värdena vi skriver till GDRam sen. De vänstra 8 bitarna och de högra
	unsigned char orgdatav, orgdatah;			//Gamla GDRam-värdena läses in hit
	
	setReadGDRam(x, y);			//Förbered för GDRam-avläsning
	
	orgdatav = readNextGDRam(0);//Läs en byte från GDRam, 0 betyder att vi kommer läsa mer
	orgdatah = readNextGDRam(1);//Läs nästa byte från GDRam, 1 = vi är klara med det nu.
	
	//Set extended instruction set, Graphics on.
	LCD_write(0, 0b00110110);
	LCD_write(0, 0b00110110);
	
	if (xpos > 7){			//Om xpos är större än sju ska pixeln vara i högra delen
		datav = 0;			//Här ska pixeln inte vara, så = 0.
		datah = 0b10000000;	//Stoppa in en bit
		datah = datah >> (xpos - 8); //Skifta den till rätt plats.
	}
	else{
		datah = 0;
		datav = 0b10000000;		//Stoppa in en bit
		datav = datav >> xpos;	//Skifta den till rätt plats.
	}
	datah = datah | orgdatah; //Blanda nya värden med värdena från GDRam
	datav = datav | orgdatav; //Blanda nya värden med värdena från GDRam
	

	  
	LCD_write(0, ver);	//SET GRAPHIC RAM ADDRESS Y
	LCD_write(0, hor);	//SET GRAPHIC RAM ADDRESS X
	  
	LCD_write(0, 0b00110010);	//change to basic instruction set
	
	LCD_write(1, datav);	//write to ram.
	LCD_write(1, datah);	//write to ram.
}

void commandLCD(){
	EN = 1;
	delay64ms(1);
	EN = 0;
}	
void setReadGDRam(unsigned char x,unsigned char y){ //ANROPAS MED X-SEGMENT
	unsigned char ver = 0b10000000 + y;
	unsigned char hor = 0b10000000 + x;
	unsigned int read = 0;
	LCD_write(0, 0b00110110); //Set extended instruction set, Graphics on
	
	LCD_write(0, ver);	//Set GDRam address vertical
	LCD_write(0, hor);	//Set GDRam addres horizontal
	
	LCD_write(0, 0b00110010);	//Change to basic instruction set, Graphics ON
	
	TRISC = 0b11111111;			//Buss ingångar
	RS = 1;		
	RW = 1;		//READ-läge
	
	commandLCD(); //dummyread
	/*commandLCD(); //Read 1.
	read = read + PORTC; //Läs in värdet
	read = read << 8;	 //Skifta det åtta bitar åt vänster
	commandLCD(); //Read 2.
	read = read + PORTC; //Läs in värdet2
	RW = 0;
	RS = 0;
	TRISC = 0;	//Buss utgångar igen.*/
}

unsigned char readNextGDRam(unsigned char done){
	unsigned char read;
	commandLCD();
	read = PORTC;
	if (done == 1){
		TRISC = 0;
		RW = 0;
		RS = 0;
	}	
	return read;	
}			

void writeSpeed(unsigned char speed){
	unsigned char out2 = 0xB0 + (speed%10);
	unsigned char out1;
	out1 = speed;
	out1 = speed - (speed%10);
	out1 = speed / 10;
	out1 = out1 + 0xB0;
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0x20);// write ' '
	LCD_write(1, 0xA3);
	LCD_write(1, out1);
	LCD_write(1, 0xA3);
	LCD_write(1, out2);
}	

void LCD_write(int rs, unsigned char d){
	EN = 0;
	RS = rs; 
  	RW = 0; 
   	PORTC = d; 
 
  	commandLCD();
}	
Skriv svar