0 Daumen
216 Aufrufe

Aufgabe: Stoppuhr in Assembly


Problem/Ansatz: Wieso funktioniert das nicht dass der je nach dem welche taste gedrückt wurde der  in dem zustand wechslet??


Ichhba de anderen unterfunktion ausgelassen die funktioenieren aber


;* Description       : This is a StopWatch
;
; lcdPrintC ist für R0 R1 und R2 nicht sicher (zeigt random Nummer an)
;***************************
; Define address of selected GPIO and Timer registers
PERIPH_BASE   equ 0x40000000                ;Peripheral base address
AHB1PERIPH_BASE equ (PERIPH_BASE + 0x00020000)
APB1PERIPH_BASE   equ PERIPH_BASE

GPIOD_BASE equ (AHB1PERIPH_BASE + 0x0C00)
GPIOF_BASE equ (AHB1PERIPH_BASE + 0x1400)
TIM2_BASE         equ (APB1PERIPH_BASE + 0x0000)

GPIO_F_PIN       equ (GPIOF_BASE + 0x10)
GPIO_D_PIN equ (GPIOD_BASE + 0x10)
GPIO_D_SET equ (GPIOD_BASE + 0x18)
GPIO_D_CLR equ (GPIOD_BASE + 0x1A)
TIMER equ (TIM2_BASE + 0x24)  ; CNT : current time stamp (32 bit), resolution
TIM2_PSC equ (TIM2_BASE + 0x28)  ; Prescaler resolution
TIM2_ERG equ (TIM2_BASE + 0x14)  ; 16 Bit register, Bit 0 : 1 Restart Timer
EXTERN initITSboard
  EXTERN GUI_init
EXTERN TP_Init
EXTERN initTimer
EXTERN lcdSetFont
EXTERN lcdGotoXY     ; TFT goto x y function
EXTERN lcdPrintS ; TFT output function
  EXTERN lcdPrintC           ; TFT output one character
EXTERN Delay ; Delay (ms) function
;****************
; Data section, aligned on 4-byte boundery
;****************
AREA MyData, DATA, align = 2
    GLOBAL text
DEFAULT_BRIGHTNESS DCW 800

text DCB "00:00:00",0
minuten DCD 6000000
sekunden DCD 100000
millisekunden DCW 100
;****************
; Code section, aligned on 8-byte boundery
;****************
AREA |.text|, CODE, READONLY, ALIGN = 3

;--------------------------------------------
; main subroutine
;--------------------------------------------
EXPORT main [CODE]
main PROC

; Initialisierung der HW
BL initITSboard
LDR r1, =DEFAULT_BRIGHTNESS
LDRH r0, [r1]
BL GUI_init ; Display einschalten
BL initTimer
LDR R1,=TIM2_PSC ; Set pre scaler such that 1 timer tick represents 10 us
MOV R0,#(90*10-1)
STRH R0,[R1]
LDR R1,=TIM2_ERG ; Restart timer
MOV R0,#0x01
STRH R0,[R1] ; Set UG Bit
MOV R0, #24
BL lcdSetFont

superloop

ansteuern_tasten
PUSH {R0-R1,LR}
LDR R0,=GPIO_F_PIN ; Adresse der Unterfunktion in R0 laden
LDRH R0, [R0] ; Lade Halbwort in R0
AND R0, R0, #0xFF ; Mithilfe von AND ermittelt welche Taste gedrückt ist
if_1
  ; Prüfe, ob S5 (Bit 5) gedrückt ist
  AND   R1, R0, #2_11011111          ; Maske für Bit 5 (S5)
  CMP   R1, #2_11011111                        ; Vergleiche mit 0
  BNE   else_if                     ; Springe, wenn S5 nicht gedrückt
  BL     INIT                         ; Springe zu INIT, wenn S5 gedrückt

else_if
  ; Prüfe, ob S6 (Bit 6) gedrückt ist
  AND   R1, R0, #2_10111111          ; Maske für Bit 6 (S6)
  CMP   R1, #2_10111111                        ; Vergleiche mit 0
  BNE   else_if_2                    ; Springe, wenn S6 nicht gedrückt
  BL     HOLD                         ; Springe zu HOLD, wenn S6 gedrückt

else_if_2
  ; Prüfe, ob S7 (Bit 7) gedrückt ist
  AND   R1, R0, #2_01111111          ; Maske für Bit 7 (S7)
  CMP   R1, #2_01111111              ; Vergleiche mit 0
  BNE   superloop                   ; Springe, wenn S7 nicht gedrückt
  BL     RUNNING                     ; Springe zu RUNNING, wenn S7 gedrückt



POP {R0-R1, LR}
B superloop

;********************
;-------------Unterprogramme--------------------------------*
;********************

INIT

PUSH {R0-R1,LR}
BL ausschalten_led
BL zeit_auf_0_setzen
POP {R0-R1,LR}

