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

), 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();
}