Skocz do zawartości

Pomocna odpowiedź

Cześć.

Kolejne testy mojej karty VGA współpracującej z Arduino UNO.

Test obejmuje zapis znaków do DDRAM z atrybutami kolorów oraz sterowanie adresem DDRAM.

W kodzie Arduino dodałem kilka funkcji ułatwiających obsługę karty VGA, np.: setCursorColor(255, 255, 255); setFontColor(255, 200, 0); ddramAddressSet();

Dzięki temu zarządzanie kartą VGA jest znacznie prostsze niż w assemblerze.

Poniżej pełny kod testowy oraz krótki film pokazujący działanie.

.

// Linie danych DB0..DB7
const byte DB[8] = {2, 3, 4, 5, 6, 7, 8, 9};

// Linie sterujące
const byte RS = 12;
const byte RW = 11;
const byte E  = 10;

bool endInit = 0;

//rejestry karty VGA
byte entryModeSet = 0b00000100;
byte displayCon   = 0b00001000;
byte registerSet  = 0b00100000;
byte addressSet   = 0b01000000;
byte ramWriteSet  = 0b10000000;

// rejestr adresu ddram w arduino
unsigned long ddramAddress = 0;

// przykładowy tekst
const char *txt = "          HELLO VGA    test koloru znaku i kursora    ";
const char *txt1 = "          VGA_HD44780-extendet. Test zapisu DDRAM zakonczony sukcesem    ";

//------------------------------------------------


// funkcja zapisująca 1 bajt komendy lub danych
void writeDB(byte value) {
  for (byte i = 0; i < 8; i++) {
    digitalWrite(DB[i], (value >> (7 - i)) & 1);
  }
  digitalWrite(E, HIGH);
  digitalWrite(E, LOW);
}

//------------------------------------------------

// funkcja zapisu danych
void dataWrite(byte value) {
  digitalWrite(RS, HIGH);     // RS=1 → dane
  writeDB(value);       // zapis zmian
}

// funkcja obsługi komend
void vgaControll(byte value) {
  digitalWrite(RS, LOW);     // RS=0 → komenda
  writeDB(value);       // zapis zmian
}

//------------------------------------------------

void clearScreen() {
    vgaControll(0b00000001);
}

void cursorHome() {
    vgaControll(0b00000010);
}

void displayON() {
  displayCon |= (1 << 2);
  vgaControll (displayCon);
}

void displayOFF() {
  displayCon &= ~(1 << 2);
  vgaControll (displayCon);
}

void cursorON() {
  displayCon |= (1 << 1);
  vgaControll (displayCon);
}

void cursorOFF() {
  displayCon &= ~(1 << 1);
  vgaControll (displayCon);
}

void cursorBlinkON() {
  displayCon |= (1 << 0);
  vgaControll (displayCon);
}

void cursorBlinkOFF() {
  displayCon &= ~(1 << 0);
  vgaControll (displayCon);
}

void fullBlockCursor() {
  addressSet |= (1 << 2);
  addressSet |= (1 << 1);
  vgaControll (addressSet);
}

void horizontalBarCursor() {
  addressSet |= (1 << 2);
  addressSet &= ~(1 << 1);
  vgaControll (addressSet);
}

void verticalBarCursor() {
  addressSet &= ~(1 << 2);
  addressSet |= (1 << 1);
  vgaControll (addressSet);
}

void autoIncrementON() {
  entryModeSet |= (1 << 1);
  entryModeSet |= (1 << 0);
  vgaControll (entryModeSet);
}

void autoDecrementON() {
  entryModeSet |= (1 << 1);
  entryModeSet &= ~(1 << 0);
  vgaControll (entryModeSet);
}

void autoIncrementOFF() {
  entryModeSet &= ~(1 << 1);
  vgaControll (entryModeSet);
}

void ddramWriteON() {
  ramWriteSet |= (1 << 6);
  vgaControll (ramWriteSet);
}

