Forum: Mikrocontroller und Digitale Elektronik 16Bit Timer Problem (läuft nicht) | ATmega128


von Ano N. (oorim)


Lesenswert?

Servus

Ich wieder  8-[ Folgende Aufgabe gilt es zu lösen (ist gelöst, ich such 
nur den Fehler :D): Die LEDs solen Binär zählen und zwar per 10bit 
geteiltem 16bit Timer1, Zeit einstellbar (0...255 entsprechen dann 2,22 
bis 5,xms). Geschrieben haben wir folgenden Code
1
  .nolist              ; include-file nicht in Listing
2
  .include  "m128def.inc"    ; Definitionen für ATmega 128 einbinden
3
4
5
  .list              ; Listing erstellen
6
7
8
  .def  akku    = r16    ; r16 als Rechenregister "akku" definieren
9
  .def  msTimer    = r23    ; r23 als Zeit-Einstellungsregister
10
      ; r24 als Zählregister
11
  .def  templ    = r17    ; Zwischenspeicher 1
12
  .def  temp2    = r18    ; Zwischenspeicher 2
13
  .def  PulsCounter  = r19
14
  .equ  key_pin    = PINA    ; Tasterpins
15
  .equ  key_port  = PORTA    ; Datenregister (Taster)
16
  .equ  key_ddr    = DDRA    ; Datenrichtungsregister (Taster)
17
18
  .equ  led_port  = PORTB    ; Datenregister (LED)
19
  .equ  led_pin    = PINB
20
  .equ  led_ddr    = DDRB    ; Datenrichtungsregister (LED)
21
22
23
  .cseg
24
25
;-------Adress Tabelle für Interrupt-Vektoren-----------------------------
26
27
  .org    0x0000        ; Interrupt-Vektor für RESET
28
  rjmp    Init
29
  
30
  .org    0x0002        ; Interrupt-Vektor für externen Interrupt 1
31
  rjmp    Extint1
32
33
  .org    0x0018        ; Interrupt-Vektor für Timer/Counter-0-Interrupt
34
  rjmp    TC1int
35
36
  .org    0x0045        ; Ende der Interrupt-Vektor-Tabelle
37
38
;-------Macros-------------------------------------------------------------
39
; Pin Toggeln
40
.macro TogPin
41
  SBIS    @0,@1        ; Wenn Bit (@1) in I/O-Reg. (@2) gesetzt, überspringe nächsten Befehl
42
  rjmp    SetPin
43
ClrPin:
44
  cbi      @0,@1
45
  rjmp    TogPinx
46
SetPin:
47
  SBI      @0,@1
48
TogPinx:
49
.endmacro
50
;--------------------------------------------------------------------------
51
  
52
Init:              ; Beginn des Hauptprogrammes
53
54
  ldi      r16,LOW(RAMEND)    ; Stack Initialisieren
55
  out      SPL,r16
56
  ldi      r16,HIGH(RAMEND)
57
  out      SPH,r16
58
59
  ser      akku        ; Alle Bits in Akku setzen
60
  out      DDRB,akku      ; PORTB als Ausgang (alle Bits 1)
61
62
  ldi      msTimer,0x99
63
  out      OCR1AL,msTimer
64
65
  ldi      templ,0
66
  out      OCR1AH,templ  
67
68
  ldi      templ,0x0
69
  out      TCNT1L,templ
70
71
  ldi      templ,0x0
72
  out      TCNT1H,templ
73
74
  ldi      akku,0b00011000
75
  out      TIMSK,akku
76
77
  ldi      akku,0b00000100
78
  out      TCCR1B,akku      ; Übertrage auf Timer Counter Control Register
79
80
  
81
  ldi      PulsCounter,255
82
83
84
  
85
86
Prog:
87
  
88
  in      templ,TIFR
89
  SBRC    templ,4
90
  rcall    Count
91
  rjmp    Prog
92
93
94
;-------Unterprogramme----------------------------------------------------
95
Extint1:              ; ISR für externen Interrupt 1
96
97
  reti
98
99
Count:
100
  TogPin    led_port,0
101
102
  ret
103
104
TC1int:                ; ISR für Timer/Counter 1 Interrupt  
105
  
106
  reti
107
.exit

Der tuts aber nicht! Wenn ich den Makro Aufruf statt in Count in TC1int 
schreibe funktioniert alles Tadellos, die LED wird umgeschaltet.. .Ich 
gehe damit davon aus das der Timer sowie die einstellung von OCR 
funktionieren.

Wenn ich den eigentlichen Zähl Code
1
  dec PulsCounter
2
  out led_port,PulsCounter

irgendwohin, also entweder in Count, die Programmschleife selbst (das 
Dekrementieren dann hinter den SBRC Befehl) oder in den Interrupt selbst 
packe funktioniert es auch nicht.
Die LED sind Low Aktiv.

Die überprüfung des Bits im TIFR Register hat der ING genauso in der 
Musterlösung, bei ihm soll es funktionieren (ebenfalls Mega128).

Weder der LaborING noch mein Laborpartner noch ich wissen was wirklih 
los ist ...


Findet jemand den Fehler? :-s


Grüße

PS: Es liegt nicht daran das der Interrupt Aktiviert und in der Tabelle 
steht. Die Globalen Interrupts sind deaktiviert und in einer Aufgabe 
vorher haben wir den gleichen Code (kann ich gern Posten) mit dem 8bit 
Timer und aktivierten Globalen Interrutps und da funktioniert alles ... 
das komplette entfernen der Sprungadresse + Unterprogramm halfen auch 
nicht.

PSS: Genau das selbe steht auch im Roboternetz Forum ;)

