Geisterbilder auf einer 8 x 8 Matrix

Gast #3824718
Hallo Leute,

ich Multiplexe zur Zeit meine 8 x 8 Matrix Testweise in der while(1)

- MEGA32 / 16 MHz...


Leider sehe ich auf meiner LED Matrix ständig "Geisterbilder"

So sieht mein Code aus... Mache ich was falsch ? Später soll das ganze 
zwei ISR Interrupts übernehmen...
1
    PORTB = VRAM[0];
2
    PORTC |= (1<<PC7);
3
    _delay_ms(2);
4
    PORTC &=  ~(1<<PC7);
5
    PORTB = 0x00;
6

7
    PORTB = VRAM[1];
8
    PORTC |= (1<<PC6);
9
    _delay_ms(2);
10
    PORTC &= ~(1<<PC6);
11
    PORTB = 0x00;
12
    
13
    PORTB = VRAM[2];
14
    PORTC |= (1<<PC5);    
15
    _delay_ms(2);
16
    PORTC &= ~(1<<PC5);
17
    PORTB = 0x00;
18
    
19
    PORTB = VRAM[3];
20
    PORTC |= (1<<PC4);
21
    _delay_ms(2);
22
    PORTC &= ~(1<<PC4);
23
    PORTB = 0x00;
24

25
    PORTB = VRAM[4];
26
    PORTC |= (1<<PC3);
27
    _delay_ms(2);
28
    PORTC &= ~(1<<PC3);
29
    PORTB = 0x00;
30

31
    PORTB = VRAM[5];  
32
    PORTC |= (1<<PC2);
33
    _delay_ms(2);
34
    PORTC &= ~(1<<PC2);
35
    PORTB = 0x00;
36

37
  
38
    PORTB = VRAM[6];    
39
    PORTC |= (1<<PC1);
40
    _delay_ms(2);
41
    PORTC &= ~(1<<PC1);
42
    PORTB = 0x00;
43

44
    PORTB = VRAM[7];  
45
    PORTC |= (1<<PC0);
46
    _delay_ms(2);
47
    PORTC &= ~(1<<PC0);
48
    PORTB = 0x00;
Gast #3824742
Das habe ich ja auch schon versucht mit dem Timer Interrupt.
Wenn ich alles in einem Interrupt erledige (AN & AUS)
Habe ich den gleichen Effekt...
#3824747
Zwischen dem aus von einer Zeile und dem an der nächsten sollte immer 
etwas Zeit sein. Mit einem Oszi siehst du die Entladekurve, ansonsten µs 
weise immer länger warten bis das ghosting weg ist (dauerte bei mir 
immer so 3-5 µS).
#3824755
Dieter B. schrieb:
> Karl Heinz schrieb:
>> Zeig mal deine Schaltung.
>
> Muss den erstmal suchen.
> Aufjedenfall schalte ich die Zeilen mit nem N-Kanal FET...
>
> Spannungsteiler ( 1 kOhm zum Gate --> 1MOhm gegen GND )

Das könnte ein wenig hoch sein.

Das Problem bei FET besteht darin, dass man sie sich wie mit einem 
eingebauten Kondensator vorstellen muss. D.h. man braucht da am Gate 
schon ordentlich Power um den FET schnell zu schalten. Und schnell 
schalten ist bei einer Matrix so gut wie alles. Mit deinen paar 
Milliampere wirst du da nicht viel reissen.
Gast #3824763
Meine letzte 8 x 8 Matrix hatte keine FET´s...
Diese habe ich in der ISR abgearbeitet....
1
/* Multiplexen der Anzeige */
2
ISR(TIMER0_COMP_vect)
3
{
4
  
5
  
6
  
7
  cli();
8
  
9
  
10
    static volatile uint8_t spalte = 0;
11

12
    PORTC &= ~((1<<PC7) | (1<<PC6) | (1<<PC5) | (1<<PC4) | (1<<PC3));
13
    PORTB &= ~((1<<PB2) | (1<<PB1) | (1<<PB0));
14
    
15
    // neue Zeilendaten ausgeben
16
    
17
  PORTA = ~(VRAM)[spalte];
18
    
19
    // Spalte aktivieren  
20
    switch (spalte) {
21
      case 0: PORTC |= (1<<PC3);
22
      break;
23
      case 1: PORTC |= (1<<PC4);
24
      break;
25
      case 2: PORTC |= (1<<PC5);
26
      break;
27
      case 3: PORTC |= (1<<PC6);
28
      break;
29
      case 4: PORTC |= (1<<PC7);
30
      break;
31
      case 5: PORTB |= (1<<PB2);
32
      break;
33
      case 6: PORTB |= (1<<PB1);
34
      break;
35
      case 7: PORTB |= (1<<PB0);
36
      break;
37
      default: break;
38
    }
39

40
    spalte++; // nächste Spalte
41
    if (spalte >= 8) spalte = 0; // Spalten 0..7  
42
  
43
  sei();  
44
}