BX LR
RUNNING

PUSH {R0-R1,LR}
MOV R7, #1
BL einschalten_led
BL timer_starten
POP {R0-R1,LR}

BX LR

HOLD

PUSH {R0-R1,LR}
MOV R7, #2
BL einschalten_led
POP {R0-R1,LR}

BX LR



;******************
;------------------Init Zustand-----------------------*
;******************

zeit_auf_0_setzen
PUSH   {R0-R3, LR}        ; Register sichern

  MOV   R0, #10            ; X-Position auf dem Display
  MOV   R1, #7            ; Y-Position auf dem Display
  BL     lcdGotoXY         ; Cursor setzen

  LDR   R0, =text ; Zeichenkette mit der Zeit "00:00:00"
LDR R1, [R0]
  BL     lcdPrintS   ; Zeichenkette auf dem Display ausgeben

  POP   {R0-R3, LR}        ; Register wiederherstellen
  BX     LR               ; Rückkehr


;+++++++++++++++++++++++++++++++++++++++++++++++;
;-----------------halt_zeit---------------------;

halt_zeit
  LDR   R0, =TIMER   ; Adresse des Timer-Steuerungsregisters laden
  LDR   R1, [R0]          ; Aktuellen Wert des Steuerungsregisters laden
  BIC   R1, R1, #1        ; Timer deaktivieren (entsprechendes Bit auf 0 setzen)
  STR   R1, [R0]          ; Geänderten Wert zurückschreiben

  BX     LR               ; Rückkehr

Avatar von

1 Antwort

0 Daumen

Der Hauptgrund, warum die Zustandswechsel nicht funktionieren, liegt in der fehlerhaften Abfrage der Tasten. Die verwendeten Masken und Vergleiche sind inkorrekt. Hier ist die Schritt-für-Schritt-Erklärung und Korrektur:

Problemanalyse:

Die Tastenabfrage verwendet AND mit einer Maske, die das jeweilige Bit löscht, und vergleicht dann mit der Maske. Dies setzt voraus, dass alle anderen Bits 1 sind, was nicht der Fall sein muss.
Die korrekte Methode ist, das jeweilige Bit direkt zu testen (mit TST) und auf 0 zu prüfen (da Tasten aktiv-low sind: gedrückt = 0).
Korrektur des Codes:

S5 (Bit 5) Abfrage ersetzen:

; Vorher
AND R1, R0, #0xDF
CMP R1, #0xDF
BNE else_if

Nachher:

TST R0, #(1 << 5)      ; Teste Bit 5
BEQ INIT               ; Wenn 0 (gedrückt), springe zu INIT

S6 (Bit 6) Abfrage ersetzen:

; Vorher
AND R1, R0, #0xBF
CMP R1, #0xBF
BNE else_if_2

Nachher:

TST R0, #(1 << 6)      ; Teste Bit 6
BEQ HOLD               ; Wenn 0 (gedrückt), springe zu HOLD

S7 (Bit 7) Abfrage ersetzen:

; Vorher
AND R1, R0, #0x7F
CMP R1, #0x7F
BNE superloop

Nachher:

TST R0, #(1 << 7)      ; Teste Bit 7
BEQ RUNNING           ; Wenn 0 (gedrückt), springe zu RUNNING

Korrigierter Codeabschnitt:

ansteuern_tasten
  PUSH {R0-R1, LR}
  LDR R0, =GPIO_F_PIN   ; GPIOF input address
  LDRH R0, [R0]          ; Lade Tastenzustand
  AND R0, R0, #0xFF     ; Isoliere die unteren 8 Bits

  ; Prüfe S5 (Bit 5)
  TST R0, #(1 << 5)      ; Teste Bit 5
  BEQ INIT               ; Wenn gedrückt (0), INIT

  ; Prüfe S6 (Bit 6 TST R0, #(1 << 6)      ; Teste Bit 6
  BEQ HOLD               ; Wenn gedrückt (0), HOLD

  ; Prüfe S7 (Bit 7)
  TST R0, #(1 << 7)      ; Teste Bit 7
  BEQ RUNNING             ; Wenn gedrückt (0), RUNNING

  POP {R0-R1, LR}
  B superloop             ; Zurück zur Hauptschleife

Mit diesen Änderungen wird die Logik zur Erkennung der Tastenanschläge korrekt implementiert, sodass die Zustandswechsel wie gewünscht funktionieren sollten. Achte darauf, dass die GPIO-Pins richtig konfiguriert sind und dass eventuell eine Entprellung der Tasten implementiert wird, um unerwünschte Mehrfachauslösungen zu vermeiden.

Avatar von

Ein anderes Problem?

Stell deine Frage

Willkommen bei der Stacklounge! Stell deine Frage einfach und kostenlos

x
Made by a lovely community