Forum: Mikrocontroller und Digitale Elektronik Assembler PIC auswertiung


von rotermexico (Gast)


Angehängte Dateien:

Lesenswert?

Assembler kann ich leider nicht ... und jetzt suche ich jemand der mir 
weiterhelfen kann bei einem programm für ein PIC12F629. Ich hätte gerne 
der autor gefragt aber da das von 2004 ist gibts da keine antwort...

Ich habe leider keine verschiedenen anschlüsse zu verfügung sondern nur 
eine spannung .. ein einzelner impuls und ein doppelimpuls. also 
"schloßauf" ein spannungsimpuls und "schloßzu" 2 pulse nacheinander... 
Kann man das ändern das der PIC auf die anzahl der pulse reagiert ??

 -=[ Lock-Flash ]=-    V1.20    23.04.2004
;
;   (C) by CoolChip
;
;**************************************************************
;
; Taktfrequenz: Interne 4 MHz
;
; Pinbelegung
; ----------------------------------
;  GPIO:  0  OUT    Blinker Links
;         1  OUT    Blinker Rechts
;         2  IN    Schloss Auf
;         3  IN    Schloss Zu
;         4  IN    Jumper B
;         5  IN    Jumper A
;
;**************************************************************
; Befehle für COMPILER oder BURNER
;
  processor 12f629
  #include <P12f629.INC>

  ERRORLEVEL    -302    ;SUPPRESS BANK SELECTION MESSAGES
;
; Boden off, Code Protection off, Data Protectioon off, Power-on-Timer 
off,
; Watchdog off, Master Cear off, Interner-Oscillator
;
  __CONFIG  _BODEN_OFF & _CP_OFF & _PWRTE_OFF & _WDT_OFF & _MCLRE_OFF & 
_INTRC_OSC_NOCLKOUT

;
;**************************************************************
; Variablen festlegen  20h ... 5Fh
;
xflags      equ    0x20      ; Platz für zusätzliche Flags
W_save      equ    0x21            ; Backup für Akku
Status_save    equ    0x22      ; Backup für Status-Bits

loops      equ    0x25      ; Zähler für Warteschleife
loops2      equ    0x26      ; Zähler für untere Warteschleife

; Flag bits (FLAGS)
;
#define close_akt  xflags, 0      ; Öffen-Aktion
#define open_akt  xflags, 1      ; Schließ-Aktion

#define links    GPIO, 0
#define rechts    GPIO, 1
#define open    GPIO, 2
#define close    GPIO, 3
#define jmpB    GPIO, 4
#define jmpA    GPIO, 5
;
;***********************************************************************
; Sprung zum Programmanfang
    org    0x0000
    goto  init
;
;***********************************************************************
; Interruptroutine
    org    0x0004

    movwf  W_save                  ; erstmal Backup machen
    swapf  STATUS, W
    bcf    STATUS, RP0             ; Bank0
    movwf  Status_save

    bcf    INTCON, GIE        ; Interupt generell verbieten
    bcf    links
    bcf    rechts
    call  pause50          ; Pause wegen Prellen
    btfsc  open          ; aufschließen?
    goto  react          ; Jo
    btfss  close          ; zuschließen?
    goto  intFail          ; Nö

react
    btfsc  open
    bsf    open_akt
    btfsc  open
    bcf    close_akt

    btfsc  close
    bsf    close_akt
    btfsc  close
    bcf    open_akt

waitforend
    btfsc  open          ; aufschließen?
    goto  waitforend        ; Jo
    btfsc  close          ; zuschließen?
    goto  waitforend        ; Jo

intEnde
    swapf  Status_save, w
    movwf  STATUS
    swapf  W_save,f
    swapf  W_save,w
    bcf    INTCON, GPIF        ; GPIO-Interrupt löschen
    bsf    INTCON, GIE          ; Interupt generell erlauben
    goto  main

intFail
    swapf  Status_save, w
    movwf  STATUS
    swapf  W_save,f
    swapf  W_save,w
    bcf    INTCON, GPIF      ; GPIO-Interrupt löschen
    bsf    INTCON, GIE        ; Interupt generell erlauben
    retfie
;
;**************************************************************
; Initialisierung
;
init

; interner Taktgenerator
  bsf    STATUS, RP0          ; Bank 1
  call  0x3FF
  movwf  OSCCAL            ; 4-MHz-Kalibrierung
  bcf    STATUS, RP0          ; Bank 0

; 12F629 alle Comparatoreingänge auf Digital umschalten
; alles in der Bank 0
  bsf   CMCON, CM0
  bsf   CMCON, CM1
  bsf   CMCON, CM2

