Forum: Mikrocontroller und Digitale Elektronik Reaktionstester mit Atmel 4051


von Ramon S. (r_serrano)


Lesenswert?

Hallo zusammen!

Will einen Reaktionstester mit einen Atmel 4051 bauen! Habe die Platine 
auch schon fertig. Habe aber probleme mit der Assembler programmierung. 
Ich hoffe ihr koennt mir da weiterhelfen! :)

Die Ausgabe erfolgt auf 4 Sieben-Segment-Anzeigen. Desweiteren gibt es 
natuerlich einen Start, Stop und Reset Taster!

Taktgeber ist ein Quarz!
Der Taktgeber ist auf PIN "XTAL1" & "XTAL2".
Die 4 Sieben-Segment-Anzeigen haben folgende PIN-Belegung:
- Sekunden "P3.0"
- 1/10 Sekunde "P3.1"
- 1/100 Sekunde "P3.4"
- 1/1000 Sekunde "P3.5"
Die einzelnen Segmente der 7-Segment-Anzeigen von PIN "P1.1" bis "P1.7"
Der Start-Taster auf PIN "P3.2/INT0", der Stop-Taster auf "P3.3/INT1"
Reset natuerlich auf "RST"

Nach 9.999 Sekunden soll die Anzeige auf -.--- umspringen. Und nach dem 
man Reset gedrueckt hat auf 0.000 !

Wenn Ihr weitere Details braucht meldet euch

Ich habe mal ein wenig rumgebastelt (Habe auch Teile von einer Stoppuhr 
hineingebracht). Nun weiss ich nicht, in wie fern ich das Richtig 
gemacht habe. Wuerde mich ueber eure Beitraege sehr freuen! Vielen Dank 
im vorraus!

Ramon


Hier der Code:

$include (reg52.inc)

START-Taster    bit P0.0
STOP-Taster     bit P0.1
RESET-Taster    bit P0.2

org 0000h
  LJMP start


;Einsprungadresse Interrupt-Serviceroutine für Timer 0

org 000Bh
  LJMP isrTimer0


org 0100h
startabfrage:  JB Starttaster,start        ;Programm starten wenn Taster 
gedrückt
               LJMP startabfrage

start:  CALL initRegister
        CALL initTimer0

loop:      JB Resettaster,springer

springer:  LJMP initRegister

      LJMP loop       ;Endlosschleife



initRegister:
      MOV  R0,#0      ;bestimmt welche der Anzeigen aktiv ist
      MOV  R1,#0      ;Zähler von o bis 249 -->4ms*250 = 1 Sec

      MOV  R2,#0      ;Sekunden Einer
      MOV  R3,#0      ;Sekunden Zehner
      MOV  R4,#0      ;Sekunden Hundertstel
      MOV  R5,#0      ;Sekunden Tausendstel

      RET


initTimer0:

      SETB  ET0          ;Freigabe Timer0. Bit im Reg IE, Reg.-Adresse
A8h

      SETB   EA            ;Globale INT Freigabe. Bit im Reg IE

      MOV  TMOD,#00000001b  ;Timer0 konfiguieren, Modus1: 16bit Zaehler

      MOV  TL0,#060h      ;Timer0 vorladen

      MOV  TH0,#0F0h      ;65536 - 4000 = 61536 = F060h (4ms)

      SETB  TR0          ;Start Timer0

      RET

;Interrupt-Service-Routine für Timer0

isrTimer0:

      MOV  TL0,#060h      ;Timer0 erneut vorladen

      MOV  TH0,#0F0h      ;65536 - 4000 = 61536 = F060h (4ms)

      CALL  neueUhrzeit      ;neue Uhrzeit berechnen

      CALL  ausgabe        ;Ausgabe auf Anzeige

      RETI              ;Ende der Interrupt-Service-Routine




neueUhrzeit:

         INC R1           ;erhoehe Register 1
         CJNE R1,#250d,weiter   ;Springe nach weiter wenn der Inhalt von 
R1 ungleich 250d ist
         MOV  R1,#0d            ;Lade Register 1 mit dem Wert 0


         INC R2                 ;erhoehe Register 2
         CJNE R2,#10d,weiter    ;Springe nach weiter wenn der Inhalt von 
