Forum: Mikrocontroller und Digitale Elektronik Geisterbilder auf einer 8 x 8 Matrix


von Dieter B. (Gast)


Lesenswert?

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;

von Max D. (max_d)


Lesenswert?

Dieter B. schrieb:
>PORTC |= (1<<PC7);
> PORTB = 0x00;
>
>     PORTB = VRAM[1];

Das passiert SEHR schnell auf dem µC (keine 10 takte), da wird der PORTB 
noch restladung haben.

Unabhängig davon: Nimm dafür doch einen Timer-Interrupt für das 
multiplex

von Max D. (max_d)


Lesenswert?

Dieter B. schrieb:
> PORTB = 0x00;
>
>     PORTB = VRAM[1];

Mahc hier in diese Lücken mal ein kleines delay ( paar µs)

von Dieter B. (Gast)


Lesenswert?

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...

von Karl H. (kbuchegg)


Lesenswert?

Zeig mal deine Schaltung.

von Max D. (max_d)


Lesenswert?

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).

von Dieter B. (Gast)


Lesenswert?

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 )

FET: PMN28UN

von Karl H. (kbuchegg)


Lesenswert?

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.

: Bearbeitet durch User
von Dieter B. (Gast)


Lesenswert?

Ich habe mir das auch schon gedacht.
Ich sollte den 1MOhm vill. gegen 10Ohm tauschen ?

von Karl H. (kbuchegg)


Lesenswert?

Dieter B. schrieb:
> Ich habe mir das auch schon gedacht.
> Ich sollte den 1MOhm vill. gegen 10Ohm tauschen ?

Hab nicht zu Ende gedacht.
Ich würde mal die 1K rauswerfen!

Edit: wenn nicht überhaupt ein FET-Treiber notwendig wird.

: Bearbeitet durch User
von Dieter B. (Gast)


Lesenswert?

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...

von Karl H. (kbuchegg)


Lesenswert?

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)

: Bearbeitet durch User
von Dieter B. (Gast)


Lesenswert?

Ich habe diese komplett durch "0Ohm" Brücken ersetzt.
Ist weiterhin vorhanden.

Mist...

von Dieter B. (Gast)


Lesenswert?

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)

von Karl H. (kbuchegg)


Lesenswert?


von MaWin (Gast)


Lesenswert?

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.

von Dieter B. (Gast)


Lesenswert?

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?

von Karl H. (kbuchegg)


Lesenswert?

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.

: Bearbeitet durch User
von Dieter B. (Gast)


Lesenswert?

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 ?

von Karl H. (kbuchegg)


Lesenswert?

Dieter B. schrieb:
> Wenn ich meine Animation laufen lassen will, klappt das nicht aufgrund
> des "_delay_us(1)"

Du kannst es drehen und wenden wie du willst. Deine FET müssen 
schneller schalten. Sonst ist das ganze witzlos.

von Max D. (max_d)


Lesenswert?

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

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

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.

von MaWin (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von H.Joachim S. (crazyhorse)


Lesenswert?

Mal ne ganz blöde Frage - wie sieht es denn mit DDRB/DDRC aus?

von Max D. (max_d)


Lesenswert?

H.Joachim Seifert schrieb:
> Mal ne ganz blöde Frage - wie sieht es denn mit DDRB/DDRC aus?

Wenn die auf Eingang wären, dann würde man die LEDs bei einem 1/8 
Multiplex nichtmehr sehen.

@TO: wie oft in der Sekunden geht denn dein Timer-Interuppt los ?

von Dieter B. (Gast)


Lesenswert?

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;

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.