Danke euch dreien für die Ausführungen.

Zitat Zitat von radbruch Beitrag anzeigen
... Das habe ich hier auch schon mal beschrieben ...
Ja, das hatte ich (leider nur) überflogen, bevor mich die Schnapsidee überkam das selbst zu machen. Und so läuft das ja auch bei mir. Die LED-Ansteuerung hatte ich mir zu Beginn meiner Überlegungen am Oskar angesehen (2-Kanal analog) und daraus Timing und Schaltweise entnommen. Die Funktion LED=an wenn A high und K low ist war dann Ausgangspunkt für die Steuerung.

Realisiert ist die Ansteuerung der LEDs in einer ISR die alle 250 µs aufgerufen wird. Darin wird die vorhergehende Zeile ausgeschaltet, das Schieberegister mit dem aktuellen Bitmuster versorgt, aktiv geschaltet und danach die neue Zeile eingeschaltet. Frisst rund 50% CPU-Zeit und ergibt eine augenfreundliche Frequenz von 400 Hz. Meine Annahme war dabei, dass die 2000 Maschinenzyklen zwischen zwei Interrupts genug wären um IRS und Hauptprogramm abzuarbeiten. Und das funktionierte schon prächtig : die beiden Rackets laufen mit Potisteuerung brav in ihren Grenzen auf und ab.
Code:
// ===============================================================================
//      Interruptroutinen
// ===============================================================================
// ===============================================================================
// ===  Initialisierung der Ports auf ATMEGA8 AU auf Vektor 10 (1-19) TIMER0 OVF
//                      Timer/Counter0 Overflow mit ###>>> 250 µs bei 8 MHz
//TCCR0 |= (1<<CS01);           // 1/8  Prescaler, 250 µs bei 8 MHz
                                // entsprechend 250*8 = 2000 Maschinenzyklen
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 ISR (TIMER0_OVF_vect)          // ISR schaltet LED der Reihe nach
 {                              //
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  SetBit (PORTD, 3);            // Zeitnahmeblink ein
  Izeit_1  ++;                  // Boardzeit hochtickern
  if (Izeit_1 == 4001) Izeit_1 = 1;   // ... und eingrenzen
  TC  ++;                       // ISR-Timercount incrementieren
  if (TC == 11) TC  = 1;        // ... und eingrenzen
                                //
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//      Es beginnt die Schalterei der LEDs, Zeile für Zeile,
//      Zuerst "alte Zeile" ausschalten (case), danach Zeilenmuster einlesen
// - - - - - - - - - - - - - - -
  switch (TC) {                 //
  case 1:                       //
    ClrBit (PORTB, 1);          // Zeile 0 aus - letzte Zeile
    break;                      // switch verlassen
  case 2:                       //
    ClrBit (PORTC, 0);          // Zeile 1 aus-
    break;                      // switch verlassen
  case 3:                       //
    ClrBit (PORTC, 1);          // Zeile 2 aus-
    break;                      // switch verlassen
  case 4:                       //
    ClrBit (PORTC, 2);          // Zeile 3 aus-
    break;                      // switch verlassen
// - - - - - - - - - - - - - - -
  case 5:                       //
    ClrBit (PORTC, 3);          // Zeile 4 aus-
    break;                      // switch verlassen
  case 6:                       //
    ClrBit (PORTD, 4);          // Zeile 5 aus-
    break;                      // switch verlassen
  case 7:                       //
    ClrBit (PORTD, 5);          // Zeile 6 aus-
    break;                      // switch verlassen
  case 8:
    ClrBit (PORTD, 6);          // Zeile 7 aus-
    break;                      // switch verlassen
  case 9:
    ClrBit (PORTD, 7);          // Zeile 8 aus-
    break;                      // switch verlassen
  case 10:
    ClrBit (PORTB, 0);          // Zeile 9 aus-
    break;                      // switch verlassen
  default:
    break;
  }                             // Ende switch (TC), Zeile TC ausschalten
// - - - - - - - - - - - - - - -
//      "Alte Zeile" wurde ausgeschaltet, jetzt aktuelles Zeilenmuster einlesen
//      Aktuell ist die Zeile TC
                                        //
  for (LPp = 4; LPp < 16; LPp++)
  {                                     //
    if (IsBitSet (L[TC], LPp))          // 
    { ClrBit (PORTB, dta); }            // Data low  <=> LED on
    else { SetBit (PORTB, dta); }       // Data high <=> LED off
    ClrBit (PORTB, clk);                // Clock low
    SetBit (PORTB, clk);                // Clock high
  }                             // Ende for (LPp = 0; LPp == 7; LPp++)
                                //
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//      Neue Zeilen einschalten mit case TC, danach strobe auf Schieberegister
// - - - - - - - - - - - - - - -
  switch (TC) {                 //
  case 1:                       //
    SetBit (PORTC, 0);          // Zeile 1 ein - erste Zeile
    break;                      // switch verlassen
  case 2:                       //
    SetBit (PORTC, 1);          // Zeile 2 einschalten
    break;                      // switch verlassen
  case 3:                       //
    SetBit (PORTC, 2);          //
    break;                      //
  case 4:                       //
    SetBit (PORTC, 3);          //
    break;                      //
// - - - - - - - - - - - - - - -
  case 5:                       //
    SetBit (PORTD, 4);          // Zeile 5 einschalten
    break;                      // switch verlassen
  case 6:                       //
    SetBit (PORTD, 5);          //
    break;                      //
  case 7:                       //
    SetBit (PORTD, 6);          //
    break;                      //
  case 8:                       //
    SetBit (PORTD, 7);          //
    break;                      //
  case 9:                       //
    SetBit (PORTB, 0);          //
    break;                      //
  case 10:                      //
    SetBit (PORTB, 1);          // Zeile 0 einschalten
    break;                      // switch verlassen
  default:
    break;
  }                             // Ende switch (TC), Zeile TC einschalten
// - - - - - - - - - - - - - - -
//      Neue Zeilen sind eingeschaltet, jetzt strobe
                                //
  ClrBit (PORTB, str);          // Strobe low
  SetBit (PORTB, str);          // Strobe high
                                // Ende Ausgabe für Zeilen
// - - - - - - - - - - - - - - -
    ClrBit (PORTD, 3);            // Zeitnahmeblink aus
    //  Zeitnahme am 20. Feb. 2011: Routine x10 benötigt 
  return;                       // Ende ISR
 }                              //
// ===============================================================================
So - aufgefallen ist mir dabei, dass mehrere LEDs in einer Reihe leuchten können - ist ja klar, weil mehrere eben mehr Strom brauchen als eine *ggg*. Einfachstes Beispiel: beide Schläger stehen auf gleicher Höhe, es leuchten zwei LEDs in einer Reihe und damit sieht man ein klitzekleines Einbrechen der Helligkeit. Das stimmt ja auch mit einfachsten Überlegungen überein. Es ist kaum merklich - aber ich wollte wissen, ob diese Matrixfahrweise eben die LEDs einzeln oder zeilenweise ansteuert.

Also - zeilenweise. Und der geringe Helligkeitseinbruch ist ja auch praktisch kaum zu sehen.

Nochmal danke für die Hilfe.