; ******************************************************************* ; * PCM2PWG-Dekoder fuer AT90S2323, Version 0.4 vom 20.12.2000 * ; * Dekodiert PCM Pulse in pulsweitenmoduliertes Rechtecksignal * ; * (C)2000 by info@avr-asm-tutorial.net * ; ******************************************************************* ; ; Momentan eingestellt auf PCM-Signale von 800 bis 2200 µs und 4 MHz ; Taktfrequenz des Prozessors. ; Durch Anpassung der Konstanten unten kann der Code an andere Signale ; angepasst werden. ; ; VCC LED PWG PCM PCM-Ein: 25ms = 40 Hz Frequenzeingang ; Aus Aus Ein positiv gepulste PCM-Signale ; +-8----7----6----5--+ ; | | PWG-Aus: 1.4 ms = 714 Hz Ausgangsfrequenz ; O AT 90 S 2323 | positiv gepulst fuer 0..1,4 ms ; | | ; +-1----2----3----4--+ LED-Aus: Ausgang auf Null, wenn Fehler ; RST XT1 XT2 GND ; ; ********* Eingangssignal PCM-kodiert ************************ ; ; Phase I II III IV V VI VII ; PCM 1---- -------------------- ------ ; Ein \\\\\ / \\\\\\\\\\\\ / ; 0------------ ------------------------ ; ; ********* Ausgangssignal Pulsweite-Oszillator *************** ; ; PWG 1 ------------- ------ ; Aus / \ / ; 0---- ------------- ; Zeit µs |<--0..cCycl->|<-cCycl..0-->| 800 - 2200 µs: ; |<----------cCycl---------->| cCycl = 1400 µs ; ; ************************************************************* ; .NOLIST .INCLUDE "C:\avrtools\appnotes\2323def.inc" .LIST ; ; Verwendete Register ; .DEF rmpr = R16 ; Vielzweckregister .DEF rdel = R17 ; Register fuer Verzoergerungsschleifen .DEF rpwc = R18 ; Zaehler fuer den Pulsweiten-Generator .DEF rpws = R19 ; Aktueller Ausgangswert fuer den Pulsweiten-Generator .DEF rpwn = R20 ; Naechster Wert fuer Pulsweiten-Generator .DEF rtry = R21 ; Anzahl der zulaessigen Fehlversuche .DEF rctr = R22 ; Zaehler fuer aktive Schleifen .DEF rerr = R23 ; Anzahl Fehlversuche ; ZL = R30 and ZH = R31 werden fuer lange Zeitschleifen benutzt ; ; IO-Port-Bits ; .EQU pbmode = 0b00000110 ; Port B Port-Modus .EQU bIn = 0 ; Eingangspin 0, positive Polaritaet .EQU bOut = 1 ; Ausgabe fuer Pulsweitengenerator .EQU bFail = 2 ; Ausgang fuer die Fehler-LED, aktiv Null ; ; Konstanten (1 Zyklus = 6 µs = 24 Taktzyklen bei 4 MHz) ; ; Anpassung der Quarzfrequenz an andere Taktfrequenzen des Prozessors ; .EQU cXtal = 4 ; Taktfrequenz in MHz ; ; Anpassung der Gesamtlaenge an andere Eingangssignale ; .EQU cPulseDuration = 25000 ; Gesamtdauer des Eingangsimpulses in µs ; ; Anpassung der Zeiten an andere PCM-Pulsweiten ; .EQU cMinPulse = 800 ; Minimum Pulsdauer in µs .EQU cMaxPulse = 2200 ; Maximum Pulsdauer in µs ; ; Anpassung des Defaultwertes fuer den Pulsweiten-Generator bei ; Fehlsignalen oder Signalverlust, 0%: Ausgang wird Null, 100%: ; Ausgang wird dauerhaft Eins, 50%: Ausgang geht auf 50% Pulsweite ; .EQU cFallBackValue = 50 ; 50% Pulsweite ; ; Die folgenden Werte werden automatisch aus den obigen Angaben ; ausgerechnet. Bitte nur aendern, wenn Du weisst was Du tust! ; .EQU cUnitLength = 24 ; Taktzyklen pro Schleifendurchgang .EQU cCycleLength = cUnitLength/cXtal ; Gesamtschleifendauer in µs .EQU cCycl = cPulseDuration/cCycleLength ; Schleifen in 25 ms .EQU cStep = (cMaxPulse-cMinPulse)/cCycleLength ; Aktive Schleifen .EQU cTolerance = cStep/10; Tolerierte Frueh- und Spaetschleifendauer .EQU cMinSteps = cMinPulse/cCycleLength ; Schleifen bis zum Zaehlbeginn .EQU cMaxSteps = cMaxPulse/cCycleLength ; Schleifen nach Zaehlende .EQU cMin1 = cMinSteps-cTolerance-1 ; Mindestschleifen mit Eingang hoch .EQU cTlp = cTolerance-1 ; Fruehzeitige inaktive Schleifen, toleriert .EQU cTla = cTolerance ; Schleifen nach Ende der aktiven Zaehlzeit .EQU cMin0 = (cCycl-cMaxSteps)*90/100 ; Schleifen mit inaktivem Signal .EQU cFbck = 1 ; Number of false signals to tolerate before default is set .EQU cDflt = cstep*cFallbackValue/100 ; Default-Wert fuer den PWG ; ; Makros fuer den Error-LED-Ausgang (auf Aktiv low eingestellt) ; .MACRO LedErrOn cbi PortB,bFail .ENDM .MACRO LedErrOff sbi PortB,bFail .ENDM ; ; Makros fuer Verzoegerungen ; .MACRO Delay1 ; Einzelschritt nop .ENDM ; .MACRO Delay2 ; Doppelschritt nop nop .ENDM ; .MACRO Delay3 ; Verzoegerung um Vielfache von je 3 Schritten ldi rdel,@0 MD3: dec rdel brne MD3 .ENDM ; .MACRO Delay4 ; Verzoegerung um Vielfache von je 4 Schritten ldi rdel,@0 MD4: dec rdel nop brne MD4 .ENDM ; .MACRO MacPwm ; Makro fuer den Pulsweiten-Generator dec rpwc ; 1 1 1 1 breq MAP2 ; 1 1 2 2 cp rpws,rpwc ; 1 1 brcs MAP1 ; 1 2 nop ; 1 cbi PortB,bOut; 2 rjmp MAP3 ; 2 MAP1: sbi PortB,bOut; 2 rjmp MAP3 ; 2 MAP2: mov rpws,rpwn ; 1 1 ldi rpwc,cstep; 1 1 sbi PortB,bOut; 2 2 nop ; 1 1 nop ; 1 1 MAP3: ;----------- ; 9 9 9 9 ;=========== .ENDM ; ; Beginn des Hauptprogrammes, initiere Variablen ; Start: ldi rpwc,cDflt ; Zaehler fuer den PWG ldi rpws,cDflt ; Aktueller PWG-Wert ldi rpwn,cDflt ; Naechster PWG-Wert ; Initiiere den Port B ; ldi rmpr,pbmode ; Setze Datenrichtungsregister out DDRB,rmpr ; von Port B sbi PortB,bIn ; Schalte Pull-Up-Widerstand am Eingang an ; Starte Phase I : Warte bis der Eingang Null wird ; ; Schalte Fehler ein, bis das Signal korrekt ist ; PH1: macpwm ; 9 ldi rerr,cFbck; 1 ldi rpwn,cDflt; 1 lederron ; 2 delay3(3) ; 9 ; ; Setze maximale Zeitdauer fuer die Erkennung eines Null-Signals ; PH1a: ldi ZL,Low(cCycl); 1 ldi ZH,HIGH(cCycl);1 ; --- ; 24 ; === ; Warte bis der Eingang Null ist oder Zeitueberlauf eintritt ; PH1b: macpwm ; 9 9 9 sbis PinB,bIn ; 2 2 1 rjmp PH2 ; 2 sbiw ZL,1 ; 2 2 breq PH1c ; 1 2 delay4(2) ; 8 rjmp PH1b ; 2 ; --- ; 24 ; === ; Zeitueberlauf mit Eingang auf Eins ; PH1c: ; (15) delay4(1) ; 4 ; ; Fehler bei aktivem Eingang, zaehle die Fehler ; PH1d: ;(19 19) dec rerr ; 1 1 brne PH1a ; 2 1 ; ; Zu viele Fehler in Folge, setze Fehlerbedingung ; delay1 ; 1 rjmp PH1 ; 2 ; --- ; 24 ; === ; Starte Phase II: Eingang ist Null, warte auf aktives Signal ; PH2: ; (12) delay3(2) ; 6 delay2 ; 2 rjmp PH2b ; 2 ; ; Fehler aufgetreten, setze Fehlerbedingung ; PH2a: macpwm ; 9 ldi rerr,cFbck; 1 ldi rpwn,cDflt; 1 lederron ; 2 delay3(3) ; 9 ; ; Setze Zaehler fuer Zeitueberlauf bei inaktivem Eingang ; PH2b: ; (22 22) ldi ZL,LOW(cCycl); 1 1 ldi ZH,HIGH(cCycl); 1 1 ; ------ ; 24 24 ; ====== ; Warte bis der Eingang eins ist oder Zeitueberlauf passiert ; PH2c: macpwm ; 9 9 9 9 sbic PinB,bIn ; 2 2 2 1 rjmp PH3 ; 2 sbiw ZL,1 ; 2 2 2 breq PH2d ; 1 2 2 delay4(2) ; 8 rjmp PH2c ; 2 ; --- ; 24 ; === ; Zeitueberlauf bei inaktivem Eingang, zaehle Fehler ; PH2d: ; (15 15) delay4(1) ; 4 4 PH2e: ; (19 19) dec rtry ; 1 1 brne PH2b ; 1 2 nop ; 1 rjmp PH2a ; 2 ; --- ; 24 ; === ; Phase III: Eingang ist aktiv geworden, warte cMin1 Schleifen, ob stabil ; PH3: ; (12) delay3(3) ; 9 delay2 ; 2 ldi rtry,cMin1; 1 ; --- ; 24 ; === ; Warte bis cMin1 Schleifen mit aktivem Eingang abgelaufen ; PH3a: macpwm ; 9 9 9 sbis PinB,bIn ; 2 2 1 rjmp PH3b ; 2 dec rtry ; 1 1 breq PH4 ; 1 2 delay3(3) ; 9 rjmp PH3a ; 2 ; --- ; 24 ; === ; Fruehes Inaktivierung des Einganges, Fehler bei Eingang Null ; PH3b: ; (12) delay3(1) ; 3 delay2 ; 2 rjmp PH2e ; 2 ; ; Phase IV: Eingang ist Eins fuer cMin1 Schleifen, starte Toleranzzeit ; PH4: ;(14) delay4(2) ; 8 ldi rtry,cTlp ; 1 ldi rctr,cstep; 1 ; --- ; 24 ; === ; Warte fuer Toleranzzeit oder auf inaktiven Eingang ; PH4a: macpwm ; 9 9 9 sbis PinB,bIn ; 2 2 1 rjmp PH7 ; 2 dec rtry ; 1 1 breq PH5 ; 1 2 delay3(3) ; 9 rjmp PH4a ; 2 ; --- ; 24 ; === ; ; Phase V: Ende der Toleranzzeit, beginne Abwaertszaehlung ; PH5: ; (14) delay4(2) ; 8 delay2 ; 2 ; --- ; 24 ; === PH5a: macpwm ; 9 9 9 sbis PinB,bIn ; 2 2 1 rjmp PH7 ; 2 dec rctr ; 1 1 breq PH6 ; 1 2 delay3(3) ; 9 rjmp PH5a ; 2 ; --- ; 24 ; === ; Phase VI: Ende des Abwaertszaehlens, toleriere Nachlaufzeit ; PH6: ; (14) delay3(3) ; 9 ldi rtry,cTla ; 1 ; --- ; 24 ; === ; Zeitueberlauf nach cTla Schleifen, beende bei Ueberlauf oder inaktiv ; PH6a: macpwm ; 9 9 9 sbis PinB,bIn ; 2 2 1 rjmp PH7 ; 2 dec rtry ; 1 1 breq PH6b ; 1 2 delay3(3) ; 9 rjmp PH6a ; 2 ; --- ; 24 ; === ; Aktives Signal zu lang, Fehlerbedingung mit aktivem Eingang ; PH6b: ; (14) delay3(1) ; 3 rjmp PH1d ; 2 ; ; Phase VII: Eingang inaktiv, pruefe auf ausreichende inaktive Zeit ; ; PH7: ; (12) delay4(2) ; 8 delay2 ; 2 ldi ZL,LOW(cMin0); 1 ldi ZH,HIGH(cMin0); 1 ; --- ; 24 ; === PH7a: macpwm ; 9 9 9 sbic PinB,bIn ; 2 2 1 rjmp PH7b ; 2 sbiw ZL,1 ; 2 2 breq PH7c ; 1 2 delay4(2) ; 8 rjmp PH7a ; 2 ; --- ; 24 ; === ; Fruehzeitiges Ende der Signalpause, Fehlerbedingung bei inaktivem Eingang ; PH7b: ; (12) delay3(1) ; 3 delay2 ; 2 rjmp PH1d ; 2 ; ; Ende der Mindestdauer des inaktiven Signals, setze neuen Messwert ; PH7c: ; (15) mov rpwn,rctr ; 1 ldi rerr,cFbck; 1 lederroff ; 2 delay1 ; 1 rjmp PH2b ; 2 ; ; Ende des Programmes ;