PSSS: Ich hoffe der Source Code ist nicht zu lang

PSSSS: Beitrag "Atmega128 16-bit Timer" Ich habe das mal 
überflogen, kann es sein das ich beim 16bit Timer wirklich TCNT1 bei 
jedem durchlauf neu auf 0 setzen muss? Beim 8bit Timer läuft das ja von 
selbst ...

von Werner B. (werner-b)


Lesenswert?

sei ?

von Ano N. (oorim)


Lesenswert?

sei aktiviert ja die Globalen interrupts und wir sollen das ganze per 
Polling Auswerten
1
  in      templ,TIFR
2
  SBRC    templ,4
3
  rcall    Count
4
  rjmp    Prog

von Uwe (Gast)


Lesenswert?

Hi!
Ich habe jetzt kein "128"ger Datenblatt, aber wenn ich lese:
>in Count in TC1int schreibe funktioniert alles Tadellos
würde ich jetzt mal vermuten du prüfst in:
> in      templ,TIFR
> SBRC    templ,4
ein falsches Bit. Schaue doch bitte mal genau ins Datenblatt.

Viel Erfolg, Uwe

von Ano N. (oorim)


Lesenswert?

Ich bin mal so frei:
Timsk:
1
• Bit 5 – TICIE1: Timer/Counter1, Input Capture Interrupt Enable
2
When this bit is written to one, and the I-flag in the Status Register is set (interrupts globally
3
enabled), the Timer/Counter1 Input Capture interrupt is enabled. The corresponding interrupt
4
vector (See “Interrupts” on page 60.) is executed when the ICF1 flag, located in TIFR, is set.
5
• Bit 4 – OCIE1A: Timer/Counter1, Output Compare A Match Interrupt Enable
6
When this bit is written to one, and the I-flag in the Status Register is set (interrupts globally
7
enabled), the Timer/Counter1 Output Compare A Match Interrupt is enabled. The corresponding
8
interrupt vector (see “Interrupts” on page 60) is executed when the OCF1A flag, located in TIFR,
9
is set.
10
• Bit 3 – OCIE1B: Timer/Counter1, Output Compare B Match Interrupt Enable
11
When this bit is written to one, and the I-flag in the Status Register is set (interrupts globally
12
enabled), the Timer/Counter1 Output Compare B Match Interrupt is enabled. The corresponding
13
interrupt vector (see “Interrupts” on page 60) is executed when the OCF1B flag, located in TIFR,
14
is set.
15
• Bit 2 – TOIE1: Timer/Counter1, Overflow Interrupt Enable
16
When this bit is written to one, and the I-flag in the Status Register is set (interrupts globally
17
enabled), the Timer/Counter1 overflow interrupt is enabled. The corresponding interrupt vector
18
(see “Interrupts” on page 60) is executed when the TOV1 flag, located in TIFR, is set.

