Forum: Mikrocontroller und Digitale Elektronik Framebegrenzer mit Atmega8


von Daniel K. (Firma: keine) (minotaurus)


Lesenswert?

Hiho,
ich brauch einen Framebegrenzer für ein Pacman mit dem Atmega8.
Also ich dachte mir sowas mach man sicher mit nem Timer oder nem Counter 
oder sowas. Aber wie kann man diesen unter WinAvr (also mit der Sprache 
"C") nutzen?
Und wieviel Zeit darf denn dann so nen Frame haben? Ich glaube 40ms 
oder?

von Mathi (Gast)


Lesenswert?

Die Dauer eines Frames hängt von der Bildwiederholrate ab.

Aber was meinst Du mit einem Framebegrenzer?

von Daniel K. (Firma: keine) (minotaurus)


Lesenswert?

Der sorgt dafür, dass nur 25 Bilder pro Sekunde gemalt werden. In meinem 
Fall ist das egal, aber es sollen halt auch die Berechnungen begrenzt 
werden. Also z.B. soll Pacman nur 25 mal pro Sekunde seine Position 
aktualisieren.
Es soll eine Schleife da sein, die nur alle 40ms einmal durchläuft oder 
auch anders, da gibt es ja mehrere Möglichkeiten.
Mich interessiert halt wie man die Timer nutzt oder ob das anders besser 
zu machen ist.

von Daniel K. (Firma: keine) (minotaurus)


Lesenswert?

Keiner eine Idee?

von Benedikt K. (benedikt)


Lesenswert?

Timerinterrupt: 25Hz
In diesem eine Variable auf 1 setzen, und irgendwo im Spielablauf dann 
die Abfrage:
while (!wait40ms);
wait40ms=0;

von Daniel K. (Firma: keine) (minotaurus)


Lesenswert?

:) danke so in etwa hatte ich mir das auch gedacht, aber mein Problem 
ist eher wie man das auf nem Atmega8 in "C" Programmiert. Also wie man 
den Timer einstellt und aktiviert.

von Christian L. (lorio)


Lesenswert?

Daniel Kehr wrote:
> :) danke so in etwa hatte ich mir das auch gedacht, aber mein Problem
> ist eher wie man das auf nem Atmega8 in "C" Programmiert. Also wie man
> den Timer einstellt und aktiviert.

Sei mir nicht böse, aber ist dein Problem WIRKLICH das, dass du nicht 
weist, wie man in C den Timer etc. konfigurierst, oder ist es eher, dass 
du garnicht weist, wie man den Timer etc. konfiguriert?

von Daniel K. (Firma: keine) (minotaurus)


Lesenswert?

Hmm, wo ist da der Unterschied? Ich programmier den Controller nunmal in 
C und da weis ich nicht wie das geht. Wie es in einer anderen 
Programmiersprache geht weis ich dementsprechend auch nicht.

von Kai G. (runtimeterror)


Lesenswert?

>Hmm, wo ist da der Unterschied?
Ich könnte dir das z.B. nur in ASM und anhand des Datenblattes erklären 
- C müsste ich mir zusammenkratzen.

von Daniel K. (Firma: keine) (minotaurus)


Lesenswert?

Naja, Assembler ist doch auch schonmal was. Ich denke ich werd es schon 
halbwegs übersetzen können.

von Kai G. (runtimeterror)


Lesenswert?

Schau dir das mal an:
AVR-Tutorial: Timer

Fehlt dir da noch was für die Umsetzung?

von Karl (Gast)


Lesenswert?

Wie jetz? Pacman für nen AVR gestrickt aber keine Ahnung von C? 
Datenblatt, AVR-Tutorials hier in der Artikelsammlung und ein Hauch 
Eigeninitiative. Mehr brauchts nicht.

von Peter D. (peda)


Lesenswert?

Daniel Kehr wrote:
> Hmm, wo ist da der Unterschied? Ich programmier den Controller nunmal in
> C und da weis ich nicht wie das geht.

