www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Problem mit 16-bit Timer/Counter


Autor: Flo333 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi!

Ich hab folgende Problem:

Ich möchte das an Pin T0 (entspricht PD4) anliegende Rechtecksignal 
zählen. Nach 1000 Impulsen soll PortB "High" geschaltet werden. Dazu hab 
ich den Timer/Counter1 (16-bit) meines 2313 verwendet. Leider 
funktioniert es nicht, PortB bleibt immer auf "Low". Ich vermute das der 
Fehler irgendwo bei der Einrichtung des 16-bit Counters liegt. Hab aber 
bis jetzt noch nichts gefunden.

Wäre total super wenn mir einer von euch weiterhelfen könnte.

Schon mal im Voraus Danke!

MfG Flo


.include "2313def.inc"
.def temp = r16
.equ start = 65536 - 1000
.equ highValue = high(start)
.equ lowValue = low(start)

rjmp reset      ;Reset Handler
reti    ;IRQ0 Handler
reti    ;IRQ1 Handler
reti          ;Timer1 Capture Handler
reti          ;Timer1 Compare Handler
rjmp counter1   ;Timer1 Overflow Handler
reti          ;Timer0 Overflow Handler
reti          ;SPI Transfer Complete Handler
reti          ;UART RX Complete Handler : RXCIE
reti          ;UDR Empty Handler
reti    ;UART TX Complete Handler
reti    ;ADC Conversion Complete Interrupt Handler
reti    ;EEPROM Ready Handler
reti          ;Analog Comparator Handler


reset:

ldi temp, low(RAMEND)  ;set stackpointer
out SPL, temp

ldi temp, 0x00
out DDRD, temp    ;PORTD input
ldi temp, 0xFF
out DDRB, temp    ;PORTB output

ldi temp, 1<<TOIE1   ;1000 0000
out TIMSK, temp          ;timer1 interrupt on
ldi temp, highValue  ;Startwert des Counters Highbyte
out TCNT1H, temp
ldi temp, lowValue
out TCNT1L, temp        ;Startwert des Counters Lowbyte

ldi temp, 0b00000111
out TCCR0, temp    ;Counter +1 bei fallender Flanke an Pin T0

sei      ;interrupts aktiv

main:

  loop:

  rjmp loop


;--------------------------------------------------------------

counter1:

ldi temp, 0xFF
out PORTB, temp

ldi r17, 0
ldi r18, 0
ldi r19, 35

delay:
dec r17
brne delay
dec r18
brne delay
dec r19
brne delay

ldi temp, 0x00
out PORTB, temp

ldi temp, highValue  ;Startwert des Counters Highbyte neu
out TCNT1H, temp
ldi temp, lowValue
out TCNT1L, temp        ;Startwert des Counters Lowbyte neu

reti

Autor: thkaiser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du wirfst Timer0 und Timer1 durcheinander. Wenn Du Dich für einen von 
beiden entscheidest, könnte es funktionieren ;-)
Du zählst Impulse an T0, das ist der Eingang des Timer0. Allerdings die 
Interrupt-Routine ist für Timer1.

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
out TCCR0, temp ;Counter +1 bei fallender Flanke an Pin T0

da wird der Fehler liegen, sollte wohl heißen:
out TCCR1B, temp

Ansonsten kann ich nur sagen, das Programm ist ein Graus, verzeihen 
könnte ich dir das nur, wenn du Anfänger bist und dir noch keiner was 
beigebracht hat.

folgende grobe Fehler:
1. das sreg sollte in einer ISR immer gesichert werden, das sollte in 
Fleisch und Blut übergehen
2. delays dieser Größenordnung haben in Unterruptprogrammen nichts zu 
suchen
3. Wenn du wirklich korrekt zählen willst, sollte das TCNT1-Register als 
erstes in der ISR nachgeladen werden.
4. Register sollten schon Namen bekommen, lange Fehlersuche ist sonst 
bei etwas komplexeren Programmen vorprogrammiert
5. wenn Register nicht ausdrücklich nur für eine ISR reserviert sind, 
auf dem Stack sichern. Programme wachsen im Lauf der Zeit, solche 
(erstmal funktionierenden) Nachlässigkeiten rächen sich später.

Autor: Flo333 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Morgen!

Danke für die Antworten!

Werds dann gleich mal so ausprobieren.

@ crazy horse

ja ich bin leider noch ziemlicher Anfänger

1. das sreg sollte in einer ISR immer gesichert werden, das sollte in 
Fleisch und Blut übergehen
---> Danke für den Tip, wusste ich nicht
2. delays dieser Größenordnung haben in Unterruptprogrammen nichts zu 
suchen
---> Das war nur zum Test, sonst seh ich an meinen LED´s ja nichts
3. Wenn du wirklich korrekt zählen willst, sollte das TCNT1-Register als 
erstes in der ISR nachgeladen werden.
---> Nochmals Danke, ist ja eigentlich auch logisch
4. Register sollten schon Namen bekommen, lange Fehlersuche ist sonst 
bei etwas komplexeren Programmen vorprogrammiert
---> wie gesagt, die Delay war nur kurz zusammengeschustert
5. wenn Register nicht ausdrücklich nur für eine ISR reserviert sind, 
auf dem Stack sichern. Programme wachsen im Lauf der Zeit, solche 
(erstmal funktionierenden) Nachlässigkeiten rächen sich später.
---> Werds mir merken!

MfG

Flo

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
counter1:
in sreg_bak, sreg
push temp
ldi temp, highValue ;Startwert des Counters Highbyte neu
out TCNT1H, temp
ldi temp, lowValue
out TCNT1L, temp ;Startwert des Counters Lowbyte neu
set      ;T=1
bld flags, t1_ready
pop temp
out  sreg, sreg_bak
reti

für das Register sreg_bak benutzt ich i.a. R1, wenn du keine Interrupts 
verschachtelst, kannst du das Register für verschiedene ISR benutzen
.def sreg_bak R1
.def flags R2
.equ t1_ready=0 ;bit0 von R2

Im Hauptprogramm kannst du dann den Zustand von t1_rady abfragen, ist es 
gesetzt, werden die entsprechenden Aktionen ausgeführt (Port setzen, 
delay, Port rücksetzen.
Es spielt zwar in deinem Programm keine Rolle, wird aber in komplexeren 
Programmen wichtig.
also:
- sreg sichern
- alle benutzten Register sichern
- ISR-Laufzeit kurz wie möglich halten
Das ist natürlich kein unumstößliches Muss, wenn mans beherrscht oder 
besondere Umstände es erfordern, kann man davon abweichen, aber als 
Grundregel ist es nicht schlecht.

Man kann das sreg auch auf dem Stack sichern:
push temp
in temp, sreg
push temp
.
pop temp
out sreg, temp
pop temp
reti
Das empfiehlt sich bei verschachtelten ISRs (die fast immer vermeidbar 
sind)

Autor: Flo333 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich bin´s nochmal!

Leider funktioniert das Programm immer noch nicht!

Hab das "TCCRO, temp" gegen "TCCR1B, temp" ausgetauscht.

Hat jemand vielleicht irgendein Beispielprogramm zum 16-Bit Timer / 
Counter?

MfG

Flo

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tja, und nun solltest du deine Impulse auch an den T1-EIngang legen 
(PD5), willst ja mit dem Timer1 zählen.

Autor: Flo333 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ganz dumm bin ich auch nicht! :-)

Das hab ich gemacht, funktioniert aber trotzdem nicht. :-(

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.