TIFR:
1
• Bit 5 – ICF1: Timer/Counter1, Input Capture Flag
2
This flag is set when a capture event occurs on the ICP1 pin. When the Input Capture Register
3
(ICR1) is set by the WGMn3:0 to be used as the TOP value, the ICF1 flag is set when the
4
counter reaches the TOP value.
5
ICF1 is automatically cleared when the Input Capture Interrupt vector is executed. Alternatively,
6
ICF1 can be cleared by writing a logic one to its bit location.
7
• Bit 4 – OCF1A: Timer/Counter1, Output Compare A Match Flag
8
This flag is set in the timer clock cycle after the counter (TCNT1) value matches the Output
9
Compare Register A (OCR1A).
10
Note that a forced output compare (FOC1A) strobe will not set the OCF1A flag.
11
OCF1A is automatically cleared when the Output Compare Match A interrupt vector is executed.
12
Alternatively, OCF1A can be cleared by writing a logic one to its bit location.
13
• Bit 3 – OCF1B: Timer/Counter1, Output Compare B Match Flag
14
This flag is set in the timer clock cycle after the counter (TCNT1) value matches the Output
15
Compare Register B (OCR1B).
16
Note that a forced output compare (FOC1B) strobe will not set the OCF1B flag.
17
OCF1B is automatically cleared when the Output Compare Match B interrupt vector is executed.
18
Alternatively, OCF1B can be cleared by writing a logic one to its bit location.
19
• Bit 2 – TOV1: Timer/Counter1, Overflow Flag
20
The setting of this flag is dependent of the WGMn3:0 bits setting. In normal and CTC modes, the
21
TOV1 flag is set when the timer overflows. Refer to Table 61 on page 135 for the TOV1 flag
22
behavior when using another WGMn3:0 bit setting.


Ich meine also die richtigen gesetzt zu haben ... Deshalb mach ich das 
auch so umständlich mit den Bitmustern, da weis ich genau was passiert 
...

von Stefan E. (sternst)


Lesenswert?

Wenn du den Interrupt nicht benutzt, sondern das I-Bit pollst, dann 
musst du es "von Hand" wieder zurücksetzen. Das fehlt in deinem Code.

von Ano N. (oorim)


Lesenswert?

Es steht aber da, dass das Bit Automatisch gelöscht wird wurde es 
ausgelöst
1
OCF1A is automatically cleared when the Output Compare Match A interrupt vector is executed.
2
Alternatively, OCF1A can be cleared by writing a logic one to its bit location.

Es müsste ja wenigstens die LED dann aus gehen und nich ma das tut sie 
augen roll ich denke das Problem liegt in TIFR, wobei der  Herr 
Laboring ebenfalls das 4. Bit abfragt...

von Stefan E. (sternst)


Lesenswert?

Ano Nym wrote:
> Es steht aber da, dass das Bit Automatisch gelöscht wird wurde es
> ausgelöst

Da steht, dass es automatisch gelöscht wird, wenn der Interrupt 
ausgeführt wird. Das wird er bei dir aber nicht, also musst du es selber 
löschen.

> Es müsste ja wenigstens die LED dann aus gehen

Die geht im Augenblick so schnell aus, wieder an, wieder aus, wieder an, 
... , dass du es gar nicht siehst.

von Ano N. (oorim)


Lesenswert?

Aber ich frag das Interrupt Flag doch ab? Ich hab den "Compare-Mode" 
aktiviert und frage das "Compare"-Bit ab. Also führe ich den Interrupt 
doch aus, oder macht es einen unterschied ob ich in eine x-beliebige 
Routine mit der Interrupt Adresse springe oder nicht?

Ich werde es mir aber mal notieren und testen wenn ich wie der im Labor 
bin.


Oder kann es daran liegen das TCNT  zurückgesetzt werden muss?

von Stefan E. (sternst)


Lesenswert?

Ano Nym wrote:

> Also führe ich den Interrupt
> doch aus, oder macht es einen unterschied ob ich in eine x-beliebige
> Routine mit der Interrupt Adresse springe oder nicht?

Es macht natürlich einen großen Unterschied, ob du von Hand irgendwo 
hinspringst, oder ob der Prozessor automatisch in den Interrupt 
springt.

von Ano N. (oorim)


Lesenswert?

Das heist obwohl ich oben die Interrupt Tabelle habe, mit dem 
entsprechenden Interrupt, und ich das Interrupt aktiviert habe muss 
ich es Manuell Löschen? Beim 8-Bit Timer funktioniert das auch so ohne 
Probleme (Code Postbar)

von Stefan E. (sternst)


Lesenswert?

