Forum: Mikrocontroller und Digitale Elektronik ATMega16 LED Matrix


von Tomato (Gast)


Lesenswert?

Hallöchen alle miteinander!

Ich habe das Ziel mit meinem ATMega16 ein kleines Tetris Spiel zu 
programmieren, welches auf zwei 7x5 LED Matrizen abgebildet werden soll.
Schritt für Schritt taste ich mich gerade ran, jedoch stehe ich gerade 
vor einem Problem, welches ich nocht nicht so lösen konnte.
Fallen direkt zwei Punkte hintereinander runter verschwindet beim 
Übergang von der oberen in die untere Matrix einer der Punkte (der 
obere).
Also die letzte Zeile der oberen Matrix wird nicht mehr angezeigt, 
sobald die obere Zeile der unteren Matrix angesprochen wird.

xo sind die Variablen für die obere Matrix und xu die Variablen für die 
untere Matrix.
1
#define F_CPU 16000000
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
5
uint16_t matrix2d[5][2] = {{0,0},{0,0},{0,0},{0,0},{0,0}};
6
7
void Init();
8
void InitPorts();
9
void InitTimer();
10
11
volatile uint_8 var = 1;
12
volatile uint8_t c = 0;
13
volatile uint16_t slowy = 0;
14
volatile uint8_t xo1 = 3;
15
volatile uint8_t xo2 = 0;
16
volatile uint8_t xo3 = 0;
17
volatile uint8_t xo4 = 0;
18
volatile uint8_t xo5 = 0;
19
volatile uint8_t xu1 = 0;
20
volatile uint8_t xu2 = 0;
21
volatile uint8_t xu3 = 0;
22
volatile uint8_t xu4 = 0;
23
volatile uint8_t xu5 = 0;
24
int main(void)
25
{
26
  Init();
27
  while (1)
28
  {
29
   }
30
}
31
32
void Init()
33
{
34
  InitPorts();
35
  InitTimer();
36
}
37
38
void InitPorts()
39
{
40
  DDRA= 0xFF;
41
  DDRB= 0x1F;
42
  DDRC= 0xFF;
43
  DDRD= 0x00;
44
}
45
46
void InitTimer()
47
{
48
  //Timer1
49
  TCCR1B |= (1<<CS10) | (1<<CS12) | (1<<WGM12);
50
  TIMSK |= (1<<OCIE1A);
51
  OCR1A = 5;
52
  
53
  sei();
54
}
55
56
ISR(TIMER1_COMPA_vect)
57
{
58
//Multiplexen der Transistoren
59
  PORTA &= ~0xFF;
60
  PORTC &= ~0xFF;
61
   
62
  var=var*2;
63
  if (var==32)
64
  {
65
  var=1;
66
  }
67
  PORTB = ~var;
68
69
c++;
70
if (c == 5)
71
{
72
  c = 0;
73
}
74
75
//slowy für eine "angenehme" Geschwindigkeit
76
slowy++;
77
if (slowy == 1500)
78
{
79
  slowy=0;
80
//"fallende" Punkte
81
  if (xu1 <= 64)
82
  {
83
    xu1=xu1*2;
84
  }
85
  if (xo1 < 127)
86
  {
87
    xo1=xo1*2;
88
  }
89
  if (xo1 > 127)
90
  {
91
    xo1=xo1*2;
92
    
93
    if (xu1<0x15)
94
    {
95
      xu1=xu1+1;      
96
    }      
97
  }  
98
}
99
100
//Übergabe der Werte ans Array
101
matrix2d[0][0]=xo1;
102
matrix2d[1][0]=xo2;
103
matrix2d[2][0]=xo3;
104
matrix2d[3][0]=xo4;
105
matrix2d[4][0]=xo5;
106
matrix2d[0][1]=xu1;
107
matrix2d[1][1]=xu2;
108
matrix2d[2][1]=xu3;
109
matrix2d[3][1]=xu4;
110
matrix2d[4][1]=xu5;
111
112
//Ausgabe des Arrays
113
PORTA |= matrix2d[c][0];
114
PORTC |= matrix2d[c][1];
115
116
//Debug LED
117
PORTA ^= (1<<PA7);
118
}

von Michael B. (laberkopp)


Lesenswert?

Tomato schrieb:
>   if (xo1 < 127)
>   {
>     xo1=xo1*2;
>   }
>   if (xo1 > 127)

Wenn man bits abfragt, würde ich eher xo&0x80 auswerten, als ein grösser 
oder kleiner, sonst passiert so ein Mist wie <127 und >127 und keiner 
weiss was genau bei 127 passieren soll.

>     if (xu1<0x15)

?!?

von Falk B. (falk)


Angehängte Dateien:

Lesenswert?

Tomato schrieb:

> Fallen direkt zwei Punkte hintereinander runter verschwindet beim
> Übergang von der oberen in die untere Matrix einer der Punkte (der
> obere).
> Also die letzte Zeile der oberen Matrix wird nicht mehr angezeigt,
> sobald die obere Zeile der unteren Matrix angesprochen wird.
>
> xo sind die Variablen für die obere Matrix und xu die Variablen für die
> untere Matrix.

Naja, bei Namen wie x01, xo2 etc. schreit das gerade nach einem Array. 
Auch deine Platzierung der Matrixfülllogik in der ISR ist nicht 
sinnvoll. Für einen Test mag das OK sein, für weitere 
Softwareentwicklung eher nicht. Deine ganzen volatile Definitionen der 
Variablen sind sinnlos, denn diese werden hier nur in der ISR benutzt, 
nicht im Hauptprogramm. Deine "fallenden Punkte" kann man einfacher und 
übersichtlicher prgrammieren. Wenn man eine Bitversciebung erreichen 
will, schreibt man das meist auch so hin, auch wenn ein *2 logisch das 
Gleiche bewirkt. Deine Logik deiner fallenden Punkte über 2 verteilte 
Bytes hab ich jetzt nicht im Detail geprüft, wo da der Fehler liegt. Das 
Problem kann man aber vereinfachen, indem man einfach 16 Bit für deine 
LED-Matrix benutzt. Upps, das hast du ja schon, aber die oberen 16 Bit 
sind immer ungenutzt. Warum? Siehe Anhang.

Man kann es mit der Modularität und den Unterfunktionen auch 
übertreiben. So einfache Initialisierungen schreibt man einfach so hin 
und gut, da braucht es keine Funktion.

Man sollte sinnvolle, aussagekräftige Variablennamen benutzen, "var" 
sagt gar nix.

Beim multiplexen einer LED-Matrix sollte man folgende Reihenfolge 
einhalten, um Geisterbilder zu vermeinden.

aktuelle Spalte ausschalten
neues Spaltenmuster berechnen und ausgeben
neue Spalte einschalten

Durch diese kleine Pause von wenigen us vermeidet man Nachleuchten des 
Musters einer Spalte in der nächsten.

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.