PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Assembler-Programm Zeitschleife: Ich finde den Fehler nicht!



wolf***
20.01.2007, 12:43
Ein Hallo an alle Experten,
ich will ein kleines Assembler - Programm schreiben und sehe den Fehler nicnt!
Es sollte mal ein Programm werden, welches durch jeden Interrupt eine beliebige Zeit aufaddiert. 1. Interrupt=5 Min., kommt in der Zeit der 2. Interrupt dann 10 Min.usw. Wie ein retriggerbares Mono-Flipflop.

Der RC Takt= 4,8kHz durch 4=1,2kHz für lange Zeiten.

Ich habe jetzt TEST Punkte eingebaut, so dass nur UP-timer2 PORTA,1 eine LED einschaltet, dann loop1 abarbeitet, dann die LED wieder ausschaltet und in l4 hängenbleibt.

Die LED blinkt, warum nur warum????? https://www.roboternetz.de/phpBB2/images/smiles/eusa_wall.gif
Brick wall

Ist die Zeitschleife falsch????
mfg wolf

list p=16f84a ;PIC type auswählen
;------------------------------------
;
; Pinbelegung
; ----------------------------------
; PORTA: 0 LED
; 1
; 2
; 3
; 4
; PORTB: 0 Eingang Interrupt
; 1
; 2
; 3
; 4
; 5
; 6
; 7
;----------------------------------
;Dr. Ver: 2.1 20.01.2007
;Interrupt
;Takt: RC
;0-1-Flanke an RB0 ändert LED an RA0
;-----------------------------------
;Includedatei für den 16f84 einbinden
#include <P16f84a.INC>
;Configuration festlegen
;4Mhz, Power On Timer, kein Watchdog, RC-Oszillator
;A C H T U N G : R C - O S Z I L L A T O R
__config _PWRTE_ON & _WDT_OFF & _RC_OSC
;-------------------------------
;init

;Variablennamen vergeben

s_copy equ 0x20
w_copy equ 0x21
verz equ 0x22
loop1 equ 0x23
loop2 equ 0x24
loop3 equ 0x25
;--------------------------------------------

org 0x00
goto Init ; Sprung zum Hauptprogramm

;-------------------------------------------------
; die Interuptserviceroutine

org 0x04
intvec
movwf w_copy ; w retten
swapf STATUS, w ; STATUS retten
movwf s_copy
;-----------------------------------------------------;
incf verz, f ; verz + 1

bsf PORTA,0 ;LED einschalten


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

Int_end
bcf INTCON, INTF ; RB0-Interupt-Flag löschen
swapf s_copy, w ; STATUS zurück
movwf STATUS
swapf w_copy, f ; w zurück mit flags
swapf w_copy, w
retfie
;------------------------------------------------------

; das Hauptprogramm

Init
beginn clrf verz ;verz aus

;-----------------------------------------------------
; Port RA0 auf Ausgabe stellen

bsf STATUS, RP0 ; auf Bank 1 umschalten
movlw B'11111100' ; PortA RA0+RA1= output
movwf TRISA
bcf STATUS, RP0 ; auf Bank 0 zurückschalten
bcf PORTA,0 ; LED aus
call time2 ;TEST TEST!
;-------------------------------------------------------
; RB0-Interrupt einstellen
bsf STATUS, RP0 ; auf Bank 1 umschalten
bsf OPTION_REG, INTEDG ; 0-1-Flanke an RB0
bcf STATUS, RP0 ; auf Bank 0 zurückschalten
;
bsf INTCON, INTE ; RB0-interupt erlauben
bsf INTCON, GIE ; Interupt generell erlauben
;------------------------------------------------------
; movlw 0x01
; movwf PORTA
; movlw 0x2
; movwf verz
;-------------------------------------------------------
m1 movf verz,f ;Verz=0, Z=1
btfsc STATUS,Z
goto m1 ;wenn Z=1
call time2 ;wenn Z=0
;----------------------------------------------
movf verz,f ;verz=0 dann Z=1
btfsc STATUS,Z ;
bcf PORTA,0 ;wenn Z=1, LED Aus
goto m1 ;wenn Z=0



