Forum: Mikrocontroller und Digitale Elektronik atmega8 counter1 über T1 hochzählen


von a.big (Gast)


Lesenswert?

Hallo Leute,
ich versuche schon längere Zeit beim Atmega8 über den T1 Eingang (PD5) 
den Counter1 hochzuzählen.
Folgendes Programm habe ich über Assembler eingegeben;
.include"m8def.inc"

ldi  r16,0b00000110
out  tccr1b,r16
ldi  r16,0b00000000
out  tccr1a,r16
sei

loop:
nop
nop
rjmp loop

ich habe mit AVRStudio3.56 schon simuliert, funktioniert aber garnicht.
Muß ich noch irgendwas initialisieren.
Brauche dringend hilfe.
Danke
Gruß Andy

von Bernhard S. (bernhard)


Lesenswert?

Hallo Andy

; INITIALISIEREN External clock source on T1 pin. Clock on falling edge
  ldi temp,(1<<CS12)|(1<<CS11) |(0<<CS10)
  out TCCR1B,temp

; CLEAR
  clr temp
  out TCNT1H,temp
  out TCNT1L,temp

; TIMER ERGEBNIS einlesen
  in temp1,TCNT1L
  in temp2,TCNT1H



Weiter unten in diesem Thread findest Du eine Anwendung für höhere 
Frequenzen:

Beitrag "einfacher 5 MHz Frequenzzähler (Assembler) ATmega8"


Bernhard



PS:

Die Scheibweise "ldi r16,0b00000110" ist nicht so günstig

besser ist:

ldi temp,(1<<CS12)|(1<<CS11) |(0<<CS10)

sonst muss man erst im Datenblatt blättern und umständlich Nullen und 
Einsen abzählen.

von a.big (Gast)


Lesenswert?

Hallo,

mitlerweile habe ich was neues rausgefunden.
Kann es sein, dass die Pinbelegung im Atmega8 Datasheet falsch ist.
Wenn ich im Simulator für Counter0 den PIN PB0 zum externen zählen 
benutze,
und für Timer1 den PIN PB1 funktioniert es.
Im Datasheet steht PIN PD4 für Timer0 und PIN PD5 für Timer1.
Kann das jemand bestätigen?

Gruß Andy

von unsichtbarer WM-Rahul (Gast)


Lesenswert?

>|(0<<CS10)
Sowas soll angeblich die Lesbarkeit erhöhen. Finde ich aber nicht, 
sondern bewirkt eher das Gegenteil. (Einen anderen Sinn kann dieser 
Ausdruck nicht haben!) Sonst stimme ich Bernhard bzgl. der Schreibweise 
natürlich zu.

>Pinbelegung im Atmega8 Datasheet falsch ist
Das bezweifle ich doch sehr.

>AVRStudio3.56
Vielleicht mal auf 4.1x aktualisieren?! Das AVRStudio bzw. dessen 
Simulator ist nicht perfekt (es gibt da noch diverse Bugs drin).
Ich würde es eher in Hardware ausprobieren und mich auf das Datenblatt 
verlassen.

von johnny.m (Gast)


Lesenswert?

Ich vermute eher, der Fehler liegt bei Dir. PB0 und PB1 sind z.B. bei 
den 40-Pin-AVRs (ATMega16, 32 usw.) die Timer-Eingänge. Das sieht mir 
ganz danach aus, als hättest Du für die Simulation den falschen 
Controller ausgewählt.

von Bernhard S. (bernhard)


Lesenswert?

@unsichtbarer WM-Rahul

> |(0<<CS10)
> Sowas soll angeblich die Lesbarkeit erhöhen. Finde ich aber nicht,
> sondern bewirkt eher das Gegenteil.


statt "ldi r16,0b00000110"

besser so

ldi temp,(1<<CS12)|(1<<CS11)


Da gebe ich Dir natürlich Recht, aber bei manchen (mehrfach verwendeten) 
Registern würde ich diese "0" Schreibweise empfehlen, damit man nicht 
versehentlich ein Register doppelt be- bzw überschreibt.

Bsp MCUCR (Sleep/ext. Interrupt):

ldi temp, (0<<SE)|(1<<ISC01)
out MCUCR, temp

Bernhard




von unsichtbarer WM-Rahul (Gast)


Lesenswert?

>damit man nicht versehentlich ein Register doppelt be- bzw überschreibt.

Das muß ich im Zusammenhang mit
>ldi temp, (0<<SE)|(1<<ISC01)
>out MCUCR, temp

nicht verstehen, oder? In diesem Fall wird der Inhalt des MCUCR auf 
jeden Fall komplett überschrieben (soweit meine Assembler-Kenntnisse 
reichen).

Ich weiß jetzt nicht, wie die Anweisung in Assembler aussehen würde; in 
C sieht das so aus:

MCUCR | = (1<<ISC01);

Hier wird das MCUCR ausgelesen, mit (1<<ISC01) verodert und der Wert 
dann ins MCUCR zurückgeschrieben. Dadurch würde dann auch nur das 
ISC01-Bit gesetzt werden, und alle anderen so belassen, wie sie waren.

Ausserdem sollte man schon wissen, was man programmiert...

von Bernhard S. (bernhard)


Lesenswert?

>damit man nicht versehentlich ein Register doppelt be- bzw überschreibt.

>Das muß ich im Zusammenhang mit
>ldi temp, (0<<SE)|(1<<ISC01)
>out MCUCR, temp

>nicht verstehen, oder? In diesem Fall wird der Inhalt des MCUCR auf
>jeden Fall komplett überschrieben (soweit meine Assembler-Kenntnisse
>reichen).


Oh..., jetzt haben wir uns etwas verhaspelt.

Deutsches Spraches ist schweres Spraches.

Fallbeispiel: Es soll der SLEEP-MODUS und ein ext. Interrupt aktiviert 
werden (Assembler).


Richtig ist natürlich:

ldi temp, (1<<SE)|(1<<ISC01)
out MCUCR, temp


FALSCH:

ldi temp, (1<<SE)
out MCUCR, temp

ldi temp, (1<<ISC01)
out MCUCR, temp

Das könnte passieren, wenn im Laufe der Programmentwicklung bestimmte 
Register noch gesetzt werden müssen.

Würde nicht passieren, wenn von Anfang an die etwas komplzierteren 
Register komplett formuliert werden.

Bsp:
ldi temp, (x<<SE)|(x<<ISC11)|(x<<ISC10)|(x<<ISC01)|(x<<ISC00)

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.