> Das heist obwohl ich oben die Interrupt Tabelle habe, mit dem
> entsprechenden Interrupt, und ich das Interrupt aktiviert habe muss
> ich es Manuell Löschen?

Herrgott, ist das denn wirklich so schwer?
Er springt nicht von alleine zur Interruptroutine, also löscht er auch 
das Bit nicht von alleine.

> Beim 8-Bit Timer funktioniert das auch so ohne
> Probleme (Code Postbar)

Sicher nicht.

von Ano N. (oorim)


Angehängte Dateien:

Lesenswert?

Keinen grund ungehalten zu werden. Verstanden habe ich es schon, ich 
wollte es nur bestätigt wissen.

Habe mal die 3. Aufgabe mit dem 8-Bit Timer angehangen das ohne Probleme 
funktioniert - auser ich hab einen gewaltigen denkfehler was sehr gut 
sein kann :)

von Stefan E. (sternst)


Lesenswert?

Ano Nym wrote:

> Habe mal die 3. Aufgabe mit dem 8-Bit Timer angehangen das ohne Probleme
> funktioniert

Da ist ja auch ein SEI drin!!!
Also komplett andere Situation.

von Stefan E. (sternst)


Lesenswert?

Und "ohne Probleme" funktioniert es sicher nicht, denn die Funktion 
Taster wird dort keinesfalls bei jedem Timer-Interrupt aufgerufen, 
sondern nur bei manchen (eher zufällig). Allerdings wohl immer noch oft 
genug, dass es nicht direkt auffällt.

von Peter D. (peda)


Lesenswert?

Ano Nym wrote:
> Ich meine also die richtigen gesetzt zu haben ... Deshalb mach ich das
> auch so umständlich mit den Bitmustern, da weis ich genau was passiert

Das ist in der Tat umständlich und man weiß eben nicht, was passiert!

Warum benutzt Du denn nicht die Bitnamen, dann weiß man, was passiert 
und der Code wird leserlicher.

Z.B. im Datenblatt ist das Bootloaderbeispiel mit Bitnamen:
1
; page erase
2
ldi spmcsrval, (1<<PGERS) | (1<<SPMEN)
3
call Do_spm
4
; re-enable the RWW section
5
ldi spmcsrval, (1<<RWWSRE) | (1<<SPMEN)


Ich habe jedenfalls keine Lust, die Bitmuster von Dir erstmal 
umständlich aufdröseln zu müssen.


Peter

von Ano N. (oorim)


Lesenswert?

Das Problem scheint wirklich an dem nicht zurücksetzen des Bits zu 
liegen - testen kann ich es erst am Donnerstag.
Über die Schreibweise
1
ldi spmcsrval, (1<<PGERS) | (1<<SPMEN)
habe ich mir noch keine Gedanken gemacht ehrlich gesagt. Macht aber 
durchaus mehr Sinn als das Bitmuster. Wobei ich das Datenblatt eh immer 
offen habe und bei einem
1
ldi TIFR, 0b00010000
Weis das eben das 4. Bit (von 0 ab gezählt) gesetzt ist und kann 
nachschlagen was es bedeutet - das nachschlagen entfällt oben natürlich. 
Find ich gut! Danke. Kann das jemand aufdröseln wie es Funktioniert? 
"<<" ist ja der Schiebeoperator der das Bit Rechts davon nach Links 
durch das Register schiebt, das hier ja eine 1 ist.


Ich weis das das alles ziemlich idiotisch und nervig rüber kommt. 
Problem an der ganzen Geschichte ist, dass wir uns alles selbst bei 
bringen und keinen blassen Schimmer von ASM haben, ich hab lediglich in 
der Theorie vor 3 Monaten mal ein bisschen was mit C gemacht - das hilft 
nur bedingt. Deshalb kommt diese 0-Ahnung... Leider. Ich wünschte es 
wäre anders ^^

von spess53 (Gast)


Lesenswert?

Hi

>  ldi      msTimer,0x99
>  out      OCR1AL,msTimer

>  ldi      templ,0
>  out      OCR1AH,templ

Datenblatt:

To do a 16-bit write, the high byte must be written before the low byte. 
For a 16-bit read, the low byte must be read before the high byte.

Schreib mal dein Programm um.

MfG Spess

von Ano N. (oorim)


Lesenswert?

