mikrocontroller.net

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


Autor: Ano Nym (oorim)
Datum:

Bewertung
0 lesenswert
nicht 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
  .nolist              ; include-file nicht in Listing
  .include  "m128def.inc"    ; Definitionen für ATmega 128 einbinden


  .list              ; Listing erstellen


  .def  akku    = r16    ; r16 als Rechenregister "akku" definieren
  .def  msTimer    = r23    ; r23 als Zeit-Einstellungsregister
      ; r24 als Zählregister
  .def  templ    = r17    ; Zwischenspeicher 1
  .def  temp2    = r18    ; Zwischenspeicher 2
  .def  PulsCounter  = r19
  .equ  key_pin    = PINA    ; Tasterpins
  .equ  key_port  = PORTA    ; Datenregister (Taster)
  .equ  key_ddr    = DDRA    ; Datenrichtungsregister (Taster)

  .equ  led_port  = PORTB    ; Datenregister (LED)
  .equ  led_pin    = PINB
  .equ  led_ddr    = DDRB    ; Datenrichtungsregister (LED)


  .cseg

;-------Adress Tabelle für Interrupt-Vektoren-----------------------------

  .org    0x0000        ; Interrupt-Vektor für RESET
  rjmp    Init
  
  .org    0x0002        ; Interrupt-Vektor für externen Interrupt 1
  rjmp    Extint1

  .org    0x0018        ; Interrupt-Vektor für Timer/Counter-0-Interrupt
  rjmp    TC1int

  .org    0x0045        ; Ende der Interrupt-Vektor-Tabelle

;-------Macros-------------------------------------------------------------
; Pin Toggeln
.macro TogPin
  SBIS    @0,@1        ; Wenn Bit (@1) in I/O-Reg. (@2) gesetzt, überspringe nächsten Befehl
  rjmp    SetPin
ClrPin:
  cbi      @0,@1
  rjmp    TogPinx
SetPin:
  SBI      @0,@1
TogPinx:
.endmacro
;--------------------------------------------------------------------------
  
Init:              ; Beginn des Hauptprogrammes

  ldi      r16,LOW(RAMEND)    ; Stack Initialisieren
  out      SPL,r16
  ldi      r16,HIGH(RAMEND)
  out      SPH,r16

  ser      akku        ; Alle Bits in Akku setzen
  out      DDRB,akku      ; PORTB als Ausgang (alle Bits 1)

  ldi      msTimer,0x99
  out      OCR1AL,msTimer

  ldi      templ,0
  out      OCR1AH,templ  

  ldi      templ,0x0
  out      TCNT1L,templ

  ldi      templ,0x0
  out      TCNT1H,templ

  ldi      akku,0b00011000
  out      TIMSK,akku

  ldi      akku,0b00000100
  out      TCCR1B,akku      ; Übertrage auf Timer Counter Control Register

  
  ldi      PulsCounter,255


  

Prog:
  
  in      templ,TIFR
  SBRC    templ,4
  rcall    Count
  rjmp    Prog


;-------Unterprogramme----------------------------------------------------
Extint1:              ; ISR für externen Interrupt 1

  reti

Count:
  TogPin    led_port,0

  ret

TC1int:                ; ISR für Timer/Counter 1 Interrupt  
  
  reti
.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
  dec PulsCounter
  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 ...

Autor: Werner B. (werner-b)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sei ?

Autor: Ano Nym (oorim)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sei aktiviert ja die Globalen interrupts und wir sollen das ganze per 
Polling Auswerten
  in      templ,TIFR
  SBRC    templ,4
  rcall    Count
  rjmp    Prog

Autor: Uwe (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Ano Nym (oorim)
Datum:

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

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

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Ano Nym (oorim)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es steht aber da, dass das Bit Automatisch gelöscht wird wurde es 
ausgelöst
OCF1A is automatically cleared when the Output Compare Match A interrupt vector is executed.
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...

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Ano Nym (oorim)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Ano Nym (oorim)
Datum:

Bewertung
0 lesenswert
nicht 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)

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Ano Nym (oorim)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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 :)

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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:
; page erase
ldi spmcsrval, (1<<PGERS) | (1<<SPMEN)
call Do_spm
; re-enable the RWW section
ldi spmcsrval, (1<<RWWSRE) | (1<<SPMEN)


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


Peter

Autor: Ano Nym (oorim)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Problem scheint wirklich an dem nicht zurücksetzen des Bits zu 
liegen - testen kann ich es erst am Donnerstag.
Über die Schreibweise
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
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 ^^

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Ano Nym (oorim)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: spess53 (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hi

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

MfG Spess

Autor: Ano Nym (oorim)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Ano Nym (oorim)
Datum:

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

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Ano Nym (oorim)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dankeschön!

Autor: Spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Ano Nym (oorim)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Ano Nym (oorim)
Datum:

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

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Ano Nym (oorim)
Datum:

Bewertung
0 lesenswert
nicht 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)

$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?

Autor: Ano Nym (oorim)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: spess53 (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Ano Nym (oorim)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Ano Nym (oorim)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Ano Nym (oorim)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Ano Nym (oorim)
Datum:

Bewertung
0 lesenswert
nicht 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 :/

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Ano Nym (oorim)
Datum:

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

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Müsste ich mal wieder hervorkramen.

MfG Spess

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.