void ddramWriteOFF() {
  ramWriteSet &= ~(1 << 6);
  vgaControll (ramWriteSet);
}

void cgramWriteON() {
  ramWriteSet |= (1 << 5);
  vgaControll (ramWriteSet);
}

void cgramWriteOFF() {
  ramWriteSet &= ~(1 << 5);
  vgaControll (ramWriteSet);
}

void sramWriteON() {
  ramWriteSet |= (1 << 4);
  vgaControll (ramWriteSet);
}

void sramWriteOFF() {
  ramWriteSet &= ~(1 << 4);
  vgaControll (ramWriteSet);
  clearRegB();
}

//------------------------------------------------

// funkcja usuwająca zapis
void clearRegB() {
  vgaControll(0b00100000);
}

// funkcja zapis do B0
void setB0 (byte value) {
  vgaControll(0b00110000);
  dataWrite(value);
  clearRegB();
}

// funkcja zapis do B1
void setB1 (byte value) { 
  vgaControll(0b00101000);
  dataWrite(value);
  clearRegB();
}

// funkcja zapis do B2
void setB2(byte value) {
  vgaControll(0b00100100);
  dataWrite(value);
  clearRegB();
}

//------------------------------------------------

// funkcja zapisu danych o kolorze
void setColor(byte red, byte green, byte blue) {
  setB0(red);
  setB1(green);
  setB2(blue);
}

// funkcja zapisująca kolor kursora
void setCursorColor(byte red, byte green, byte blue) {
  setColor(red, green, blue);
  vgaControll(0b00100001);
}

// funkcja zapisująca kolor czcionki
void setFontColor(byte red, byte green, byte blue) {
  setColor(red, green, blue);
  vgaControll(0b00100010);
}

//------------------------------------------------
// funkcja inicjująca adres ddram w karcie VGA
void ddramAddressSet() {
  setB0((ddramAddress >> 0) & 0xFF);
  setB1((ddramAddress >> 8) & 0xFF);
  setB2((ddramAddress >> 16) & 0xFF);
  addressSet |= (1 << 5);
  vgaControll (addressSet);
  addressSet &= ~(1 << 5);
}

//------------------------------------------------

// inicjacja linii sterujących
void setup() {
  for (byte i = 0; i < 8; i++) {
    pinMode(DB[i], OUTPUT);
  }

  pinMode(RS, OUTPUT); // bit wyboru między komendą i danymi wysyłanymi do karty VGA
  pinMode(RW, OUTPUT); // w naszym kodzie nie używamy (służy do odczytu bitu zajętości karty VGA)
  pinMode(E, OUTPUT);  // sygnał zapisu dla karty VGA (zapis wyzwalamy dodatnim zboczem)
  pinMode (LED_BUILTIN, OUTPUT); // kontrolka LED sygnalizująca zakończoną inicjacjię karty VGA

  digitalWrite(RS, LOW);
  digitalWrite(RW, LOW);
  digitalWrite(E, LOW);
  digitalWrite(LED_BUILTIN, LOW);

  writeDB(0x00);
}