Das hatten wir auch schon versucht was auch nichts geändert hat. Genauso 
wie ich schon sagte das wir
- das sei entfernt/hinzugefügt hatten
- Den Ansprung (Tabelle/Unterprogramm) entfernt/hinzugefügt hatten
Und da es mit dem Interrupt selbst geht gehe ich immer mehr davon aus 
das es einfach nur daran liegt das man das Bit händisch zurück setzen 
muss.


Edit: Ich möchte nicht das einer denkt das ich die Tips nicht aufnehme!! 
Ich nehme alles zur Notiz und denke darüber nach, viel mehr kann ich 
ohne µP nicht tun und da ich nur zwei mal die Woche ins Labor komme kann 
ich im moment nicht mehr sagen

von Falk B. (falk)


Lesenswert?

@ Ano Nym (oorim)

>Edit: Ich möchte nicht das einer denkt das ich die Tips nicht aufnehme!!
>Ich nehme alles zur Notiz und denke darüber nach, viel mehr kann ich
>ohne µP nicht tun

Dann kauf dir in Gottes Namen ein einfaches Evalboard bei Pollin und 
probiers praktisch aus.

Such mal auf

http://www.pollin.de

nach

Funk-AVR-Evaluations-Board

von spess53 (Gast)


Angehängte Dateien:

Lesenswert?

Hi

Habe mal dein Programm von oben getestet und etwas modifiziert. Im 
Simulator läuft es.

MfG Spess

von Ano N. (oorim)


Lesenswert?

spess53 wrote:
> Hi
>
> Habe mal dein Programm von oben getestet und etwas modifiziert. Im
> Simulator läuft es.
>
> MfG Spess


Im Simulator läuft bei mir nicht mal der Timer (zählt nicht hoch, beim 
OnChip Debugging tut sich da auch nichts)... warum weis ich auch noch 
nicht.

Falk Brunner wrote:
> @ Ano Nym (oorim)
>
>>Edit: Ich möchte nicht das einer denkt das ich die Tips nicht aufnehme!!
>>Ich nehme alles zur Notiz und denke darüber nach, viel mehr kann ich
>>ohne µP nicht tun
>
> Dann kauf dir in Gottes Namen ein einfaches Evalboard bei Pollin und
> probiers praktisch aus.
>
> Such mal auf
>
> http://www.pollin.de
>
> nach
>
> Funk-AVR-Evaluations-Board

Ich finde deine Antworten etwas patzig. Warum? Ich hab dir schlieslich 
nix getan ... Das Pollin Board fällt flach, ich hab weder RS232 noch 
Parallel zur Verfügung und ich warte eine JTAG Version von Embedded 
Projects ab.

von spess53 (Gast)


Lesenswert?

Hi

> ldi      akku,0b00001100  ; Timer auf CTC !!!!!!!!!!!!!!!!
> out      TCCR1B,akku      ; Übertrage auf Timer Counter Control Register

Dann gings. Bei 10MHz Simulator-Takt wird 'Count' ca. alle 4ms 
angesprungen. Allerdings ist ist mir jetzt auf die Schnelle auch nicht 
klar, warum der Timer im Normalmode nicht läuft. Werde mir das zu 
gegebener Zeit noch mal ansehen.

MfG Spess

von Falk B. (falk)


Lesenswert?

@ spess53 (Gast)

>angesprungen. Allerdings ist ist mir jetzt auf die Schnelle auch nicht
>klar, warum der Timer im Normalmode nicht läuft.

Möglicherweise ein Simulator-Bug?

MFg
Falk

von spess53 (Gast)


Lesenswert?

Hi

Gerade noch mal getestet. Läuft jetzt auch im Normalmode??????
Bei Timern hat der Simulator eigentlich nur bei PWM einige Probleme. 
Aber er braucht sowieso CTC. Sonst wird OCF1A nicht gesetzt.

MfG Spess

von Ano N. (oorim)


Lesenswert?

Okay vielen dank ich habs gerade gesehen und der Absatz
1
Clear Timer on
2
Compare Match (CTC)
3
Mode
4
In Clear Timer on Compare or CTC mode (WGMn3:0 = 4 or 12), the OCRnA or ICRn Register
5
are used to manipulate the counter resolution. In CTC mode the counter is cleared to zero when
6
the counter value (TCNTn) matches either the OCRnA (WGMn3:0 = 4) or the ICRn (WGMn3:0 =
7
12). The OCRnA or ICRn define the top value for the counter, hence also its resolution. This
8
mode allows greater control of the compare match output frequency. It also simplifies the operation
9
of counting external events.
10
The timing diagram for the CTC mode is shown in Figure 51. The counter value (TCNTn)
11
increases until a compare match occurs with either OCRnA or ICRn, and then counter (TCNTn)
12
is cleared.

