Forum: Mikrocontroller und Digitale Elektronik Warum zählt mein Counter nicht?


von Grillparzer (Gast)


Lesenswert?

;Der Timer0 (8Bit) wird als Zähler verwendet
;Am Pin INTO PD2 werden die Impulse gezählt und an Port B ausgegeben
;In Entwicklung



.include "m8515def.inc"

.equ CountValue = 64000;
.def temp = r16
.def ZA   = r20


  rjmp Reset    ;Reset vector
  reti      ;Ext Int 0
  reti      ;Ext Int 1
  reti      ;Timer 1 Capture Event
  reti      ;Timer 1 Compare Match A
  reti      ;Timer 1 Compare Match B
  reti      ;Timer 1 Overflow
        reti              ;Timer 0 Overflow
  reti      ;Serial Transfer complet
  reti             ;USART, Rx Complete
  reti      ;USART, Dataregister Empty
  reti              ;USART, Tx Complete
  reti            ;Analog Compare
  reti      ;External Interrupt Request 2
  rjmp ComTimer ;Timer0 Compare Match
  reti      ;EEPROM ready
  reti       ;Store Programm Memory ready



Reset:
  ldi temp,LOW(RAMEND)      ;LOW-Byte der obersten RAM-
  out SPL, temp
  ldi  temp,HIGH(RAMEND)       ;HIGH-Byte der obersten RAM-
  out  SPH, temp

        ldi  temp,0xFF
  out  DDRB, temp              ;Datenrichtung von Port B

  ldi  temp,0xF0
  out  PORTB, temp              ;Datenrichtung von Port B



    ldi temp,0b00000000   ;
  out TCCR0,temp              ;Vorteiler = 1024

    ldi temp,0xFD                   ;Startwert des Timers einstellen:
  out TCNT0, temp

  ldi temp, 0b00001001        ;Bit 1 /Timer/Counter 0 Überlauf
        OUT TIMSK,temp


  sei


MainPro:

  rjmp MainPro



ComTimer:
  com temp          ;invertiert
  out PORTB, temp    ;Portausgabe

reti

von Alex (Gast)


Lesenswert?

Gib dem Controller mal noch an, welchen Prescaler er verwenden soll,
dann zählt er auch los.

Alex

von ...HanneS... (Gast)


Lesenswert?

Hi...

Du schreibst 0 in TCCR0, damit schaltest du Timer/Counter0 aus.
Für Vorteiler 1024 müsstest du 5 in TCCR0 schreiben.

Deinem anderen Thread entnahm ich aber, dass du externe Impulse zählen
wolltest. Dazu müsstest du die Impulse an T0 (PB0, Pin1) legen und den
Vorteiler auf externen Takt einstellen, also 6 oder 7 in TCCR0
schreiben. Das ist im Datenblatt auf Seite 91 beschrieben.

Bit- & Bytebruch...
...HanneS...

von Grillparzer (Gast)


Lesenswert?

Hallo zusammen

Danke für die Mühe.
Also ich habe den Pin T0 (PB0, Pin1) mit einen Switch auf dem STK500
Board verbunden.
Der 1024 Teiler war ein Fehler im Kommentar. Eigentlich wollte ich gar
keinen Teiler.

Nun steht bei:
SC02  SC01  SC00
1      1    1     für extermem Takt. Was ich auch möchte

Aber wenn ich keinen Teiler möchte steht:
0       0    1

Welches ist richtig beides geht nicht.

Gruss

Grillparzer

von ...HanneS (Gast)


Lesenswert?

Hi...

Eigentlich müsste ich mich jetzt heraushalten, denn du arbeitest mit
dem STK500 von dem ich keine Ahnung habe da ich keins habe. Ich benutze
die AVRs pur, also nur mit einem einfachen ISP-Interface. Es kann sein,
dass das STK noch einige Fallstricke hat, die ich daher nicht
berücksichtigen kann...

Auch sollten bei einem Hilfeersuchen die Kommentare halbwegs stimmen
und nicht in die Irre führen. Damit meine ich auch den Kommentar am
Anfang des Programms, INT0 ist garnicht beteiligt. Ohne die Diskussion
im anderen Thread hätte ich nicht nachvollziehen können, was du
eigentlich willst. - Sorry...