; ** Ports vorbereiten **
  bsf    STATUS, RP0          ; Bank 1
  movlw  b'111100'          ; 0 = Output - 1 = Input
  movwf  TRISIO
  bcf    STATUS, RP0          ; Bank0

; GPIO-Interrupt einstellen
  bsf    INTCON, GPIE        ; GPIO-Interupt erlauben
  bsf    STATUS, RP0          ; Bank 1
  movlw  b'001100'          ; 0 = NoInt - 1 = Interupt erlauben
  movwf  IOC
  bcf    STATUS, RP0          ; Bank 0
  bcf    INTCON, GPIF        ; GPIO-Interrupt löschen
  bsf    INTCON, GIE          ; Interupt generell erlauben

; ** Register/Flags löschen **
;
  clrf  xflags            ; 'xflags' löschen
  clrf  GPIO

; ** ENDE der Initalisierung **
; Signal
  bsf    links
  bsf    rechts
  call  pause100

  bcf    links
  bcf    rechts
  call  pause250

  bsf    links
  bsf    rechts
  call  pause100

  bcf    links
  bcf    rechts
  call  pause250
;
;**********************************************************
; Hauptprogrammschleife
;
main
  btfsc  open_akt        ; aufschließen?
  goto  blink_auf        ; Jo
  btfsc  close_akt        ; zuschließen?
  goto  blink_zu        ; Jo

  goto  main
;
;**********************************************************
; Blink-Programm beim Öffnen
;
; Signal gedreht über Jumper A?
blink_auf
  btfsc  jmpA
  goto  blink_zu_go

; BigFlash oder Normal? (Jumper B)
blink_auf_go
  btfss  jmpB
  goto  bigflash_open

; Normales Standart-Blinken
normal_open
  bsf    links
  bsf    rechts
  call  pause150

  bcf    links
  bcf    rechts
  call  pause250

  bsf    links
  bsf    rechts
  call  pause150

  bcf    links
  bcf    rechts
  call  pause250

  clrf  xflags            ; 'xflags' löschen
  goto  main

; BigFlash
bigflash_open
  bsf    links
  call  pause50
  bcf    links
  call  pause10
  bsf    rechts
  call  pause50
  bcf    rechts
  call  pause10

  bsf    links
  call  pause50
  bcf    links
  call  pause10
  bsf    rechts
  call  pause50
  bcf    rechts
  call  pause10

  bsf    links
  call  pause50
  bcf    links
  call  pause25
  bsf    rechts
  call  pause50
  bcf    rechts
  call  pause25

  bsf    links
  call  pause50
  bcf    links
  call  pause25
  bsf    rechts
  call  pause50
  bcf    rechts
  call  pause25

  bsf    links
  call  pause50
  bcf    links
  call  pause50
  bsf    rechts
  call  pause50
  bcf    rechts
  call  pause50

  bsf    links
  call  pause50
  bcf    links
  call  pause50
  bsf    rechts
  call  pause50
  bcf    rechts
  call  pause50

  bsf    links
  call  pause50
  bcf    links
  call  pause75
  bsf    rechts
  call  pause50
  bcf    rechts
  call  pause75

  bsf    links
  call  pause50
  bcf    links
  call  pause75
  bsf    rechts
  call  pause50
  bcf    rechts
  call  pause75

  bsf    links
  call  pause50
  bcf    links
  call  pause100
  bsf    rechts
  call  pause50
  bcf    rechts
  call  pause100

  bsf    links
  call  pause50
  bcf    links
  call  pause125
  bsf    rechts
  call  pause50
  bcf    rechts
  call  pause125

  bsf    links
  call  pause50
  bcf    links
  call  pause150
  bsf    rechts
  call  pause50
  bcf    rechts
  call  pause150

  bsf    links
  call  pause50
  bcf    links
  call  pause175
  bsf    rechts
  call  pause50
  bcf    rechts
  call  pause175

  bsf    links
  call  pause50
  bcf    links
  call  pause200
  bsf    rechts
  call  pause50
  bcf    rechts
  call  pause200

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

  call  pause250
  call  pause250
  bsf    links
  bsf    rechts
  call  pause150
  bcf    links
  bcf    rechts

  call  pause250
  bsf    links
  bsf    rechts
  call  pause250
  call  pause250
  bcf    links
  bcf    rechts

  clrf  xflags            ; 'xflags' löschen
  goto  main