Timer gehören nicht zum C-Sprachumfang und daher gibt es auch keine 
Timerfunktionen in C.
Du hast auf dem AVR auch kein OS, welches Dir Systemcalls zur Verfügung 
stellt.

Timer sind als Hardware im AVR ausgeführt, d.h. um sie anzusprechen, 
mußt Du das Datenblatt lesen und dann auf die entsprechenden IO-Register 
zugreifen.



Peter

von Daniel K. (Firma: keine) (minotaurus)


Lesenswert?

@Karl: Welchen Sinn hatte der Beitrag. Es gibt sicher auch SpamForen für 
solch nutzlose Beiträge.

@Kai: Danke. Ich werde es mir mal anschauen.

@Peter: Danke, dann brauch ich ja danach nichtmehr zu suchen.

Gibt es denn keine INCLUDE-Datei für die Timer? Nagut, trotzdem danke.

von Simon K. (simon) Benutzerseite


Lesenswert?

Daniel Kehr wrote:
> @Karl: Welchen Sinn hatte der Beitrag. Es gibt sicher auch SpamForen für
> solch nutzlose Beiträge.

Jaja, sei mal lieber nicht so frech ;)

> Gibt es denn keine INCLUDE-Datei für die Timer? Nagut, trotzdem danke.

Nein, das braucht es auch nicht. Wofür sollte es denn 
Funktionen/Datentypen/Macros/whatever für den Timer geben?

von Bernhard R. (barnyhh)


Lesenswert?

Warum fällt mir dazu immer der blöde Witz aus den 1950er Jahren ein:
Mutter: "Fritzchen, was wünscht Du Dir zu Weihnachten?"
Fritzchen: "OB!"
...
Mutter: "Ja, warum das denn?"
Fritzchen: "Weil man damit schwimmen und Schlittschuh laufen und Fahrrad 
fahren kann!"

Q: "Warum willst Du C programmieren?"
A: "Weil man damit PACMAN, Windows, Linux machen kann!"

kopfschüttelnd
Bernhard

von Daniel K. (Firma: keine) (minotaurus)


Lesenswert?

:)
Hätte ja sein können.
Hab das mal grob überflogen, kann man denn den Vorteiler beliebig wählen 
oder muss der 1,8,64,256 oder 1024 sein?

von Steffen (Gast)


Lesenswert?

Hallo,

was ist eigentlich das Ziel? Hast du auf einem AVR Pacman programmiert? 
Oder willst du ein externes Gerät begrenzen?

Sorry für die dumme Frage.

Steffen.

von Karl (Gast)


Lesenswert?

Der Beitrag von  Kai Giebeler war noch nicht da, als ich meinen 
geschrieben habe.
Der Sinn des Beitrags: Die immer wieder auftauchende Frage nach Timer 
und Co. auf das Tutorial lenken, falls du das noch nicht kanntest. Dazu 
die Aufforderung, dir das Datenblatt durchzulesen. Da steht beinahe 
alles drin, was du wissen musst. Der Wink mit der Eigeninitiative sollte 
wohl die Frage verhindern, welchen wert du nun in welches Register zu 
welchem Zeitpunkt schreiben musst.

von Karl (Gast)


Lesenswert?

>Hab das mal grob überflogen, kann man denn den Vorteiler beliebig wählen
>oder muss der 1,8,64,256 oder 1024 sein?

Da ist es schon. Datenblatt!

von Daniel K. (Firma: keine) (minotaurus)


Lesenswert?

@Bernhard Reichenbach: Also ein eigenes kleines Betriebssystem hab ich 
schon programmiert. Das ist ja nicht so extrem schwer.
Warum programmierst du denn C?

@Steffen: Naja, ich hab hier nen Display und den Mega8 verbunden und 
möchte ganz einfach wie bei jedem Spiel, welches ich bisher auf dem 
Rechner programmiert habe auch hier eine Framebremse.

von Bj (Gast)


Lesenswert?