Aber:
CS2 CS1 CS0
 1   1   1   ist externer Takt, steigende Flanke,
 1   1   0   ist externer Takt, fallende Flanke,
 0   0   0   ist garnix, also deaktiviert,
 0   0   1   ist direkter Prozessortakt (also Vorteiler 1:1),
             nicht etwa "ohne" (also abgeschaltet)

Übrigens ist ein Taster als Impulsquelle an T0 äußerst ungeeignet, da
der Kontakt eines Tasters prellt. Das sollte schon ein prellfreier
elektronisch erzeugter Impuls sein.

Hast du das mal mit dem AVR-Studio simuliert? Da siehst du doch am
ehesten wo der Hase im Pfeffer liegt.

Bit- & Bytebruch...
...HanneS...

von Grillparzer (Gast)


Angehängte Dateien:

Lesenswert?

Hi Hannes

Also ich bin Anfänger und weiss nicht wie ich simulieren kann.

Als im Moment bin ich am Beispiel sammeln.

Ich will an diesem Eingang den Zähler raufzählen und wenn dann der
Overflow kommt den PORTB ausgang invertieren.

Ich habe jetzt eine Taktgeneratoro am Eingan angehängt.
Das STK500 müsste gehen bis jetz ist alles gelungen.

Ich habe nochmals den den Source angehängt.



Gruss

Grill parzer

von ...HanneS... (Gast)


Angehängte Dateien:

Lesenswert?

Hallo...

Du weißt nicht wie man simuliert... Dafür gibt es im AVR-Studio den
Button "Simulation". Nach dem Assemblieren ("BUILD") die Simulation
aufrufen, links das I/O-Fenster einblenden, die von dir benutzten I/Os
und Register anzeigen lassen und mittels Einzelschritt-Button das
Programm Schritt für Schritt abarbeiten, dabei den Programmablauf und
die Werte der Register und I/Os mit den von dir erwarteten
vergleichen.
Bei der Anzeige der I/Os siehst du auch, welche I/O-Register für welche
Funktionsgruppen zuständig sind.

Wenn deine Programme etwas größer werden, dann kannst du auch mit
Breakpoints arbeiten, das ist vorläufig aber noch nicht erforderlich.


Ich habe mir dein Programm mal angesehen und einige Kommentare
eingefügt. Korregiert habe ich es nicht, es ist nicht konkret zu
erkennen, was du eigentlich mit dem Programm bezweckst. Kommentare und
Programmcode widersprechen sich da etwas. Aber das siehst du ja an
meinen Kommentaren.

Tip: Schau dir erstmal einfache, funktionierende Programme im Simulator
von AVR-Studio an, damit du den Umgang mit dem Simulator üben kannst.

Gruß...
...HanneS...

von Grillparzer (Gast)


Lesenswert?

Hi Hannes

Danke mal. Ich muss das Morgen ausprobieren. Melde mich dann wieder

Grusss
Grillparzer

von ...HanneS... (Gast)


Angehängte Dateien:

Lesenswert?

Hi...

Ich habe dir mal ein ganz kleines Demo-Programm für Timer/Counter0 als
Ereigniszähler geschrieben, mit AVR-Studio simuliert (sorry, der Button
heißt nicht "Simulation" sondern "Debug") und getestet. Es
funktioniert im Simulator. Im Anhang findest du einen Screenshot des
AVR-Studios während der Simulation.

Links oben (Workspace) ist der I/O-Bereich geöffnet, davon nur die
Teile, die mich momentan interessieren, also PortD und Timer/Counter0.
Mausklick auf das rechte Bit von PinB setzt bzw. löscht den
Zähleingang. Bei jedem Setzen wird tcnt0 um 1 erhöht. Die restlichen
Bits von PortB zeigen den Zählerstand (nur 7 Bit) an.

Rechts oben siehst du das Programm und den Zeiger, welche Zeile gerade
abgearbeitet wird. Mit F11 geht es einen Schritt weiter.

Links unten (Output) stehen Meldungen des Systems, so auch
Fehlermeldungen.

Rechts unten lasse ich mir die Registerinhalte zeigen, soeben
veränderte Werte werden rot dargestellt. Hier wird mom nur r16
benutzt.