macht ja klar das man dieses Bit auch braucht - das 4. Bit in TCCR1B 
muss also auch gesetzt werden.

Danke!

Mag mir noch jemand erklären wie die bessere Schreibweise des setzen der 
Einstellbits funktioniert? Kann ich damit dann auch direkt setzen oder 
muss ich auch den umweg über ein normales Register gehen?

Grüße

von Falk B. (falk)


Lesenswert?


von Ano N. (oorim)


Lesenswert?

Dankeschön!

von Spess53 (Gast)


Lesenswert?

Hi

>Mag mir noch jemand erklären wie die bessere Schreibweise des setzen der
>Einstellbits funktioniert? Kann ich damit dann auch direkt setzen oder
>muss ich auch den umweg über ein normales Register gehen?

Das hängt vom Register ab.

Wenn Adresse< $20($40):  sbi/cbi io_reg, bitnummer (0..7)

Wenn Adresse< $40($60)   ldi rxy,1<<bitnummer
                         out io_reg,rxy

Wenn Adresse>=$40($60)   ldi rxy,1<<bitnummer
                         sts io_reg,rxy

Siehe Datenblatt 'Register Summary' und 'Instruction Set'

MfG Spess

von Ano N. (oorim)


Lesenswert?

Vielen vielen dank auch hierfür. [ironie]Was man nicht alles lernen 
kann[/ironie]