;--------------------------------------------
time2 bsf PORTA,1 ;TEST TEST
time1 movlw d'1'
movwf loop3
l3 movlw d'1'
movwf loop2
l2 movlw d'2'
movwf loop1
l1 decfsz loop1,f
goto l1
bcf PORTA,1
l4 nop
goto l4 ;TEST TEST
decfsz loop2,f
goto l2
decfsz loop3,f
goto l3
decfsz verz,f
goto time1

Return

end

](*,) ](*,) ](*,) ](*,) ](*,)

PICture
20.01.2007, 23:25
Hallo wolf***!

Ich bin zwar kein Experte, aber vielleicht kann ich Dir helfen.

Dein Feler ist leicht zu finden. Es ist eine endlose Schleife:

l4 nop
goto l4

Deine Beschreibung des Programms (was es eigentlich machen soll), ist für mich leider unverständlich.

Ich würde Dir empfehlen nur so grosse (am Anfang sehr eifache) Programme zu schreiben die Du durchblicken und Fehler selber finden kannst.

Sonst verlierst Du viel Zeit, in der Du bei einfachen Programmen viel lernen kannst.

Es wäre auch sehr hilfreich, sich vor dem Schreiben eines Programms, ein flowchart zu erstellen, um später unvermeindliche Fehler schneller finden zu können.

MfG

wolf***
21.01.2007, 12:56
Hallo PICture,
erst mal schönen Dank fürs durchsehen des Programms, leider sind die TABs verrutscht, es muss da noch einen anderen Weg geben, das Programm hier darzustellen. Wenn ich das Programm mit den Debugger von MPLAP überprüfe scheint ja alles so zu funktionieren wie ich denke, aber leider nicht im programmierten PIC. Diese Endlosschleife soll die das Programm stoppen, wenn die innere Zeitschleife (loop1) abgelaufen ist. Also passiert im Testfall jetzt folgendes: PORTA,1 schaltet eine LED zur kontrolle ein. Loop1 lauft 255 mal, die LED wird ausgeschaltet und die Endlosschleife rotiert. Meiner Meinung nach müsste die LED ca. 2sec aufblitzen und das wars, aber die LED geht für ca. 0,1sec an, ist dann für 2sec aus usw. wegen dieser Endlosschleife dürfte die LED aber nur einmal angehen. Ich wollte so nacheinander die drei verschachtelten Zeitschleifen in Echtzeit testen, eigentlich ganz einfach in der Theorie und im Debugger funktioniert es auch so, aber leider nicht in der Praxis
MfG Wolf***

PICture
21.01.2007, 13:57
Hallo wolf***!

Tja, das ist eben der Unterschied zwischen der Theorie und Praxis. Ich habe schon mehrmals gesagt, dass ich jede Simulation als Zeitverschwendung finde und selber nie eingesetzt habe.

Ubrigens, Deine endlose Schleife wird vom Interrupt immer unterbrochen und die LED jedesmal eingeschaltet.

Also wenn man schon Interrupts im Programm hat, muss man damit rechnen, dass das Programm auf jede Stelle, die dem Programmierer meistens unbekannt ist, durch Interrupt angehalten wird und nach dem Ausführen der ISR fortgesetzt wird, an der Stelle wo es unterbrochen war. Wenn das Programm sich in einer endloser Schleife befindet, wird es vom ISR sicher dort unterbrochen.

Man muss sich vorstellen können, dass im Falle, wenn Interrupts benutzt werden, mehrere Programme paralell und gleichzeitig laufen.

Wenn es um posten vom Code geht, dann ist es sehr eifach:

1. Den Code mit "Ctrl" und "C" Tasten in zwischenablage kopieren.
2. Den Kursor im Beitrag auf gewünschte Stelle bringen.
3. Den Code mit "Ctrl" und "V" Tasten in Beitrag kopieren.
4. Mit "Vorschau" den Beitrag abschliessen.

MfG :)