Ein Betriebssystem programmiert ohne den Haus einer Ahnung wie man 
Hardware (Timer) anspricht. Das muss ein tolles System sein, oder 
meintest du "while(1){}" mit Betriebssystem ??

Mal Spass beiseite, wie willst du jemals auf dem Display was sehen 
können wenn du nicht mal die Hardware ansprechen kannst ? Alleine die 
Frage nach dem  beliebigen Vorteiler disqualifiziert dich hier....

Leute gibt's (kopfschüttel....)

von Bernhard R. (barnyhh)


Lesenswert?

@Daniel Kehr:
Hic Rhodos, hic salta!
Bitte den Source-Code vom Betriebssystem!

Und "Warum" fragen Kindergarten-Kinder.

von Daniel K. (Firma: keine) (minotaurus)


Lesenswert?

Sorry, das ist der einzige Code den ich noch finden konnte, da ist 
allerdings einiges nicht von mir(alles was hinter dem Code noch 
kommentiert ist ist nicht von mir :) ). Es handelt sich dabei um die 
Interupt Routine 21. Ich weis nicht wo die Endversion hin ist, sorry. 
Bootloader und Kernel hab ich natürlich auch noch. So, hier:
1
;###Int 21h
2
int21h:
3
cmp ah,0h
4
JE pr_z
5
cmp ah,01h
6
JE pr_str
7
cmp ah,02h
8
JE rd_z
9
cmp ah,03h
10
JE rd_z_a
11
cmp ah,04h
12
JE rd_string
13
cmp ah,05h
14
JE rd_string_lenght
15
mov al,1 ;Fehlercode
16
int21h_e:
17
iret
18
;###Int 21h Ende
19
20
21
22
23
;### Zeichen ausgeben
24
pr_z:
25
mov ah,0eh
26
int 10h
27
iret
28
;###Zeichenausgeben ende
29
30
;### Stringausgabe int 21h ah=01h begrenzungszeichen=ASCII 0 BX=OFFSET
31
pr_str:
32
lodsb             ; Byte laden
33
or al,al
34
jz short putstrd  ; 0-Byte? -> Ende!
35
mov ah,0x0E       ; Funktion 0x0E
36
mov bx,0x0007     ; Attribut-Byte (wird nicht bentigt)
37
int 0x10          ; schreiben
38
jmp pr_str
39
putstrd:
40
iret
41
;### Stringausgabe ende
42
43
;###Zeichen von Tastatur einlesen
44
rd_z:
45
mov ah,0
46
int 16h
47
iret
48
;### 
49
50
;###Zeichen von Tastatur lesen und ausgeben
51
rd_z_a:
52
mov ah,0
53
int 16h
54
mov ah,0eh
55
int 10h
56
iret
57
;###Zeichen einlesen ende
58
59
;###String einlesen
60
;#BX:Offset
61
rd_string:
62
mov cx,0
63
push cx
64
mov [bx],cx
65
rd_str:
66
mov ah,0
67
int 16h
68
cmp al,13
69
JE rd_str_ende
70
cmp al,8
71
jne rd_str_weiter
72
pop cx
73
cmp cx,0
74
push cx
75
je rd_str
76
mov ah,3
77
mov bh,0
78
int 10h
79
mov ah,2
80
mov bh,0
81
dec dl
82
int 10h
83
mov al,0
84
mov ah,0eh
85
int 10h
86
mov ah,2
87
int 10h
88
pop cx
89
dec cx
90
push cx
91
dec bx
92
mov [bx],al
93
jmp rd_str
94
rd_str_weiter:
95
mov ah,0eh
96
int 10h
97
pop cx
98
inc cx
99
push cx
100
mov [bx],al
101
inc bx
102
xor ax,ax
103
mov [bx],al
104
jmp rd_str
105
rd_str_ende:
106
inc bx
107
mov cx, 0
108
mov [bx], cx
109
pop cx
110
jmp int21h_e
111
;###String einlesen ende
112
iret
113
114
rd_string_lenght:
115
mov cx, 0
116
rd_string_lenght_start:
117
; Einen String ausgeben:
118
lodsb                ; Byte laden
119
or al,al
120
jz short rd_string_lenght_ende     ; 0-Byte? -> Ende!
121
inc cx
122
jmp rd_string_lenght_start ; Nchstes Byte
123
rd_string_lenght_ende:
124
iret
125
126
127
times 512-($-$$)-0 db 0   ; Dateilnge: 512 Bytes