Wir kriegen wirklich gar nichts beigebracht und um auf alles selbst zu 
kommen fehlt im moment einfach die Zeit :( Danke!

von Ano N. (oorim)


Lesenswert?

Antwort: Also kann ihc TIFR mit
1
sbi TIFR,(1<<OCF1A)|(1<<TOIE0)
(Beispiel)
setzen?

von spess53 (Gast)


Lesenswert?

Hi

>Antwort: Also kann ihc TIFR mit sbi TIFR,(1<<OCF1A)|(1<<TOIE0)

Nein. Für den Anfänger etwas verwirrend.

'sbi/cbi' gehen nur mit einem Bit (0..7)  sbi io_reg,5

'sbr/cbr' gehen mit allen Bits (0..255)   sbr reg, (1<<1)|(1<<2)....

MfG Spess

von Falk B. (falk)


Lesenswert?

@  Ano Nym (oorim)

>sbi TIFR,(1<<OCF1A)|(1<<TOIE0)

Geht nicht, weil SBI immer nur EIN EINZIGES Bit setzen kann, nicht 
mehrere.
Und ich weiss jetzt gar nicht, ob TIFR eine I/O Adresse kleiner als 0x1F 
hat. Dann geht SBI auch nicht.

MFG
Falk

von Ano N. (oorim)


Lesenswert?

Verflucht stimmt ja, SBI ist ja "Set Bit in IO Register" - also ein Bit. 
SBR habe ich in dem zusammenhang ignoriert gehabt weil das ja auf 
Normale Register zugreift (Wobei ich da auch nur "Set Bit in Register" 
im Kopf habe und das auhc nur ein einziges Bit setzen sollte nach meiner 
Logik)

1
$36 ($56) TIFR OCF2 TOV2 ICF1 OCF1A OCF1B TOV1 OCF0 TOV0 109, 141, 160

Spess53 wrote:
> Hi
>
>>Mag mir noch jemand erklären wie die bessere Schreibweise des setzen der
>>Einstellbits funktioniert? Kann ich damit dann auch direkt setzen oder
>>muss ich auch den umweg über ein normales Register gehen?
>
> Das hängt vom Register ab.
>
> Wenn Adresse< $20($40):  sbi/cbi io_reg, bitnummer (0..7)
>
> Wenn Adresse< $40($60)   ldi rxy,1<<bitnummer
>                          out io_reg,rxy
>
> Wenn Adresse>=$40($60)   ldi rxy,1<<bitnummer
>                          sts io_reg,rxy
>
> Siehe Datenblatt 'Register Summary' und 'Instruction Set'
>
> MfG Spess


TIFR hat wie oben geschrieben die Adresse $26($56) und ist damit 
<$40($60) (wenn richtig verstanden) und damit muss es dann über den LDI 
umweg gesetzt werden, Okay ich sehs ein.

Die Simulation läuft mit dem Timer übrigens wirklich, ich hab das mit 
JTAG durcheinander gewürfelt, da funktioniert der Timer irgendwie nicht. 
Weis nicht ob das normal ist oder nicht. Gibt es eigentlich eine bessere 
Möglichkeit einen Tastendruck zu Simulieren als über das anklicken des 
Entsprechenden Pins/Portbits?

von Ano N. (oorim)


Angehängte Dateien:

Lesenswert?

Hi

Ich nochmal, habe jetzt eine aktuelle Version angehängt. Der Timer 
braucht in der Simulation ewig, wenn ich ihn "verstell" (also OCR nach 
unten setze) spinnt alles komplett... Vielleicht hat einer eine Idee 
wieso. Das Programm zählt aber Binär hoch, was es tun soll. Langsam, 
aber sicher :D

von spess53 (Gast)


Angehängte Dateien:

Lesenswert?

Hi

Wieso geht das langsam? Wenn du bei 'Count:' einen Breakpoint setzt und 
'Run' drückst wird der nächste Zählerstand in Sekundenbruchteilen 
erreicht.
Ich habe dein Programm mal in eine lesbare Form gebracht und noch ein 
paar Bemerkungen gemacht.

MfG Spess

von Ano N. (oorim)


Lesenswert?

spess53 wrote:
> Hi
>
> Wieso geht das langsam? Wenn du bei 'Count:' einen Breakpoint setzt und
> 'Run' drückst wird der nächste Zählerstand in Sekundenbruchteilen
> erreicht.
> Ich habe dein Programm mal in eine lesbare Form gebracht und noch ein
> paar Bemerkungen gemacht.
>
> MfG Spess

Naja "lesbar" und "nicht lesbar" ist glaube ich eine sache des Anwenders 
- da ich C gewohnt bin hab ich mir das, für mich und meinen Kollegen, 
möglichst Strukturiert geschrieben. Ich komm damit ganz gut klar. Ändert 
sich aber im laufe der Zeit ständig und immer mehr in die richtung die 
du gepostet hast.

Auf die Idee mit dem Breakpoint bin ich nch nicht gekommen, muss ich mal 
testen danke. Den Simulator zu bedienen ist scheinbar eine ähnliche 
Kunst wie ASM selbst :D

von spess53 (Gast)


Lesenswert?

Hi

>Naja "lesbar" und "nicht lesbar" ist glaube ich eine sache des Anwenders
>- da ich C gewohnt bin hab ich mir das, für mich und meinen Kollegen,...

Meine ersten Programme habe ich auf dem Papier mit Befehlstabelle 
entwickelt und per Hextastatur in den 'Computer' eingetippt. Zu der Zeit 
sahen alle Assemlerlistings so aus. Da gewöhnt man sich halt dran. Und 
das Programm mit dem ich mir den Code für den Programmrumpf generiere 
habe ich mir halt auch so geschrieben.

>Auf die Idee mit dem Breakpoint bin ich nch nicht gekommen, muss ich mal
>testen danke. Den Simulator zu bedienen ist scheinbar eine ähnliche
>Kunst wie ASM selbst :D

Nö. Auch der Simulator hat eine Hilfe. Und Breakpoints sollte man als 
Programmierer eigentlich kennen. Oder testest du ein mehrere tausend 
Quelltextzeilen langes PC-Programm im Einzelschritt.

MfG Spess

P.S. Noch zwei Sachen:

1. Denke dran , das Leds meist invertiert angesteuert werden.

2. Wenn du schon bei deinem Stil bleiben willst, dann stell wenigstens 
die Tabweite im Editor auf 1. Dann sieht das Programm wenigstens in 
jedem Editor gleich aus.

von Ano N. (oorim)


Lesenswert?

Die LEDs sind invertiert angsteuert ja, deshalb läuft der Counter auch 
Rückwärts um Vorwärts zu zählen ;)

Breakpoints setze ich relativ selten. 1. Sind unsere Programme in 
C++/MatLab ("Fortran") und Assembler bisher nicht so groß und 2. laufen 
90% aller Programme im ersten rutsch so wie sie sollen, falls nicht ist 
dann meistens ein Verschreiber drin. Falls nicht setze ich natürlich 
breakpoints, aktiviere zwischen Ausgaben, bastel mit Fehler Handlings 
etc. Das ist klar.

