Pfad:
Home =>
AVR-Übersicht =>
Anwendungen =>
PCM-Decoder => Quellcode
(This page in English:
)
Assembler Quellcode für
den PCM-Dekoder
; *******************************************************************
; * PCM2PWG-Dekoder fuer AT90S2323, Version 0.4 vom 20.12.2000 *
; * Dekodiert PCM Pulse in pulsweitenmoduliertes Rechtecksignal *
; * (C)2000 by info!at!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 "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
;
©2002 by http://www.avr-asm-tutorial.net