R2 ungleich 10d ist
         MOV R2,#0d             ;Lade Register 2 mit dem Wert 0

         INC R3                 ;erhoehe Register 3
         CJNE R3,#10d,weiter    ;Springe nach weiter wenn der Inhalt von 
R3 ungleich 10d ist
         MOV R3,#0d             ;Lade Register 3 mit dem Wert 0

         INC R4                 ;erhoehe Register 4
         CJNE R4,#10d,weiter    ;Springe nach weiter wenn der Inhalt von 
R4 ungleich 10d ist
         MOV R4,#0d             ;Lade Register 4 mit dem Wert 0

         INC R5                 ;erhoehe Register 5
         CJNE R5,#06d,weiter    ;Springe nach weiter wenn der Inhalt von 
R5 ungleich 10d ist
         MOV R5,#0d             ;Lade Register 5 mit dem Wert 0


         LJMP weiter            ;aufrufen von weiter

weiter:  RET                    ;Rücksprung aus dem Unterprogramm


ausgabe:  INC   R0
          CJNE  R0,#04,rechts
          MOV  R0,#0

sekunden:  CJNE  R0,#0,zehntel
           MOV  A,R4
           CALL  BCD7Seg
           MOV  P1,A
           MOV  P2,#00001110b

zehntel:    CJNE  R0,#1,hundertstel
            MOV  A,R5
            CALL  BCD7Seg
            MOV  P1,A
            MOV  P2,#00001101b

hundertstel:    CJNE  R0,#2,tausendstel
                MOV  A,R6
                CALL  BCD7Seg
                MOV  P1,A
                MOV  P2,#00001011b

tausendstel:  CJNE  R0,#3,return
              MOV  A,R7
              CALL  BCD7Seg
              MOV  P1,A
              MOV  P2,#00000111b

return:   RET



; Wandelt vom BCD-Code in den 7-Segment-Code

BCD7Seg:  INC  A
      MOVC  A,@A+PC
      RET
      DB  3Fh, 06h, 5Bh, 4Fh, 66h, 6Dh, 7Dh, 07h, 7Fh, 6Fh


END

von Stephan H. (stephan-)


Lesenswert?

@Ramon,
also eine Vorstellung und etwas Grundwissen sollte man schon haben 
dafür.
Einfach etwas zusammenkopieren bringt wenig und funzt äußerst selten.

1. mache Dir Gedanken über ein Grundtiming ( Wichtig )
  Was soll wann passieren....
  In der ISR berechnet man z.B.keine Zeit.
  Mann oder Frau incrmentiert, setzt ein Flag und gut.
  Das muß dann in der Main ausgewertet werden.
  zB. durch Abfrage auf Überläufe tec.

2. Dein Grundtiming sollte so gewählt sein das der Multiplextakt
   für die Anzeigen dabei "herausspringt"   ( zB. ein Vielfaches )

3. Das Grundtiming sollte auch die Tastenentperllung berücksichtigen
   10 bis 20 ms reichen dafür

Es reicht also nicht mit Copy und Paste zu "arbeiten".
Stell ein Grundgerüst auf die Beine ( PAP ). Poste es hier und dann 
gehts Schritt für Schritt weiter. Für jemanden der programmieren kann 
ist das ein Wochenendprojekt. Ich denke bei Dir wirds deutlich länger 
dauern.
Und ne Schaltung wäre ja auch nicht schlecht.
Damit progrmmiert es sich besser...

Gruß Stephan

von Peter D. (peda)


Lesenswert?

Stephan Henning wrote:

>   In der ISR berechnet man z.B.keine Zeit.
>   Mann oder Frau incrmentiert, setzt ein Flag und gut.
>   Das muß dann in der Main ausgewertet werden.

Kann man nicht so generell sagen.
Hier werden ja nur Bytes incrementiert und verglichen, sind also nur 
wenige Zyklen.

Was allerdings fehlschlägt, ist das "LJMP initRegister", gibt nen fetten 
Stack-Underflow. Wohin soll denn das "RET" hingehen ?

Und die Abfrage der Tasten finde ich nirgends.


Peter

von Stephan (Gast)


Lesenswert?

@Peter,

schrieb er doch, hat nur was von ner Stoppuhr gefunden und will damit 
was machen. Deswegen meinte ich ja Copy und Paste reicht dafür eben 
nicht.

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.