Und hier ist nun der Programmcode:
----- Schnipp -----
;Der Timer0 (8Bit) wird als Zähler verwendet
;Der Zähleingang von Timer/Counter0 ist PB0.
;Der Zählerstand wird an den restlichen Pins des PortB angezeigt.
;Dazu ist kein Interrupt erforderlich.
;In Entwicklung

.include "m8515def.inc"

;Registerdefinitionen
.def temp = r16

;Reset- & Interrupt-Vektoren
 rjmp Reset  ;Reset vector
 reti    ;Ext Int 0
 reti    ;Ext Int 1
 reti    ;Timer 1 Capture Event
 reti    ;Timer 1 Compare Match A
 reti    ;Timer 1 Compare Match B
 reti    ;Timer 1 Overflow
 reti    ;Timer 0 Overflow
 reti    ;Serial Transfer complet
 reti    ;USART, Rx Complete
 reti    ;USART, Dataregister Empty
 reti    ;USART, Tx Complete
 reti    ;Analog Compare
 reti    ;External Interrupt Request 2
 reti    ;Timer0 Compare Match
 reti    ;EEPROM ready
 reti    ;Store Programm Memory ready

Reset:
 ldi temp,LOW(RAMEND)      ;Stackpointer initialisieren...
 out SPL, temp        ;LOW-Byte der obersten RAM-Adresse
 ldi temp,HIGH(RAMEND)       ;HIGH-Byte der obersten RAM-Adresse
 out SPH, temp

 ldi temp,0xfe        ;PD0 als Eingang, PD1...PD7 ala Ausgang
 out DDRB, temp              ;Datenrichtung von Port B einstellen,

 ldi temp,0b00000111    ;Timer/Counter0 mit extrenem Takt an PB0 (T0)
triggern
 out TCCR0,temp

main:
 in temp,tcnt0        ;Timer0 einlesen
 lsl temp          ;Wert nach links schieben um PB0 nicht zu benutzen
 out portb,temp        ;Zählerstand (modulo128) an PortB ausgeben
 rjmp main          ;und nochmal...

----- Schnapp -----
Leider wird er durch die schmale Darstellung (Zeilenumbruch,
Tabulatoren) hier etwas verstümmelt, im Anhang ist aber schon das Bild,
deshalb hier im Text. Nach dem Kopieren in AVR-Studio dürfte der
Programmcode wieder korrekt angezeigt werden.

Viel Erfolg...
...HanneS...

von Grillparzer (Gast)


Lesenswert?

Hi Hannes

Mal danke für deine grossen Aufwand den du getrieben hast.
Also Simulieren kann ich das Programm im Simulator geht.
Die Hardware geht nicht. Ich muss mir jetzt Zeit nehmen und den Fehler
finden. Melde mich dann wieder.

Gruss

Grillparzer.

von Grillparzer (Gast)


Lesenswert?

Hi Hannes

Super es funktioniert.Danke.

Gruss

Grillparzer

von ...HanneS... (Gast)


Lesenswert?

Woran lag es denn nun, dass es zuerst nicht funktionierte?

...HanneS...

von Grillparzer (Gast)


Lesenswert?

Hallo Hannes

Am Signalgeber der lieft kein sauberes Signal.

Gruss

Grillparzer

von ...HanneS... (Gast)


Lesenswert?

Hi...

Tja, so ist das manchmal...

So, nun den nächsten Schritt:
INT0 als Eingang, in der ISR des Int0 ein Register (z.B. r15)
hochzählen und an PortB ausgeben. Ganz ohne Timer/Counter, dafür mit
einem Interrupt...

...HanneS...

von Grillparzer (Gast)


Lesenswert?

Hallo Hannes

Das möchte ich nicht machen. Vermutlich kann ich es schon
Den Interrupt auslösen ist mir gelungen und raufzählen kann ich auch
das ich dies für die Adressung des RAMs gebaut habe.

Ich habe noch einen neues Frage ist Forum gestllt. Vielleicht
interessiert sie dich?

Mit dem Uart senden möchte ich noch. mc -> PC

Vielleicht hast du ja scho einen code?

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.