;
;**********************************************************
; Blink-Programm beim Schließen
;
; Signal gedreht über Jumper A?
blink_zu
  btfsc  jmpA
  goto  blink_auf_go

; BigFlash oder Normal? (Jumper B)
blink_zu_go
  btfss  jmpB
  goto  bigflash_close

; Normales Standart-Blinken
normal_close
  bsf    links
  bsf    rechts
  call  pause150

  bcf    links
  bcf    rechts
  call  pause250

  clrf  xflags            ; 'xflags' löschen
  goto  main

; BigFlash
bigflash_close
  bsf    links
  call  pause50
  bcf    links
  call  pause200
  bsf    rechts
  call  pause50
  bcf    rechts
  call  pause200

  bsf    links
  call  pause50
  bcf    links
  call  pause175
  bsf    rechts
  call  pause50
  bcf    rechts
  call  pause175

  bsf    links
  call  pause50
  bcf    links
  call  pause150
  bsf    rechts
  call  pause50
  bcf    rechts
  call  pause150

  bsf    links
  call  pause50
  bcf    links
  call  pause125
  bsf    rechts
  call  pause50
  bcf    rechts
  call  pause125

  bsf    links
  call  pause50
  bcf    links
  call  pause100
  bsf    rechts
  call  pause50
  bcf    rechts
  call  pause100

  bsf    links
  call  pause50
  bcf    links
  call  pause75
  bsf    rechts
  call  pause50
  bcf    rechts
  call  pause75

  bsf    links
  call  pause50
  bcf    links
  call  pause75
  bsf    rechts
  call  pause50
  bcf    rechts
  call  pause75

  bsf    links
  call  pause50
  bcf    links
  call  pause50
  bsf    rechts
  call  pause50
  bcf    rechts
  call  pause50

  bsf    links
  call  pause50
  bcf    links
  call  pause50
  bsf    rechts
  call  pause50
  bcf    rechts
  call  pause50

  bsf    links
  call  pause50
  bcf    links
  call  pause25
  bsf    rechts
  call  pause50
  bcf    rechts
  call  pause25

  bsf    links
  call  pause50
  bcf    links
  call  pause25
  bsf    rechts
  call  pause50
  bcf    rechts
  call  pause25

  bsf    links
  call  pause50
  bcf    links
  call  pause10
  bsf    rechts
  call  pause50
  bcf    rechts
  call  pause10

  bsf    links
  call  pause50
  bcf    links
  call  pause10
  bsf    rechts
  call  pause50
  bcf    rechts
  call  pause10

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

  call  pause250
  call  pause250
  bsf    links
  bsf    rechts
  call  pause150
  bcf    links
  bcf    rechts

  clrf  xflags            ; 'xflags' löschen
  goto  main
;
;**************************************************************
; Pause-Routine
;
pause1s
  call  pause250
  call  pause250
  call  pause250
  call  pause250
  return

pause250
  movlw  D'250'      ; 250 ms Pause
  movwf  loops
  call   wai
  return

pause200
  movlw  D'200'      ; 200 ms Pause
  movwf  loops
  call   wai
  return

pause175
  movlw  D'175'
  movwf  loops
  call   wai
  return

pause150
  movlw  D'150'
  movwf  loops
  call   wai
  return

pause125
  movlw  D'125'
  movwf  loops
  call   wai
  return

pause100
  movlw  D'100'
  movwf  loops
  call   wai
  return

pause75
  movlw  D'75'
  movwf  loops
  call   wai
  return

pause50
  movlw  D'50'
  movwf  loops
  call   wai
  return

pause25
  movlw  D'25'      ; 25 ms Pause
  movwf  loops
  call   wai
  return

pause10
  movlw  D'10'      ; 10 ms Pause
  movwf  loops
  call   wai
  return

pause1
  movlw  D'1'      ; 1 ms Pause
  movwf  loops
  call   wai
  return

; Warteschleife für 1 ms
wai
  movlw  D'110'      ; Zeitkonstante für 1 ms
  movwf  loops2
wai2
  nop
  nop
  nop
  nop
  nop
  nop
  decfsz  loops2, F    ; 1 ms vorbei?
  goto  wai2      ; nein, noch nicht

  decfsz  loops, F    ; 250 ms vorbei?
  goto  wai        ; nein, noch nicht
  return          ; das Warten hat ein Ende
;
;**************************************************************
; ENDE
;
ende
  end

von Carsten S. (dg3ycs)


Lesenswert?

Hi,