das hat wunderbar funktioniert... blos waren die LED´s ziemlich 
dunkel...
das lag aber an der Puls / Pausenzeit...
#3824766
Dieter B. schrieb:
> Meine letzte 8 x 8 Matrix hatte keine FET´s...
> Diese habe ich in der ISR abgearbeitet....

> das hat wunderbar funktioniert... blos waren die LED´s ziemlich
> dunkel...
> das lag aber an der Puls / Pausenzeit...

mit Sicherheit nicht.

Deine Puls/Pausen Zeiten sind so, dass 99.9% der Zeit irgendeine Zeile 
leuchtet. Woran es auch immer alg, an den Puls/Pausen Zeiten sicher 
nicht. Die ISR dauert ein paar Taktzyklen pro Durchlauf. Bei 16Mhz 
leuchtet da vielleicht 1µs oder 2µs nichts. Aber den Rest der Zeit 
leuchtet eine Zeile.

Bis auf das cli()/sei() in der ISR ist die Methode korrekt. Schmeiss die 
auf jeden Fall raus. Die haben in einer ISR nichts verloren (zumindest 
nicht in deiner ISR)
Gast #3824794
Ich habe jetzt in der ISR noch eine Wartezeit von ca. 1ms eingebaut.
Jetzt sind die "Geisterbilder" nur noch sehr sehr schwach zu sehen (bis 
gar nicht mehr)
Gast #3824800
Dieter B. schrieb:
> Ich habe jetzt in der ISR noch eine Wartezeit von ca. 1ms eingebaut.
> Jetzt sind die "Geisterbilder" nur noch sehr sehr schwach zu sehen (bis
> gar nicht mehr)

Deine Schaltung ist das Problem, denn LEDs haben schon bei deinem ersten 
Programm kein Problem mit der Umschaltzeit.

Karl Heinz schrieb:
>> das lag aber an der Puls / Pausenzeit...
> mit Sicherheit nicht.

Mit SIchehreit doch, denn in einer 8x8 Matrix ist eine LED nur 1/8 der 
Zeit an, und ohne FETs bekommt er nur die 20mA Strom aus dem AVR, und 
die gilte für alle 8 LEDs einer Reihe zusammen.
Also leuchtet seine LED so hell, als würde man sie mit 0.3mA betrieben.
Gast #3824803
Karl Heinz schrieb:
> Ist aber trotzdem mies.
>
> Beitrag "FET mit AVR schalten - Wie schnell?"

Danke für den Link ( lese ich mir gleich mal durch )

Sollte ich das "Ein / Aus" Schalten jetzt nur mit einem Interrupt machen 
oder es lieber auf "2" Verteilen?
#3824805
MaWin schrieb:

>>> das lag aber an der Puls / Pausenzeit...
>> mit Sicherheit nicht.
>
> Mit SIchehreit doch,

Ansichtssache.

> denn in einer 8x8 Matrix ist eine LED nur 1/8 der
> Zeit an, und ohne FETs bekommt er nur die 20mA Strom aus dem AVR, und
> die gilte für alle 8 LEDs einer Reihe zusammen.

Da kann aber das Puls/Pausen Verhältnis nichts dafür, wenn er seine 
Schaltung zu schwach auslegt. Vor allen Dingen kann er per Programm 
nichts dagegen tun.
Gast #3824813
Wenn ich meine Animation laufen lassen will, klappt das nicht aufgrund 
des "_delay_us(1)"

