Forum: Mikrocontroller und Digitale Elektronik PIC16F628 retriggerbares Monoflop ASM - Hilfe!


von Skipper (Gast)


Lesenswert?

Hallo Jungs,

ich versuche mich gerade beim Programmieren von Zeitschleifen mit einem
PIC 16F628.

Hierzu habe ich mir von einem anseren User ein fertiges Programm als 
Vorlage genommen und will jetzt verstehen wie was geht.

Aber am Anfang gehen schon meine Probleme los.
Der Erfinder dieses Programms hat eine Art TAstenentprellung eingebaut 
die ich nicht verstehe bzw. deaktiviert bekomme.

Man muß, egal welchen PORTA 1Sekunde auf High setzen bevor das Signal 
weiter verarbeitet wird. Die Ausgänge fallen nach einer vorgegebenen 
Zeit wieder ab.

Dieses Warten von 1 Sekunde am Eingang würde ich gern deaktivieren.
Aber Wie???  Egal was ich versuche hat den kompletten Verkust des Delays 
am Ausgang zur Folge.

Kann mir jemand helfen?


hier das Program:
; *******************************************************************
; 8-bit retriggerable monoflop, with 35 second output pulse
; *******************************************************************
;
; 2008 Copyright by Frank Buss
; *******************************************************************

            LIST    P=16F628A

#include "P16F628A.INC"

            __CONFIG _INTOSC_OSC_NOCLKOUT & _WDT_OFF &_PWRTE_OFF & 
_MCLRE_OFF & _BOREN_OFF & _LVP_OFF & _DATA_CP_OFF & _CP_OFF

; defines
Delay       EQU D'35'   ; Monoflop time in seconds
IRQ_W       EQU 0x20
IRQ_S       EQU 0x21
Counter     EQU 0x22
Seconds     EQU 0x23
tmp         EQU 0x25
Monoflop    EQU 0x26    ; array of 8 counters
OldInput    EQU 0x2e
LastInput   EQU 0x2f
Triggered   EQU 0x30
NewOut      EQU 0x31

            org 0
            goto    start

; interrupt function:
; increment the register Seconds each second by one
; ----------------------------------------------------------
            org 4
; interrupt intro
            movwf  IRQ_W        ; save w
            swapf  STATUS, W    ; save STATUS
            movwf  IRQ_S

; interrupt main
            incf    Counter, F

IrqTest:    movlw   D'61'
            xorwf   Counter, W
            btfss   STATUS, Z   ; skip, if zero
            goto    IrqEnd
            clrf    Counter
            incf    Seconds, F

; interrupt end
IrqEnd:
            bcf    INTCON, T0IF ; delete IRQ flag
            swapf  IRQ_S, W     ; restore STATUS
            movwf  STATUS
            swapf  IRQ_W, F     ; restore W
            swapf  IRQ_W, W
            retfie

; program start
; ----------------------------------------------------------
start:
; init hardware
            movlw   D'0'        ; set levels low
            movwf   PORTB       ;  for PortB
            movlw   D'7'        ; turn comparators off and
            movwf   CMCON       ;  enable pins for I/O functions
            clrwdt
            bsf     STATUS, RP0 ; select bank 1
            movlw   D'0'        ; all bits of PortB as output
            movwf   TRISB - 0x80
            movlw   D'255'      ; all bits of PortA as input
            movwf   TRISA - 0x80
            movlw   D'5'        ; prescaler: 64
            movwf   OPTION_REG - 0x80
            bcf     STATUS, RP0 ; select bank 0

; clear variable memory
            movlw   0x20
            movwf   FSR
next:       clrf    INDF
            incf    FSR, F
            btfss   FSR, 6
            goto    next

; save current port state
            movf    PORTA, W
            movwf   OldInput

; global interrupt and timer interrupt enable
            bsf    INTCON, GIE
            bsf    INTCON, T0IE

; main loop
loop_start:
; wait one second and accumulate port changes in "Triggered" while 
waiting
            clrf    Triggered
            movf    Seconds, W
            movwf   tmp         ; save current second counter
wait:       movf    Seconds, W  ; test current second counter
            xorwf   tmp, W
            btfss   STATUS, Z   ; skip, if zero
            goto    trigger
            movf    PORTA, W
            movwf   LastInput   ; save last port state
            xorwf   OldInput, W
            iorwf   Triggered, F    ; OR changed port bits
            goto    wait

; retrigger monoflops for all changed port bits
trigger:
            movf    LastInput, W
            movwf   OldInput    ; last port state will be start for next 
test

            movlw   Monoflop    ; save address of first Monoflop counter
            movwf   FSR         ; in FSR for indirect addressing
            movlw   8           ; test 8 bits
            movwf   tmp
            clrf    NewOut
trigger2:   bcf     STATUS, C
            rrf     NewOut, F   ; shift new output byte
            movf    Triggered, W
            andlw   D'1'
            btfsc   STATUS, Z   ; skip, if not zero
            goto    OutTest
            movlw   Delay
            movwf   INDF        ; retrigger Monoflop, if input changed

OutTest:    movf    INDF, W
            btfsc   STATUS, Z   ; skip, if not zero
            goto    OutTest2
            bsf     NewOut, 7   ; set ouput bit, if Monoflop is not zero
            decf    INDF, F     ; decrement Monoflop counter

OutTest2:
            bcf     STATUS, C
            rrf     Triggered, F    ; shift triggered bits for next bit
test

            incf    FSR, F
            decf    tmp, F
            btfss   STATUS, Z   ; skip, if zero
            goto    trigger2

            movf    NewOut, W   ; copy new output bits to output port
            movwf   PORTB

            goto    loop_start

            end



Bitte helft mir.

MfG Andy

von Tobi D. (fanti)


Lesenswert?

Hallo,

wenn du wirklich nur erstmal einfache Zeitschleifen erlernen möchtest, 
dann solltest du nicht mit so einem Beispiel einsteigen, sondern eher 
sowas probieren:
mainloop:
btfss PORTA,0
goto mainloop
bsf PORTB,0
call wait
bcf PORTB,0
goto mainloop

wait:
        movlw   D'250'          ; 250 ms Pause
        movwf   loops

Wai
        movlw   .110           ; Zeitkonstante für 1ms
        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
        retlw   0              ; das Warten hat ein Ende

(siehe sprut)


ich habe zwar im Moment das Experimentierboard nicht am laufen, aber 
spontan würde ich die wait routine verändern, teste es mal bei deinem 
Programm


wait:       movf    Seconds, W  ; test current second counter
            xorwf   tmp, W
            btfss   STATUS, Z   ; skip, if zero
            goto    trigger
            movf    PORTA, W
            movwf   LastInput   ; save last port state
            xorwf   OldInput, W
            iorwf   Triggered, F    ; OR changed port bits
            goto    wait



zu ändern in:

wait:
movf    PORTA, W
movwf   LastInput
btfss   STATUS,Z
goto    wait
goto    trigger

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.