;------------------------------------------------------------------------------ ; Dieses Programm testet eine Frequenz die an Port P3.2 und p3.4 anliegen muss ; ;------------------------------------------------------------------------------ $INCLUDE (REG_8252.INC) ; include Controller-Definitionsdatei (AT89S8252) ; ;//Start-of-code (fuer HITOP) ; ;------------------------------------------------------------------------------ ; Reservierung des Stack-Bereiches ;------------------------------------------------------------------------------ ?STACK SEGMENT IDATA ; ?STACK im indirekt adressierbaren internen RAM RSEG ?STACK ; ?STACK-Segment waehlen DS 10h ; Reserviere z.B. 16 Bytes Stack ; ;------------------------------------------------------------------------------ ; Reserviere Speicherplatz fuer Variablen im int. direkt adressierbaren RAM ;------------------------------------------------------------------------------ dir_daten SEGMENT DATA ; deklariere Datensegment RSEG dir_daten ; waehle Datensegment ; SUBL: DS 1 ; Sub Low ist die Variable, die das zwischenergebniss der Lowbyt subtraktion zwischenspeichert ; ; FHI : DS 1 ; Variable für den Wert von Timer1 High FLO : DS 1 ; Variable für den Wert von Timer1 Low ; ; IMPL: DS 1 ; Variable für den Wert von Timer0 Low IMPH: DS 1 ; Variable für den Wert von Timer0 High ; ;------------------------------------------------------------------------------ ; Wertzuordnung ;------------------------------------------------------------------------------ ; ; Variablen für die Impulslänge zur überprüfung Gesamtwert 250 ; ; SIMPL EQU 0fah ; Sollwert Impuls Low ist 250 SIMPH EQU 00H ; Sollwert Impuls High ist 0 ; ; ; ; Variablen für die Überprüfung der minimalen Taktlänge Gesamtwert 300 ; ; SFREQL EQU 2cH ; Maximalwert Takt L ist 44 SFREQH EQU 01H ; Maximalwert Takt L ist 1 ; ; ; ;------------------------------------------------------------------------------ ; Auf Adresse 0 im Code-Speicher muss ein LJMP zum Programmanfang stehen ;------------------------------------------------------------------------------ CSEG AT 0 ; absolutes Code-Segment bei Adresse 0 LJMP start ; Springe zur Marke start ;------------------------------------------------------------------------------ ; Interrupt-Vektoren auf definierten Adressen ;------------------------------------------------------------------------------ CSEG AT 03H ; 03H ist Einsprungadresse fuer extern interrupt LJMP isr_mess ;------------------------------------------------------------------------------ ; Hier folgt Programmcode (Code-Beginn ueber Linker festgelegt) ;------------------------------------------------------------------------------ program_code SEGMENT CODE RSEG program_code ; waehle Code-Segment USING 0 ; Zeige Benuetzung von Registerbank 0 ; fuer den folgenden Programmcode an start: MOV SP,#?STACK-1 ; Stack-Definition orl tmod,#11111111b ; Einstellen der Betriebsmodi der Timer anl tmod,#00011001b ; Timer0 als gated Timer und Timer 1 als 16bit timer clr it0 ; Der externe Interrupt reagiert auf neg Falnke mov th0,00h ; Timer1 und Timer0 werden auf 0 gesetzt mov tl0,00h mov th1,00h mov tl1,00h setb eal ; generelle IR-Freigabe setb tr0 ; Timer 0 im gated modus wird aktiviert, zählt jedoch nur wenn auch an P3.4 ein high Signal anliegt loop: setb ex0 ; IR Fenster für eine fallende Flanke an P 3.4 nop clr ex0 mov p0,0ffh ; alle LEDs werden ausgeschaltet lcall impmess lcall freq_paus ljmp loop ;-------------------------------------------------------------------------------- ; ; Unterprogramme und Serviceroutine ; ;-------------------------------------------------------------------------------- ; ; Serviceroutine ;-------------------------------------------------------------------------------- isr_mess: clr tr0 ; stoppen des Timer0 cpl p0.3 ; bei jedem durchlauf ändert die LED an P0.3 ihren status /sollte blinken->funktioniert jnb tr1,t1go ; überprüfung ob Timer1 läuft, falls ja weiter falls nein sprung zu t1go clr tr1 ; stoppen von Timer1 mov fhi,th1 ; schreiben der Werte von Timer1 HB nach fhi mov flo,tl1 ; schreiben der Werte von Timer1 LB nach flo mov th1,#0 ; nullen von HB und LB mov tl1,#0 Imp_1: mov Impl,tl0 ; schreiben der Werte von Timer0 LB nach Impl mov Imph,th0 ; schreiben der Werte von Timer0 HB nach Imph mov th0,#0 ; nullen von HB und LB mov tl0,#0 setb tr0 ; Timer0 wird wieder gestartet reti t1go: setb tr1 ; starten von Timer1 ljmp Imp_1 ;------------------------------------------------------------------------------------ ; Unterprogramm zur Messung der Impulslänge ;------------------------------------------------------------------------------------ impmess: clr c ; löschen des carrybits mov a,Imph ; schreiben des HB der Impulslänge in den Akku cjne a,SIMPH,zuhoch ; überprüfung auf Ref wert falls ungleich sprung nachzuhoch mov a,Impl ; schreiben des LB der Impulsläge in den Akku cjne a,SIMPL,ungleich ; überprüfung auf Ref Wert, falls unglcih sprung nach ungleich clr P0.6 ; anschalten der ok LED ret ungleich: jc zuhoch ; falls das carybit gesetzt ist wird anch zu hoch gesprungen clr P0.7 ; anschalten der zu klein LED ret zuhoch: cpl P0.5 ; anschalten der zu groß LED ret ;-------------------------------------------------------------------------------------- ; Unterprogramm zur Bestimmung der Pausenlänge sowie der Taktlänge ;-------------------------------------------------------------------------------------- freq_paus: clr c ; löschen des Carrybit mov a,fhi ; das HB von Timer1 wird in den Akku geladen cjne a,sfreqh,ubertrag ; es wird mit dem Sollwert verglichen, bei ungleichheit weiter bei ubertrag mov a,flo ; das LB von Timer1 wird in den Akku geladen cjne a,sfreql,ubertrag ; es wird mit dem Sollwert verglichen, bei ungleichheit weiter bei ubertrag pause: clr c ; löschen des Carrybit mov a,flo ; das LB von Timer1 wird in den Akku geladen subb a,Impl ; das LB der Impulsmessung wird davon abgezogen mov subl,a ; das Ergebnis wird nach Subl geschrieben mov a,fhi ; das HB wird in den Akku geladen subb a,Imph ; das HB der Impulsmessung wird subtrahiert jnz gruneLED ; ist das Ergebnis nun nicht 0 wird zu grune LED gesprungen mov a,subl ; war das Ergebnis null wird nun das Ergebnis der LB subtraktion überprüft subb a,#250 ; der mindestwert wird vom Ergebnis der Subtraktion abgezogen jc roteLED ; sollte dieser mindestwert größer sein wird das carrybit gesetzt, dieses wird nun überprüft ; ob es gesetzt ist oder nicht, sollte es gesetzt sein geht es weiter bei roteLED gruneLED: clr P0.0 ; die LED an P0.0 wird angeschaltet ret ; zurück ins Hauptprogramm ubertrag: jc pause ; das Carrybit wird überprüft, sollte es gesetzt sein geht es bei Pause weiter ; sonst sprung nach roteLED roteLED: clr P0.1 ; die LED an P0.1 wird angeschaltet ret ; zurück zum Hauptprogramm END ; End Of File