// program główny
void loop() {

  if (endInit == 0) {
    // Inicjacja układu FPGA (oczekiwanie ok 0.5 sek.)
    delay(500);
    clearScreen();
    delay(500);
    setCursorColor(255, 255, 255); // R, G, B
    cursorON();
    cursorBlinkON();
    fullBlockCursor();
    autoIncrementON();
    displayON();
    
    setFontColor(255, 200, 0);
    ddramAddress = 0;
    ddramAddressSet();
    ddramWriteON();
    // DATA_RAM_WRITE_SET zapis do ddram ciągu znaków zdefiniowanych w tabeli (const char *txt)
    for (byte i = 0; txt[i] != 0; i++) {
      dataWrite(txt[i]);       // ASCII znak
    }
    ddramWriteOFF();
    
    setFontColor(0, 200, 255);
    ddramAddress += 80; // przesuń kursor do następnego wiersza na pierwszą kolumnę
    ddramAddressSet();
    ddramWriteON();
    for (byte i = 0; txt[i] != 0; i++) {
      dataWrite(txt[i]);       // ASCII znak
    }
    ddramWriteOFF();
    
    setFontColor(255, 0, 0);
    ddramAddress += 80;
    ddramAddressSet();
    ddramWriteON();
    for (byte i = 0; txt[i] != 0; i++) {
      dataWrite(txt[i]);
    }
    ddramWriteOFF();
    
    setFontColor(255, 100, 0);
    ddramAddress += 80;
    ddramAddressSet();
    ddramWriteON();
    for (byte i = 0; txt[i] != 0; i++) {
      dataWrite(txt[i]);
    }
    ddramWriteOFF();
    
    setFontColor(60, 255, 0);
    ddramAddress += 80;
    ddramAddressSet();
    ddramWriteON();
    for (byte i = 0; txt[i] != 0; i++) {
      dataWrite(txt[i]);
    }
    ddramWriteOFF();
    
    setFontColor(255, 0, 255);
    ddramAddress += 80;
    ddramAddressSet();
    ddramWriteON();
    for (byte i = 0; txt[i] != 0; i++) {
      dataWrite(txt[i]);
    }
    ddramWriteOFF();
    
    setFontColor(255, 255, 255);
    ddramAddress += 80;
    ddramAddressSet();
    ddramWriteON();
    for (byte i = 0; txt[i] != 0; i++) {
      dataWrite(txt[i]);
    }
    ddramWriteOFF();
    
    setFontColor(200, 200, 200);
    ddramAddress += 80;
    ddramAddressSet();
    ddramWriteON();
    for (byte i = 0; txt[i] != 0; i++) {
      dataWrite(txt[i]);       // ASCII znak
    }
    ddramWriteOFF();
    
    setFontColor(100, 100, 100);
    ddramAddress += 80;
    ddramAddressSet();
    ddramWriteON();
    for (byte i = 0; txt[i] != 0; i++) {
      dataWrite(txt[i]);
    }
    ddramWriteOFF();
    
    setFontColor(32, 32, 32);
    ddramAddress += 80;
    ddramAddressSet();
    ddramWriteON();
    for (byte i = 0; txt[i] != 0; i++) {
      dataWrite(txt[i]);
    }
    ddramWriteOFF();

    delay(3000);
    cursorOFF();

    for (byte i = 0; i < 2; i++) {
      delay(500);
      displayOFF();
      delay(500);
      displayON();
    }
    delay(1000);
    
    setFontColor(200, 64, 100);
    ddramAddress += 240;
    ddramAddressSet();
    ddramWriteON();
    for (byte i = 0; txt1[i] != 0; i++) {
      dataWrite(txt1[i]);
    }
    ddramWriteOFF();
    
    endInit = 1; // koniec inicjacji
    digitalWrite(LED_BUILTIN, HIGH);
  }
}

 

 

 

  • Lubię! 1
12 minut temu, kroszkanorber napisał:

W kodzie Arduino dodałem kilka funkcji ułatwiających obsługę karty VGA, np.: setCursorColor(255, 255, 255); setFontColor(255, 200, 0); ddramAddressSet();

Do tego bym jeszcze dodał setCursorColor(uint32_t hexColor), setFontColor(uint32_t hexColor) wraz z zabezpieczaniem wartości (0x00FFFFFF). Bo jednak dużo częściej dla kolorów stosuje się kody hex niż rozdzielone wartości numeryczne.

  • Lubię! 1

@H1M4W4R1  ten kod jest tylko do testów. Z ciekawości chciałem sprawdzić czy Arduino będzie współpracować z fpga. Takie połączenie jest dla mnie nowością. Zapis o którym piszesz nie jest dla mnie taki oczywisty ponieważ mało programuje w języku c. Dziękuję za podpowiedzi 

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...