Im Thema Software-Engineering sind wir noch ganz am Anfang.

Auf die Hilfe zum Simulator kam ich auch noch nich, sind immer die 
einfachen Dinge im Leben auf die man mal kommen muss ^^ Wieder was 
gelernt. Werde ich mir definitiv mal ansehen! Genauso die Tabbreite.


Die Befehlstabellen haben wir einmal kurz gesehen - mit dem Satz "so war 
das früher, ihr braucht das nicht, macht das in euerm Stil"... naja, 
lernen tun wir in der Vorlesung so oder so nichts. Wir sind 100% auf uns 
gestellt :(


Grüße



Rechtschreibfehler dürfen gefunden und behalten werde und dienen 
lediglich der belustigung des Lesers!

von spess53 (Gast)


Lesenswert?

Hi

>Die LEDs sind invertiert angsteuert ja, deshalb läuft der Counter auch
>Rückwärts um Vorwärts zu zählen ;)

Aber nicht mit 'inc PulsCounter'. Das Getödel könnt ihr euch sparen mit:

  com PulsCounter            ; invertieren
  out led_port,PulsCounter   ; ausgeben
  com PulsCounter            ; invertieren

Mit dem jetzigen Programm wird nicht gezählt: Bei 0 wird $FF geladen und 
danach incrementiert. Ergibt wieder 0. und das Spiel geht von vorn los.

MfG Spess

von Ano N. (oorim)


Lesenswert?

Ja gut ich habe das auf die weise Marke endlos basteln wollen

Zählt von 0 bis 255, geht wieder auf 0 und zählt wieder bis 255 usw.

Auf das invertieren wäre ich jetzt nicht gekommen...

1111 invertiert ergibt 0000
0000 invertiert ergibt 1111

Da zähl ich doch nicht hoch?

Wenn ich aber 0000 3 mal inkrementiere habe ich ja dann
0001
0010
0011

Und er zählt Binär hoch?


Edit: Incrementieren war hochzählen, Dekrementieren runterzählen, hab 
ichs wieder versaubeutelt  ... Peinlich

von spess53 (Gast)


Lesenswert?

Hi

>Da zähl ich doch nicht hoch?

Das hat nichts mit dem Zählen zu tun. nur mit der invertierten Ausgabe. 
Das 'inc' bleibt drin. Dafür kannst du dir

   breq CountExit
   ldiPulsCounter,0xFF

sparen.
Abgesehen kann das auch bei 'dec' entfallen, da

   dec (0) =$FF (auf Byteebene)

MfG Spess

von Ano N. (oorim)


Lesenswert?

Jep danke... Es sollte ja auch ohne das invertieren gehen wenn ichs 
einfach immer fröhlich DEkrementiere - da spare ich mir auch das 
Invertieren.

Grüßle und dankeschön


PS: Gibt es beispiele für Kompliziertere ASM Codes wie zB einen GPS 
Logger oder PID Regler? Ich hab mal gegooglet aber nichts gefunden und 
mich würde das mal interessieren wie da der ASM Code aussieht. Kann mir 
komplexere dinge nicht so recht vorstellen :/

von spess53 (Gast)


Lesenswert?

Hi

>Gibt es beispiele für Kompliziertere ASM Codes wie zB einen GPS...

Wenn du dich durchwühlen willst: Ich habe einen GPS mit Grafikdisplay 
und Anzeige von Position, Uhrzeit, Datum, Richtung, 
helligkeitsgesteuerter LCD-Beleuchtung ... und Anzeige eines 
Kartenausschnitts mit der Position mit einem ATMega128 in Assembler 
programmiert. Das PC-Programm um aus handelsüblichen Routenprogrammen 
verwertbare Kartendaten zu generieren hat länger als das 
Assemblerprogramm gedauert und mehr Nerven gekostet. Deshalb ist es bei 
einer ca.25x25km umfassenden Karte, die ich in den oberen 64k des Atmega 
untergebracht habe, geblieben.

MfG Spess

von Ano N. (oorim)


Lesenswert?

Eine Karte!? Auch noch nicht gesehen, das würde mich in der tat 
interessieren, auch wie es fertig aussieht.

von spess53 (Gast)


Lesenswert?

Hi

Müsste ich mal wieder hervorkramen.

MfG Spess

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.