Des weiteren hab ich die komplette Ausgabe auf dem Display schon, ich 
will ganz einfach nur die Häufigkeit der Berechnungen begrenzen.

von Matthias L. (Gast)


Lesenswert?

>ganz einfach nur die Häufigkeit der Berechnungen begrenzen.

Dann verwende das Zeitschlitzverfahren!
(Codeauzugaus einem meiner Projekte)
1
// timer1 ovfl 14,7456MHz/65536 = 4,444ms (225Hz) ***************
2
ISR ( TIMER1_OVF_vect )
3
{
4
  //-- increase global timebase ---------------------------------
5
  u16TimeBaseTick++;
6
}
7
void  main  (  void  )
8
{
9
  //-- local variables ----------------------------------------------
10
  uint16_t  _u16TimeBaseTickLast  = 0x0000;
11
  uint16_t  _u16TimeStampMode     = 0x0000;
12
  //-- initialisations ----------------------------------------------
13
  init_timebase  ();
14
  sei  ();
15
  //-- endless loop, call modes -------------------------------------
16
  while  (1)
17
  {
18
    //-- call modes every 4,44 ms ---------------
19
    if ( _u16TimeBaseTickLast  != u16TimeBaseTick )
20
    {
21
      _u16TimeBaseTickLast = u16TimeBaseTick;
22
      //-- fetch start time ---------------------
23
      _u16TimeStampMode  =  TCNT1;
24
      //-- call mode routine --------------------
25
      taskaufruf1 ();
26
      taskaufruf2 ();
27
      ...
28
      //-- calculate procesing time -------------
29
30
    }
31
  }
32
}

So arbeiten auch SPS'en..
Die verschiedenen Tasks werden einfach alle x Millisekunden aufgerufen..

von Daniel K. (Firma: keine) (minotaurus)


Lesenswert?

Sorry, aber das hätte ich hinbekommen, zwar hätte ich es ein bissle 
anders gemacht, aber es kommt aufs gleiche raus. Was mir fehlt ist nur 
der Teil, der sich hinter init_timebase  (); verbirgt.

Bei mir ist es halt der Timer0 und nicht der Timer1, aber ich nehm auch 
gerne den Timer1, hab ich nichts dagegen.

Bei mir sieht das gerade so aus. Aber das funktioniert nicht so recht.
1
  .global init_Timer 
2
init_Timer:
3
        ldi     temp, 0x04      ; CS00 setzen: Teiler 256
4
        out     TCCR0, temp
5
 
6
        ldi     temp, 0x01      ; TOIE0: Interrupt bei Timer Overflow
7
        out     TIMSK, temp
8
 
9
        ret

von Matthias L. (Gast)


Lesenswert?

sorry, hatte ich vergessen reinzukopieren:
1
//** init timer1 in normal mode, overflow every 4,44ms **********************************
2
void init_timebase ( void )
3
{
4
  //-- set clk => 14,7456MHz in normal mode -------------------------
5
  TCCR1B |= (1<<CS00);
6
  //-- enable overflow interrupt ------------------------------------
7
  TIMSK |= (1<<TOIE1);
8
}

von Daniel K. (Firma: keine) (minotaurus)


Lesenswert?

Danke, aber er macht trotzdem nicht was er soll. Ich hab CS10 auf 1 
gesetzt und lass immer eine Variable bis 240 Zählen und dann wird ein 
Ereignis aus ausgelöst.

Mein Mega8 läuft auf 16 MHz. Somit sollte doch eigentlich rund jede 
Sekunde einmal dieses Ereignis ausgelöst werden, oder?

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.