[c}
/* TIMER0 PWM generating */
ISR(TIMER0_OVF_vect)
{


  static volatile uint8_t spalte = 0;

  PORTC &= ~((1<<PC0) | (1<<PC1) | (1<<PC2) | (1<<PC3) | (1<<PC4) | 
(1<<PC5) | (1<<PC6) | (1<<PC7));

  PORTB = (VRAM)[spalte];

  switch (spalte)
  {
    case 0: PORTC |= (1<<PC7);
    break;
    case 1: PORTC |= (1<<PC6);
    break;
    case 2: PORTC |= (1<<PC5);
    break;
    case 3: PORTC |= (1<<PC4);
    break;
    case 4: PORTC |= (1<<PC3);
    break;
    case 5: PORTC |= (1<<PC2);
    break;
    case 6: PORTC |= (1<<PC1);
    break;
    case 7: PORTC |= (1<<PC0);
    break;
    default: break;
  }

  _delay_us(100);

  spalte++; // nächste Spalte

  if (spalte >= 8) spalte = 0; // Spalten 0..7


}// End ISR(TIMER0_OVF_vect)

[/c]

kann ich dagegen was tun ?
#3824821
Da wo dein _delay_us steht hat es genau 0 effekt
gehört hätte es so:
1
  PORTC &= ~((1<<PC0) | (1<<PC1) | (1<<PC2) | (1<<PC3) | (1<<PC4) | 
2
(1<<PC5) | (1<<PC6) | (1<<PC7));
3
  _delay_us(5);
4

5
  PORTB = (VRAM)[spalte];
So wartest du nach dem ausschalten der treiber bis die fets entladen 
sind bevor du die neue reihe anzeigst
#3824823
PS:
der delay in deiner ISR ist an dieser Stelle völlig sinnlos.
Zu dem Zeitpunkt, an dem der zum Tragen kommt, ist bereits alles 
erledigt, alle Schaltvorgänge sind abgeschlossen und er verzögert nur 
noch den Return aus der ISR. Man könnte auch sagen: der lungert nur noch 
so rum und stiehlt dem eigentlichen Programm nur die Zeit.
Gast #3824826
Karl Heinz schrieb:
> Da kann aber das Puls/Pausen Verhältnis nichts dafür, wenn er seine
> Schaltung zu schwach auslegt.

Er SCHRIEB (mit den Worten "keine FET's") daß er sie zu schwach 
ausgelegt hat, wohl weil er nicht bedacht hatte, daß die einzlne LED in 
einer Multiplexanzege  den Strom in Pulsen für 1/8 der Zeit bekommt.
#3824828
MaWin schrieb:
> Karl Heinz schrieb:
>> Da kann aber das Puls/Pausen Verhältnis nichts dafür, wenn er seine
>> Schaltung zu schwach auslegt.
>
> Er SCHRIEB (mit den Worten "keine FET's") daß er sie zu schwach
> ausgelegt hat, wohl weil er nicht bedacht hatte, daß die einzlne LED in
> einer Multiplexanzege  den Strom in Pulsen für 1/8 der Zeit bekommt.

Ohne konkrete Schaltung ist das alles nur Spekulation.
Gast #3824889
int main(void)
{

  DDRB |= (0xFF);
  DDRC |= (0xFF);

  /* Prescaler from TIMER0 set at "0"  ! ( PWM & Multiplexing ) */
  TCCR0 |= (1<<CS00) | (1<<WGM00) | (1<<WGM01);

  /* Prescaler set at "64" ( 25 ms base ) */
  TCCR1B |= (1<<CS11) | (1<<CS10) | (1<<WGM12);

  /* Interrupt "CompareMatch (OCIE1A)" & "TimerOverflow (TOIE0)" enable 
*/
  TIMSK  |= (1<<OCIE1A) | (1<<OCIE0) | (1<<TOIE0);

  /* CountRegister set at "6249" ( set Interrupt at 25 ms base) */
  OCR1A = 6249;

  /* Interrupts global enable */
  sei();

  /* PWM Start value */
  PWM_595 = 50;

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 12 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.