rotermexico schrieb:
Zuerst mal der Hinweis: GEschätzt 4/5 der Programmcodes dienen nur der 
Ausgabe von Blinkmustern... Der Teil der über das Auf/Zu entscheidet ist 
nur wenige ZEilen groß

Entscheidend sind hier die Zeilen
Im durch PEgelwechsel ausgelösten Interrupt:
    call  pause50          ; Pause wegen Prellen
    btfsc  open          ; aufschließen?
    goto  react          ; Jo
    btfss  close          ; zuschließen?
    goto  intFail          ; Nö

react
    btfsc  open
    bsf    open_akt
    btfsc  open
    bcf    close_akt

***
grobe Erklärung:
Bei einem Pegelwechsel wird in die Interruptroutine gesprungen, da wird 
dann zwecks Entprellung noch mehrfach geprüft ob - und welche Taste noch 
gedrückt ist, dann ein entsprechendes Flag gesetzt und zum Schluss noch 
gewartet bis die Taste wieder losgelassen wird.
***

und dann halt das Hauptprogramm:

; Hauptprogrammschleife
;
main
  btfsc  open_akt        ; aufschließen?
  goto  blink_auf        ; Jo
  btfsc  close_akt        ; zuschließen?
  goto  blink_zu        ; Jo

  goto  main
;
Hier wird dann nur noch geprüft ob eines der Flags zwischenzeitlich (im 
Interrupt) gesetzt wurde. Wenn eines der Flags gesetzt wurde wird in die 
entsprechende Unterroutine gesprungen.
Die eigendliche Aktion öffnen oder schließen findet also ausserhalb des 
Interrupts statt. Der Rest des Programms ist noch ein wenig 
Initialisierung und ganz viel Blinkmusterausgabe...

> Kann man das ändern das der PIC auf die anzahl der pulse reagiert ??


Ja, das kann man.
Dazu musst du den Inhalt der Interupptroutine austauschen.
Insbesondere die 10 oben zuerst zitierten Zeilen.
Aber für die neue Lösung wirst du mit 10 Zeilen nur schwerlich 
hinkommen. Und wenn di Pulse dann noch von einem Mensch o.ä. und nicht 
selbst von einem µC erzeugt werden wird es noch etwas komplizierter. 
(Variable Pulslänge + variabler Abstand dazwischen)

Mit einfach mal zwei drei Zeilen austauschen ist es da nicht getan.
Da musst du dir schon noch einige Gedanken zu machen.

Von der Schwierigkeit würde ich mal behaupten diese Lösung in Assembler 
so umzustricken oder das ganze Programm in C neu zu schreiben duerfte 
sich nicht viel tun.
(Bei jemanden der in PIC ASM fit ist sieht es natürlich doch etwas 
anders aus. Aber das bist du ja nicht.
Und ich helfe bei konkreten Fragen zwar gerne,
aber die Arbeit selber werde ich dir sicher nicht abnehmen...)

Gruß
Carsten

: Bearbeitet durch User
von Noch einer (Gast)


Lesenswert?

Am schnellsten kommst du wohl bei weg, wenn du zuerst die Pic-Assembler 
Tutorials von Sprut durcharbeitest.

http://www.sprut.de/electronic/pic/

Die Interruptroutine austauschen? Dafür muss man eigentlich so ziemlich 
alles wissen, was dieses Tutorial beschreibt.

In C programmieren? Das Datenblatt hat nur Assembler-Beispiele. Brauchst 
eh einen rudimentären Überblick zum Pic Assembler.

von Michael L. (michaelx)


Lesenswert?

rotermexico schrieb:
> Assembler kann ich leider nicht ...

Nicht können ist keine Schande, nicht wollen schon. ;-)

Ich kann meinem Vorposter nur zustimmen.

Sofern man eine Programmiersprache beherrscht, sollte es nicht schwer 
fallen, sich wenigstens in ein in einer anderen Sprache geschriebenes 
Programm hineinzudenken. Das für den Einstieg nötige Wissen beschränkt 
sich gerade beim PIC-Assembler auf sehr wenige Seiten im Datenblatt, 
welches ohnehin Pflichtlektüre ist. Ein Teil der Befehle (mov, call, 
ret, add, ...) erklärt sich eh schon von selbst, und vieles von dem, was 
man wissen muss, gilt zudem nicht nur für die Assemblerprogrammierung, 
obwohl die Beispiele alle in ASM geschrieben sind. Auch in C muss man 
sich mit den Registern herumschlagen, und bestimmte Abhängigkeiten und 
Bedingungen berücksichtigen. Die Tutorial von Sprut sind auch da eine 
große Hilfe.

Grüße.

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.