Bernd_Stein
03.05.2020, 16:58
Hallo zusammen,
dort ist dass Protokoll zu sehen, wenn die Taste A der Funk-Fernbedienung gedrückt wurde und wie es der vermeindliche CY800-Baustein dann am Data-Ausgang ausgibt.
Das 1te Bit lese ich nach 550µs ein und alle weiteren im Abstand von 1100µs.
Dort bitte auf die XYZ.jpg Datei klicken um den Screenshot zu sehen :
https://www.edv-dompteur.de/forum/index.php?page=Thread&postID=4113#post4113
Ich verstehe nicht warum die kontinuierlichen Abstände von 1100µs, Werte zwischen 1092µs und 1098µs annehmen, wenn doch jedes mal dass Gleiche passiert?
Nämlich aus dem IDLE-Mode per OC0A-IRQ geweckt werden, in die OC0A-ISR springen und danach wieder in den IDLE-Mode usw.
Hier mal der komplette Code. In der Header-Datei steht wie es funktioniert :
Header-Datei:
;
;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH HHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
; Headerdatei
;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH HHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
;Programm CY800_E.ASM
;
;Auswerten eines Funksteckdosen-Protokolls des Bausteins CY800.
;
;Für ATtiny13A mit internem RC-Oszillator 4,8MHz ( 14CK+64 )
;
;FUSE-BITS High = $FF ; Low = $39
;
;Am Pin 5 ( PCINT0 ) wird dass Signal des CY800 eingelesen ( Data )
;Am Pin 6 ( INT0 ) ueber ein retriggerbares Monoflop das Einlesen vorbereitet.
;
;Der µC soll moeglichst stromsparend betrieben werden, deshalb wird er mit ver-
;schiedenen SLEEP-Modes und Systemtakten betrieben. Zu Beginn wird der µC in den
;SLEEP-Mode, PowerDown versetzt.
;
;Da der CY800 immer irgendwelche Signale ausgibt, wird hiermit ein retrigger-
;bares Monoflop ( 8,3ms ) beaufschlagt, was somit die meiste Zeit einen High-
;Pegel erzeugt. Im CY800-Protokoll kommt es nach dem Synchronisationsbit zu
;einer 8,5ms langen Low-Phase, wodurch dass MF nicht mehr nachgetriggert wird
;und es eine Level-Interupt an INT0 erzeugt.
;In dieser INT0-ISR wird nun, unter anderem, die PCINT0-IRQ intialisiert, um den
;Beginn des Datenpaketes zu erfassen. INT0-IRQ wird danach wieder abgeschaltet.
;In der PCINT0-ISR wird unter anderem der Timer/Counter0 Compare Match A IRQ
;initialisiert (OC0A), welcher durch den CTC-Mode erzeugt wird, wo der OC0A-Pin
;als normaler Portpin betrieben wird bzw. als PCINT0-Eingang.
;Hiernach wird ebenfalls der PCINT0-IRQ abgeschaltet.
;In der OC0A-ISR wird dann nach 550µs dass erste Bit eingelesen und alle wei-
;teren 23 Bits mit 1100µs Abstand. In der Mainloop werden die drei eingelesen
;Bytes mit denen im Flash abgelegten ( Tastencode ) verglichen und bei Ueber-
;einstimmung zum Test die LED-ge eingeschaltet ( High-Pegel ).
;
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
; Einbinden der Controllerspezifischen Definitionsdatei
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
;
.NOLIST ;List-Output ausschalten
;.INCLUDE "tn13Adef.inc" ;AVR-Definitionsdatei einbinden
.LIST ;List-Output wieder einschalten
;
;RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR RRRRRRRRRRRRRRRRRRRRRRRRRRRRR
;RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR RRRRRRRRRRRRRRRRRRRRRRRRRRRRR
; Arbeitsregister umbenennen
;RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR RRRRRRRRRRRRRRRRRRRRRRRRRRRRR
;RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR RRRRRRRRRRRRRRRRRRRRRRRRRRRRR
;
.DEF byte_0 = r0 ;Byte0 vom CY800-Paket
.DEF byte_1 = r1 ;Byte1 vom CY800-Paket
.DEF byte_2 = r2 ;Byte2 vom CY800-Paket
.DEF code = r3 ;Wird f. den Codevergleich benoetigt
;.DEF = r4 ;
;.DEF = r5 ;
.DEF vergleichs_zlr = r6 ;Vergleichszaehler f. 3maligen Vergleich
;.DEF = r7 ;
;.DEF = r8 ;
;.DEF = r9 ;
;.DEF = r10 ;
;.DEF = r11 ;
;.DEF = r12 ;
;.DEF = r13 ;
;.DEF = r14 ;
.DEF s_sreg = r15 ;Zum Sichern des Statusregisters ( Nur 1 Takt )
.DEF ia = r16 ;Interrupt Arbeitsregister ia ( Nur in ISR genutzt )
;.DEF ib = r17 ;Interrupt Arbeitsregister ib ( Nur in ISR genutzt )
;.DEF = r18 ;
.DEF flag_reg = r19 ;Allgemeines Flaggen-Register
.DEF bit_zlr = r20 ;CY800 Bitzaehler
;.DEF = r21 ;
;.DEF = r22 ;
;.DEF = r23 ;
.DEF a = r24 ;Register 24 und 25 kann als universelles..
;.DEF b = r25 ;..Doppelregister dienen
;.DEF xl = r26 ;Der X-Zeiger
;.DEF xh = r27 ;..adresse
;.DEF yl= r28 ;
;.DEF yh= r29 ;
;.DEF zl = r30 ;Verwendung als Z-Zeiger, also wie bereits in der..
;.DEF zh = r31 ;..Definitionsdatei von ATMEL angegeben
;
;KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK KKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
;KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK KKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
; Konstanten als Symbole
;KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK KKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
;KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK KKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
;
.EQU #bit_zlr = 24 ;Bitzaehler der empfangenen Bits
.EQU #vergleichs_zlr = 3 ;Die 3 Bytes x mal vergleichen
.EQU #ocr0a = 66 ;Fuer Timer0, CTC-Mode -> TOP-Wert > 58
.EQU #ocr0a_rest = 192 ;Fuer restlichen 23 Bits -> TOP-Wert > 58
;
;
;Bitbezeichner fuer das allgemeine Flaggenregister flag_reg
;
;.equ = 0 ;
;.equ = 1 ;
;.equ = 2 ;
.equ pdm = 3 ;Power-Down-Mode ist erwuenscht
;.equ = 4 ;
.equ fertig = 5 ;CY800 Paket ( 24-Bits ) erfasst
;.equ = 6 ;
;.equ = 7 ;
;
Hauptprogramm:
;
.include "Header.inc" ;Label und Werte Zuweisungen
.include "Hardware.inc" ;Hardware Label Zuweisungen
;
;Programmstart nach RESET ( Interrupt Vektoren Tabelle )
;
.CSEG ;Was ab hier folgt kommt in den FLASH-Speicher
.ORG $0000 ;Programm beginnt an der FLASH-Adresse 0x0000..
rjmp _reset ;..mit der RESET-Vectortabelle
.include "IRQt13.inc" ;Restliche Interrupt Vektortabelle
.ORG INT_VECTORS_SIZE ;Programmadresse nach den ganzen IRQ-Vektoren
;
;IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII IIIIIIIIIIIIIIIIIIIIIIIIIIIII
;IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII IIIIIIIIIIIIIIIIIIIIIIIIIIIII
;I Erstinitialisierungen
;IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII IIIIIIIIIIIIIIIIIIIIIIIIIIIII
;IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII IIIIIIIIIIIIIIIIIIIIIIIIIIIII
;
_reset:
;
;Stapelzeiger initialisieren (fuer Unterprogramme und / oder Interrupts)
;
;ldi a,High(RAMEND) ;RAMEND, also das Ende vom SRAM, ist in der..
;out SPH,a ;..Definitions-datei festgelegt
ldi a,Low (RAMEND) ;Hier reicht ein Byte, weil das...
out SPL,a ;...SRAM nur 64Byte gross ist
rcall _loeschen ;Anfangsbedingungen herstelllen
;
;Ports Erstkonfiguration
;
sbi DDRB,led.pla ;PORT-Bit als Ausgang f. PLA-LED
sbi DDRB,led.ora ;PORT-Bit als Ausgang f. SLEEP-LED
sbi DDRB,led.ge ;PORT-Bit als Ausgang f. TEST-LED
sbi LED_PORT,led.ora ;LED-Orange ausschalten
;
;Variablen initialisieren ( r0-r31 haben unbestimmten Inhalt )
;
clr flag_reg ;Allgemeines Flaggenregister;
sei ;Alle programmierbaren Interrupts freigeben
;
;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH HHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH HHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
;H Hauptprogrammschleife
;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH HHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH HHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
;
_main:
;
;SLEEP-Mode ausschalten und auf Werkseinstellung setzen
;
in a,MCUCR ;MCU Control Register laden und..
cbr a,1<<SE|1<<SM1|1<<SM0 ;..auf Werkseinstellung..
out MCUCR,a ;..setzen
sbrc flag_reg,fertig ;CY800-Paket erfasst?
rjmp _fertig ;..JA -> Paket vergleichen
sbrs flag_reg,pdm ;Power-Down-Mode erwuenscht?
rjmp _idle ;Nein -> µC in IDLE-Mode versetzen
;
;SLEEP-MODE -> Power Down
;
cbi PORTB,led.ora ;LED-Orange einschalten T E S T Z W E C K E ###########################
sbi PORTB,led.ora ;LED-Orange ausschalten T E S T Z W E C K E ###########################
cbi PORTB,led.ora ;LED-Orange einschalten T E S T Z W E C K E ###########################
in a,MCUCR ;MCU Control Register laden..
sbr a,1<<SE|1<<SM1 ;..Power-Down-Mode und Sleep Enable vorbereiten..
out MCUCR,a ;..und freigeben
sleep ;µC in den Schlaf-Modus versetzen
rjmp _main ;Arbeitsschleife ausfuehren
;
;SLEEP-MODE -> IDLE
;
_idle:
sbi PORTB,led.ora ;LED Orange ausschalten T E S T Z W E C K E ###########################
cbi PORTB,led.ora ;LED-Orange einschalten T E S T Z W E C K E ###########################
sbi PORTB,led.ora ;LED-Orange ausschalten T E S T Z W E C K E ###########################
in a,MCUCR ;MCU Control Register laden(IDLE ist vorgegeben)..
sbr a,1<<SE ;..Sleep Enable vorbereiten..
out MCUCR,a ;..und freigeben
sleep
rjmp _main ;Arbeitsschleife ausfuehren
;
;Der Code stimmt nicht
;
_gescheitert:
cbi LED_PORT,led.pla ;LED-PLA ausschalten T E S T Z W E C K E #############################
sbi LED_PORT,led.pla ;LED-PLA einschalten T E S T Z W E C K E #############################
cbi LED_PORT,led.pla ;LED-PLA ausschalten T E S T Z W E C K E #############################
sbi LED_PORT,led.pla ;LED-PLA einschalten T E S T Z W E C K E #############################
cbi LED_PORT,led.pla ;LED-PLA ausschalten T E S T Z W E C K E #############################
rcall _loeschen ;..Bytes sind ungleich, also alles von vorn
rjmp _main ;Arbeitsschleife ausfuehren
;
;CY800-Paket vergleichen
;
_fertig:
lpm code,Z+ ;Code-Byte2 laden und Zeiger inkrementieren..
cp code,byte_2 ;..beide Bytes vergleichen..
brne _gescheitert ;Der Code stimmt nicht -> springen
lpm code,Z+ ;Code-Byte1 laden und Zeiger inkrementieren..
cp code,byte_1 ;..beide Bytes vergleichen..
brne _gescheitert ;Der Code stimmt nicht -> springen
lpm code,Z ;Code-Byte0 laden..
cp code,byte_0 ;..beide Bytes vergleichen..
brne _gescheitert ;Der Code stimmt nicht -> springen
;tst vergleichs_zlr ;3 maliger Vergleichen der 3 Bytes positiv?
breq _umschalten ;JA -> Ausgang Umschalten
dec vergleichs_zlr ;Vergleichszaehler dekrementieren
rcall _loeschen ;Neubeginn einrichten
rjmp _main ;Arbeitsschleife ausfuehren
;
;Ausgang Umschalten
;
_umschalten:
sbi LED_PORT,led.pla ;LED-PLA einschalten T E S T Z W E C K E #############################
rcall _loeschen ;Neubeginn einrichten
rjmp _main ;Arbeitsschleife ausfuehren
;
;UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU UUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
;UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU UUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
;U Beginn der verwendeten Unterprogramme
;UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU UUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
;UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU UUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
;
.include "UP.inc";Unterprogramme
;
;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
;Q Beginn der verwendeten Interrupt Service Routinen ( ISR )
;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
;
.include "ISR.inc" ;Interrupt Service Routinen
;
;KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK KKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
;KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK KKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
;K Beginn der Programmkonstanten
;KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK KKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
;KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK KKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
;
_code:
.DB $C3,$50,$43,00 ;3 Codebytes f. Taste A ( Byte2,Byte1,Byte0 )
;.DB $FC,$00,$00,00 ;3 Codebytes f. T E S T ( Byte2,Byte1,Byte0 )
.EXIT ;Ende des Quelltextes
Hardware:
;
;************************************************* ******************************
;* Hardware Zuweisungen
;************************************************* ******************************
;
;.EQU XTAL = 1843200 ;Quarzfrequenz in Hertz
.EQU LED_PIN = PINB ;Eingabeport an dem die LED angeschlossen ist
.EQU LED_DDR = DDRB ;Datenrichtungsregister fuer die LED
.EQU LED_PORT = PORTB ;Ausgabeport fuer die Programmlaufanzeige-LED
.EQU cy800.data = PB0 ;Pin Dataausgang vom CY800
.EQU led.ge = PB2 ;Pin an dem die LED-Gelb angeschlossen ist
.EQU led.ora = PB3 ;Pin an dem die LED-Orange angeschlossen ist
.EQU led.pla = PB4 ;Pin wo die LED-ProgrammLaufAnzeige dran ist
.EQU CY800_PIN = PINB ;CY800 Eingabeport
.EQU PIN_PLA = PINB ;Eingabeport wo die LED-ProgrammLaufAnzeige ist
IRQt13 ( Interrupt Vektortabelle ):
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV VVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
; Interruptvektortabelle des ATtiny13 Mikrocontrollers
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV VVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; ***** INTERRUPT VECTORS ************************************************
rjmp _INT0addr ; External Interrupt 0
rjmp _PCI0addr ; External Interrupt Request 0
reti ;rjmp _OVF0addr ; Timer/Counter0 Overflow
reti ;rjmp _ERDYaddr ; EEPROM Ready
reti ;rjmp _ACIaddr ; Analog Comparator
rjmp _OC0Aaddr ; Timer/Counter Compare Match A
reti ;rjmp _OC0Baddr ; Timer/Counter Compare Match B
reti ;rjmp _WDTaddr ; Watchdog Time-out
reti ;rjmp _ADCCaddr ; ADC Conversion Complete
UP's ( Unterprogramme ):
;
;UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU UUUUUUUUUUUUUUUUUUUUUUUUUUUUU
;UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU UUUUUUUUUUUUUUUUUUUUUUUUUUUUU
;U Beginn der verwendeten Unterprogramme
;UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU UUUUUUUUUUUUUUUUUUUUUUUUUUUUU
;UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU UUUUUUUUUUUUUUUUUUUUUUUUUUUUU
;
_loeschen:
;
;Systemtakt ( 4,8MHz ) durch 8 teilen ( 600kHz = 1,666µs )
;
ldi ia,1<<CLKPCE ;Im Clock Prescaler Register Bit..
out CLKPR,ia ;..Clock Prescaler Change Enable setzen..
ldi ia,1<<CLKPS1|1<<CLKPS0;..und CLKPS[3:0] loeschen (Sicherheitsprozedur)..
out CLKPR,ia ;..nun mit CLKPCE=0 und CLKPS[3:0] SYS-Takt aendern
;
;Die drei Bytes loeschen
;
clr byte_2 ;Die 3..
clr byte_1 ;..Bytes..
clr byte_0 ;..loeschen
;
;Bitzaehler einstellen
;
ldi a,#bit_zlr ;Wert f. Bitzaehler laden..
mov bit_zlr,a ;..und Bitzaehler einstellen
;
;Vergleichszaehler einstellen
;
ldi a,#vergleichs_zlr ;..Vergleichszaehler..
mov vergleichs_zlr,a ;..laden
;
;Codeadresse fuer Taste A laden
;
ldi zh,high(_code*2) ;Z-Zeiger mit Vergleichscode-Adresse..
ldi zl,low (_code*2) ;..laden
;
;Job-FLAGS bearbeiten
;
cbr flag_reg,1<<fertig ;CY800 Paket erfasst FLAG loeschen
sbr flag_reg,1<<pdm ;Power-Down-Mode FLAG setzen
;
;INT0 Low-Level-interrupt initialisieren
;
cli ;Global Interrupts sperren
ldi a,1<<INTF0 ;External Interrupt Flag 0 im..
out GIFR,a ;General Interrupt Flag Register loeschen
in a,GIMSK ;General Interrupt Mask Register laden..
sbr a,1<<INT0 ;..und External Interrupt Request 0 freigeben..
out GIMSK,a ;..zurueckschreiben
sei ;Globale Interruptfreigabe
;
;OCR0A fuer dass 1te Bit einstellen
;
ldi ia,#ocr0a ;Wert f. Timer0 CTC-Mode Compare Match A laden und..
out OCR0A,ia ;..ins Output Compare0 Match A Register schreiben
ret ;UP_loeschen verlassen
ISR ( Interrupt Service Programme ):
;
;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ QQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ QQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
;Q Beginn der verwendeten Interrupt Service Routinen ( ISR )
;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ QQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ QQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
;
;
;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ QQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
; INTERRUPT REQUEST 0 INT0
;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ QQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
;
_INT0addr:
sbi LED_PORT,led.ge ;LED-Gelb einschalten T E S T Z W E C K E #############################
cbi LED_PORT,led.ge ;LED-Gelb ausschalten T E S T Z W E C K E #############################
in s_sreg,SREG ;CPU-Statusregister sichern
;
;Pin Change Interrupt 0 -> PCI0 initialisieren
;
in ia,PCMSK ;Pin Change Mask Register laden und..
sbr ia,1<<PCINT0 ;..Pin Change Interrupt 0 auswaehlen
out PCMSK,ia ;..und Register ueberschreiben
in ia,GIMSK ;General Interrupt Masken Register laden und..
sbr ia,1<<PCIE ;..Pin Change Interruput 0 Freigabebit setzen..
out GIMSK,ia ;..INT0 Interrupt freigeben und..
ldi ia,1<<PCIF ;..Pin Change Interrupt Flag..
out GIFR,ia ;..loeschen
;
;INT0 Interrupt sperren
;
in ia,GIMSK ;General Interrupt Mask Register laden..
cbr ia,1<<INT0 ;..INT0 Interrupt sperren vorbereiten und..
out GIMSK,ia ;..ausfuehren..
;
;Systemtakt ( 4,8MHz ) durch 16 teilen ( 300kHz = 3,333µs )
;
ldi a,1<<CLKPCE ;Im Clock Prescaler Register Bit..
out CLKPR,a ;..Clock Prescaler Change Enable setzen..
ldi a,1<<CLKPS2 ;..Sicherheitsprozedur nun mit CLKPCE=0 und
out CLKPR,a ;..CLKPS[3:0] SYS-Takt aendern, abschliessen
_exit_INT0addr:
out SREG,s_sreg ;Statusregister restaurieren
sbi LED_PORT,led.ge ;LED-Gelb einschalten T E S T Z W E C K E #############################
cbi LED_PORT,led.ge ;LED-Gelb ausschalten T E S T Z W E C K E #############################
reti ;_INT0addr ISR verlassen
;
;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ QQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
; PIN CHANGE INTERRUPT 0
;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ QQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
;
_PCI0addr:
sbi LED_PORT,led.ge ;LED-Gelb einschalten T E S T Z W E C K E #############################
cbi LED_PORT,led.ge ;LED-Gelb ausschalten T E S T Z W E C K E #############################
sbi LED_PORT,led.ge ;LED-Gelb einschalten T E S T Z W E C K E #############################
cbi LED_PORT,led.ge ;LED-Gelb ausschalten T E S T Z W E C K E #############################
in s_sreg,SREG ;CPU-Statusregister sichern
;
;Timer0 ruecksetzen
;
clr ia
out TCNT0,ia
;
;Timer/Counter0 im Waveform Generation Mode 2 -> CTC betreiben
;und Compare Match A interrupt initialisieren
;
in ia,TIMSK0 ;Timer/Counter0 Masken Register laden und..
sbr ia,1<<OCIE0A ;..T/C0 Output Compare Match A Interrupt enabeln..
out TIMSK0,ia ;..und dies zurueckschreiben
ldi ia,1<<OCF0A ;Output Compare Flag 0 A..
out TIFR0,ia ;..im T/C0 Interrupt Flag Register loeschen
in ia,TCCR0A ;Timer/Counter0 Control Register A laden..
sbr ia,1<<WGM01 ;..Waveform Generations Mode 2 ( CTC ) einstellen..
out TCCR0A,ia ;..und
in ia,TCCR0B ;Timer/Counter0 Control Register B laden..
sbr ia,1<<CS00 ;..Timer0 mit 1:1 Teiler einstellen..
out TCCR0B,ia ;..und starten
;
;PCINT0 Interrupt sperren
;
in ia,GIMSK ;General Interrupt Masken Register laden und..
cbr ia,1<<PCIE ;..Pin Change Interruput 0 Freigabebit loeschen..
out GIMSK,ia ;..INT0 Interrupt freigeben und..
cbr flag_reg,1<<pdm ;Power-Down-Mode sperren
_exit_PCI0addr:
out SREG,s_sreg ;Statusregister restaurieren
sbi LED_PORT,led.ge ;LED-Gelb einschalten T E S T Z W E C K E #############################
cbi LED_PORT,led.ge ;LED-Gelb ausschalten T E S T Z W E C K E #############################
sbi LED_PORT,led.ge ;LED-Gelb einschalten T E S T Z W E C K E #############################
cbi LED_PORT,led.ge ;LED-Gelb ausschalten T E S T Z W E C K E #############################
reti ;_PCI0addr ISR verlassen
;
;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ QQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
; Timer/Counter0 Compare Match A ISR ( Interrupt Service Routine )
;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ QQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
;
_OC0Aaddr:
in s_sreg,SREG ;CPU-Statusregister sichern
sbi LED_PORT,led.pla ;LED-PLA einschalten T E S T Z W E C K E ##############################
cbi LED_PORT,led.pla ;LED-PLA ausschalten T E S T Z W E C K E ##############################
;
;CY800-Bits erfassen
;
sec ;High-Bit vorgeben
sbis CY800_PIN,cy800.data ;CY800 Signalpin = 1 ?..
clc ;..Nein -> Bit = 0 setzen
;
;Bits zusammenfassen
;
rol byte_0 ;Carry-Bit und weitere Bits links rotieren..
rol byte_1 ;Carry-Bit und weitere Bits links rotieren
rol byte_2 ;Carry-Bit und weitere Bits links rotieren..
dec bit_zlr ;Bitzaehler um eins verringern
brne _pla ;Alle 24 Bits erfasst? NEIN -> springen..
;
;Timer/Counter0 Compare Match A Interrupt sperren
;
_bits_erfasst:
in ia,TIMSK0 ;Timer/Counter0 Mask Register laden und..
cbr ia,1<<OCIE0A ;..T/C0 Output Compare Match A Interrupt..
out TIMSK0,ia ;...sperren
;
;CY800-Paket fertig FLAG setzen ( Vergleich in _main: veranlassen )
;
sbr flag_reg,1<<fertig ;CY800-Paket ( 24-Bits ) erfasst
_pla:
;
;Wert fuer den Timer0 CTC-Mode Compare Match speichern ( restlichen 23 Bits )
;
ldi ia,#ocr0a_rest ;Wert f. Timer0 CTC-Mode Compare Match A laden und..
out OCR0A,ia ;..ins Output Compare0 Match A Register schreiben
;
;Timer0 ruecksetzen
;
clr ia
out TCNT0,ia
_exit_OC0Aaddr:
out SREG,s_sreg ;Statusregister restaurieren
reti ;_OC0Aaddr ISR verlassen
Bernd_Stein
dort ist dass Protokoll zu sehen, wenn die Taste A der Funk-Fernbedienung gedrückt wurde und wie es der vermeindliche CY800-Baustein dann am Data-Ausgang ausgibt.
Das 1te Bit lese ich nach 550µs ein und alle weiteren im Abstand von 1100µs.
Dort bitte auf die XYZ.jpg Datei klicken um den Screenshot zu sehen :
https://www.edv-dompteur.de/forum/index.php?page=Thread&postID=4113#post4113
Ich verstehe nicht warum die kontinuierlichen Abstände von 1100µs, Werte zwischen 1092µs und 1098µs annehmen, wenn doch jedes mal dass Gleiche passiert?
Nämlich aus dem IDLE-Mode per OC0A-IRQ geweckt werden, in die OC0A-ISR springen und danach wieder in den IDLE-Mode usw.
Hier mal der komplette Code. In der Header-Datei steht wie es funktioniert :
Header-Datei:
;
;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH HHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
; Headerdatei
;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH HHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
;Programm CY800_E.ASM
;
;Auswerten eines Funksteckdosen-Protokolls des Bausteins CY800.
;
;Für ATtiny13A mit internem RC-Oszillator 4,8MHz ( 14CK+64 )
;
;FUSE-BITS High = $FF ; Low = $39
;
;Am Pin 5 ( PCINT0 ) wird dass Signal des CY800 eingelesen ( Data )
;Am Pin 6 ( INT0 ) ueber ein retriggerbares Monoflop das Einlesen vorbereitet.
;
;Der µC soll moeglichst stromsparend betrieben werden, deshalb wird er mit ver-
;schiedenen SLEEP-Modes und Systemtakten betrieben. Zu Beginn wird der µC in den
;SLEEP-Mode, PowerDown versetzt.
;
;Da der CY800 immer irgendwelche Signale ausgibt, wird hiermit ein retrigger-
;bares Monoflop ( 8,3ms ) beaufschlagt, was somit die meiste Zeit einen High-
;Pegel erzeugt. Im CY800-Protokoll kommt es nach dem Synchronisationsbit zu
;einer 8,5ms langen Low-Phase, wodurch dass MF nicht mehr nachgetriggert wird
;und es eine Level-Interupt an INT0 erzeugt.
;In dieser INT0-ISR wird nun, unter anderem, die PCINT0-IRQ intialisiert, um den
;Beginn des Datenpaketes zu erfassen. INT0-IRQ wird danach wieder abgeschaltet.
;In der PCINT0-ISR wird unter anderem der Timer/Counter0 Compare Match A IRQ
;initialisiert (OC0A), welcher durch den CTC-Mode erzeugt wird, wo der OC0A-Pin
;als normaler Portpin betrieben wird bzw. als PCINT0-Eingang.
;Hiernach wird ebenfalls der PCINT0-IRQ abgeschaltet.
;In der OC0A-ISR wird dann nach 550µs dass erste Bit eingelesen und alle wei-
;teren 23 Bits mit 1100µs Abstand. In der Mainloop werden die drei eingelesen
;Bytes mit denen im Flash abgelegten ( Tastencode ) verglichen und bei Ueber-
;einstimmung zum Test die LED-ge eingeschaltet ( High-Pegel ).
;
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
; Einbinden der Controllerspezifischen Definitionsdatei
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
;
.NOLIST ;List-Output ausschalten
;.INCLUDE "tn13Adef.inc" ;AVR-Definitionsdatei einbinden
.LIST ;List-Output wieder einschalten
;
;RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR RRRRRRRRRRRRRRRRRRRRRRRRRRRRR
;RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR RRRRRRRRRRRRRRRRRRRRRRRRRRRRR
; Arbeitsregister umbenennen
;RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR RRRRRRRRRRRRRRRRRRRRRRRRRRRRR
;RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR RRRRRRRRRRRRRRRRRRRRRRRRRRRRR
;
.DEF byte_0 = r0 ;Byte0 vom CY800-Paket
.DEF byte_1 = r1 ;Byte1 vom CY800-Paket
.DEF byte_2 = r2 ;Byte2 vom CY800-Paket
.DEF code = r3 ;Wird f. den Codevergleich benoetigt
;.DEF = r4 ;
;.DEF = r5 ;
.DEF vergleichs_zlr = r6 ;Vergleichszaehler f. 3maligen Vergleich
;.DEF = r7 ;
;.DEF = r8 ;
;.DEF = r9 ;
;.DEF = r10 ;
;.DEF = r11 ;
;.DEF = r12 ;
;.DEF = r13 ;
;.DEF = r14 ;
.DEF s_sreg = r15 ;Zum Sichern des Statusregisters ( Nur 1 Takt )
.DEF ia = r16 ;Interrupt Arbeitsregister ia ( Nur in ISR genutzt )
;.DEF ib = r17 ;Interrupt Arbeitsregister ib ( Nur in ISR genutzt )
;.DEF = r18 ;
.DEF flag_reg = r19 ;Allgemeines Flaggen-Register
.DEF bit_zlr = r20 ;CY800 Bitzaehler
;.DEF = r21 ;
;.DEF = r22 ;
;.DEF = r23 ;
.DEF a = r24 ;Register 24 und 25 kann als universelles..
;.DEF b = r25 ;..Doppelregister dienen
;.DEF xl = r26 ;Der X-Zeiger
;.DEF xh = r27 ;..adresse
;.DEF yl= r28 ;
;.DEF yh= r29 ;
;.DEF zl = r30 ;Verwendung als Z-Zeiger, also wie bereits in der..
;.DEF zh = r31 ;..Definitionsdatei von ATMEL angegeben
;
;KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK KKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
;KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK KKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
; Konstanten als Symbole
;KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK KKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
;KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK KKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
;
.EQU #bit_zlr = 24 ;Bitzaehler der empfangenen Bits
.EQU #vergleichs_zlr = 3 ;Die 3 Bytes x mal vergleichen
.EQU #ocr0a = 66 ;Fuer Timer0, CTC-Mode -> TOP-Wert > 58
.EQU #ocr0a_rest = 192 ;Fuer restlichen 23 Bits -> TOP-Wert > 58
;
;
;Bitbezeichner fuer das allgemeine Flaggenregister flag_reg
;
;.equ = 0 ;
;.equ = 1 ;
;.equ = 2 ;
.equ pdm = 3 ;Power-Down-Mode ist erwuenscht
;.equ = 4 ;
.equ fertig = 5 ;CY800 Paket ( 24-Bits ) erfasst
;.equ = 6 ;
;.equ = 7 ;
;
Hauptprogramm:
;
.include "Header.inc" ;Label und Werte Zuweisungen
.include "Hardware.inc" ;Hardware Label Zuweisungen
;
;Programmstart nach RESET ( Interrupt Vektoren Tabelle )
;
.CSEG ;Was ab hier folgt kommt in den FLASH-Speicher
.ORG $0000 ;Programm beginnt an der FLASH-Adresse 0x0000..
rjmp _reset ;..mit der RESET-Vectortabelle
.include "IRQt13.inc" ;Restliche Interrupt Vektortabelle
.ORG INT_VECTORS_SIZE ;Programmadresse nach den ganzen IRQ-Vektoren
;
;IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII IIIIIIIIIIIIIIIIIIIIIIIIIIIII
;IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII IIIIIIIIIIIIIIIIIIIIIIIIIIIII
;I Erstinitialisierungen
;IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII IIIIIIIIIIIIIIIIIIIIIIIIIIIII
;IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII IIIIIIIIIIIIIIIIIIIIIIIIIIIII
;
_reset:
;
;Stapelzeiger initialisieren (fuer Unterprogramme und / oder Interrupts)
;
;ldi a,High(RAMEND) ;RAMEND, also das Ende vom SRAM, ist in der..
;out SPH,a ;..Definitions-datei festgelegt
ldi a,Low (RAMEND) ;Hier reicht ein Byte, weil das...
out SPL,a ;...SRAM nur 64Byte gross ist
rcall _loeschen ;Anfangsbedingungen herstelllen
;
;Ports Erstkonfiguration
;
sbi DDRB,led.pla ;PORT-Bit als Ausgang f. PLA-LED
sbi DDRB,led.ora ;PORT-Bit als Ausgang f. SLEEP-LED
sbi DDRB,led.ge ;PORT-Bit als Ausgang f. TEST-LED
sbi LED_PORT,led.ora ;LED-Orange ausschalten
;
;Variablen initialisieren ( r0-r31 haben unbestimmten Inhalt )
;
clr flag_reg ;Allgemeines Flaggenregister;
sei ;Alle programmierbaren Interrupts freigeben
;
;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH HHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH HHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
;H Hauptprogrammschleife
;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH HHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH HHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
;
_main:
;
;SLEEP-Mode ausschalten und auf Werkseinstellung setzen
;
in a,MCUCR ;MCU Control Register laden und..
cbr a,1<<SE|1<<SM1|1<<SM0 ;..auf Werkseinstellung..
out MCUCR,a ;..setzen
sbrc flag_reg,fertig ;CY800-Paket erfasst?
rjmp _fertig ;..JA -> Paket vergleichen
sbrs flag_reg,pdm ;Power-Down-Mode erwuenscht?
rjmp _idle ;Nein -> µC in IDLE-Mode versetzen
;
;SLEEP-MODE -> Power Down
;
cbi PORTB,led.ora ;LED-Orange einschalten T E S T Z W E C K E ###########################
sbi PORTB,led.ora ;LED-Orange ausschalten T E S T Z W E C K E ###########################
cbi PORTB,led.ora ;LED-Orange einschalten T E S T Z W E C K E ###########################
in a,MCUCR ;MCU Control Register laden..
sbr a,1<<SE|1<<SM1 ;..Power-Down-Mode und Sleep Enable vorbereiten..
out MCUCR,a ;..und freigeben
sleep ;µC in den Schlaf-Modus versetzen
rjmp _main ;Arbeitsschleife ausfuehren
;
;SLEEP-MODE -> IDLE
;
_idle:
sbi PORTB,led.ora ;LED Orange ausschalten T E S T Z W E C K E ###########################
cbi PORTB,led.ora ;LED-Orange einschalten T E S T Z W E C K E ###########################
sbi PORTB,led.ora ;LED-Orange ausschalten T E S T Z W E C K E ###########################
in a,MCUCR ;MCU Control Register laden(IDLE ist vorgegeben)..
sbr a,1<<SE ;..Sleep Enable vorbereiten..
out MCUCR,a ;..und freigeben
sleep
rjmp _main ;Arbeitsschleife ausfuehren
;
;Der Code stimmt nicht
;
_gescheitert:
cbi LED_PORT,led.pla ;LED-PLA ausschalten T E S T Z W E C K E #############################
sbi LED_PORT,led.pla ;LED-PLA einschalten T E S T Z W E C K E #############################
cbi LED_PORT,led.pla ;LED-PLA ausschalten T E S T Z W E C K E #############################
sbi LED_PORT,led.pla ;LED-PLA einschalten T E S T Z W E C K E #############################
cbi LED_PORT,led.pla ;LED-PLA ausschalten T E S T Z W E C K E #############################
rcall _loeschen ;..Bytes sind ungleich, also alles von vorn
rjmp _main ;Arbeitsschleife ausfuehren
;
;CY800-Paket vergleichen
;
_fertig:
lpm code,Z+ ;Code-Byte2 laden und Zeiger inkrementieren..
cp code,byte_2 ;..beide Bytes vergleichen..
brne _gescheitert ;Der Code stimmt nicht -> springen
lpm code,Z+ ;Code-Byte1 laden und Zeiger inkrementieren..
cp code,byte_1 ;..beide Bytes vergleichen..
brne _gescheitert ;Der Code stimmt nicht -> springen
lpm code,Z ;Code-Byte0 laden..
cp code,byte_0 ;..beide Bytes vergleichen..
brne _gescheitert ;Der Code stimmt nicht -> springen
;tst vergleichs_zlr ;3 maliger Vergleichen der 3 Bytes positiv?
breq _umschalten ;JA -> Ausgang Umschalten
dec vergleichs_zlr ;Vergleichszaehler dekrementieren
rcall _loeschen ;Neubeginn einrichten
rjmp _main ;Arbeitsschleife ausfuehren
;
;Ausgang Umschalten
;
_umschalten:
sbi LED_PORT,led.pla ;LED-PLA einschalten T E S T Z W E C K E #############################
rcall _loeschen ;Neubeginn einrichten
rjmp _main ;Arbeitsschleife ausfuehren
;
;UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU UUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
;UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU UUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
;U Beginn der verwendeten Unterprogramme
;UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU UUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
;UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU UUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
;
.include "UP.inc";Unterprogramme
;
;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
;Q Beginn der verwendeten Interrupt Service Routinen ( ISR )
;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
;
.include "ISR.inc" ;Interrupt Service Routinen
;
;KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK KKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
;KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK KKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
;K Beginn der Programmkonstanten
;KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK KKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
;KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK KKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
;
_code:
.DB $C3,$50,$43,00 ;3 Codebytes f. Taste A ( Byte2,Byte1,Byte0 )
;.DB $FC,$00,$00,00 ;3 Codebytes f. T E S T ( Byte2,Byte1,Byte0 )
.EXIT ;Ende des Quelltextes
Hardware:
;
;************************************************* ******************************
;* Hardware Zuweisungen
;************************************************* ******************************
;
;.EQU XTAL = 1843200 ;Quarzfrequenz in Hertz
.EQU LED_PIN = PINB ;Eingabeport an dem die LED angeschlossen ist
.EQU LED_DDR = DDRB ;Datenrichtungsregister fuer die LED
.EQU LED_PORT = PORTB ;Ausgabeport fuer die Programmlaufanzeige-LED
.EQU cy800.data = PB0 ;Pin Dataausgang vom CY800
.EQU led.ge = PB2 ;Pin an dem die LED-Gelb angeschlossen ist
.EQU led.ora = PB3 ;Pin an dem die LED-Orange angeschlossen ist
.EQU led.pla = PB4 ;Pin wo die LED-ProgrammLaufAnzeige dran ist
.EQU CY800_PIN = PINB ;CY800 Eingabeport
.EQU PIN_PLA = PINB ;Eingabeport wo die LED-ProgrammLaufAnzeige ist
IRQt13 ( Interrupt Vektortabelle ):
;
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV VVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
; Interruptvektortabelle des ATtiny13 Mikrocontrollers
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV VVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;
; ***** INTERRUPT VECTORS ************************************************
rjmp _INT0addr ; External Interrupt 0
rjmp _PCI0addr ; External Interrupt Request 0
reti ;rjmp _OVF0addr ; Timer/Counter0 Overflow
reti ;rjmp _ERDYaddr ; EEPROM Ready
reti ;rjmp _ACIaddr ; Analog Comparator
rjmp _OC0Aaddr ; Timer/Counter Compare Match A
reti ;rjmp _OC0Baddr ; Timer/Counter Compare Match B
reti ;rjmp _WDTaddr ; Watchdog Time-out
reti ;rjmp _ADCCaddr ; ADC Conversion Complete
UP's ( Unterprogramme ):
;
;UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU UUUUUUUUUUUUUUUUUUUUUUUUUUUUU
;UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU UUUUUUUUUUUUUUUUUUUUUUUUUUUUU
;U Beginn der verwendeten Unterprogramme
;UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU UUUUUUUUUUUUUUUUUUUUUUUUUUUUU
;UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU UUUUUUUUUUUUUUUUUUUUUUUUUUUUU
;
_loeschen:
;
;Systemtakt ( 4,8MHz ) durch 8 teilen ( 600kHz = 1,666µs )
;
ldi ia,1<<CLKPCE ;Im Clock Prescaler Register Bit..
out CLKPR,ia ;..Clock Prescaler Change Enable setzen..
ldi ia,1<<CLKPS1|1<<CLKPS0;..und CLKPS[3:0] loeschen (Sicherheitsprozedur)..
out CLKPR,ia ;..nun mit CLKPCE=0 und CLKPS[3:0] SYS-Takt aendern
;
;Die drei Bytes loeschen
;
clr byte_2 ;Die 3..
clr byte_1 ;..Bytes..
clr byte_0 ;..loeschen
;
;Bitzaehler einstellen
;
ldi a,#bit_zlr ;Wert f. Bitzaehler laden..
mov bit_zlr,a ;..und Bitzaehler einstellen
;
;Vergleichszaehler einstellen
;
ldi a,#vergleichs_zlr ;..Vergleichszaehler..
mov vergleichs_zlr,a ;..laden
;
;Codeadresse fuer Taste A laden
;
ldi zh,high(_code*2) ;Z-Zeiger mit Vergleichscode-Adresse..
ldi zl,low (_code*2) ;..laden
;
;Job-FLAGS bearbeiten
;
cbr flag_reg,1<<fertig ;CY800 Paket erfasst FLAG loeschen
sbr flag_reg,1<<pdm ;Power-Down-Mode FLAG setzen
;
;INT0 Low-Level-interrupt initialisieren
;
cli ;Global Interrupts sperren
ldi a,1<<INTF0 ;External Interrupt Flag 0 im..
out GIFR,a ;General Interrupt Flag Register loeschen
in a,GIMSK ;General Interrupt Mask Register laden..
sbr a,1<<INT0 ;..und External Interrupt Request 0 freigeben..
out GIMSK,a ;..zurueckschreiben
sei ;Globale Interruptfreigabe
;
;OCR0A fuer dass 1te Bit einstellen
;
ldi ia,#ocr0a ;Wert f. Timer0 CTC-Mode Compare Match A laden und..
out OCR0A,ia ;..ins Output Compare0 Match A Register schreiben
ret ;UP_loeschen verlassen
ISR ( Interrupt Service Programme ):
;
;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ QQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ QQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
;Q Beginn der verwendeten Interrupt Service Routinen ( ISR )
;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ QQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ QQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
;
;
;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ QQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
; INTERRUPT REQUEST 0 INT0
;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ QQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
;
_INT0addr:
sbi LED_PORT,led.ge ;LED-Gelb einschalten T E S T Z W E C K E #############################
cbi LED_PORT,led.ge ;LED-Gelb ausschalten T E S T Z W E C K E #############################
in s_sreg,SREG ;CPU-Statusregister sichern
;
;Pin Change Interrupt 0 -> PCI0 initialisieren
;
in ia,PCMSK ;Pin Change Mask Register laden und..
sbr ia,1<<PCINT0 ;..Pin Change Interrupt 0 auswaehlen
out PCMSK,ia ;..und Register ueberschreiben
in ia,GIMSK ;General Interrupt Masken Register laden und..
sbr ia,1<<PCIE ;..Pin Change Interruput 0 Freigabebit setzen..
out GIMSK,ia ;..INT0 Interrupt freigeben und..
ldi ia,1<<PCIF ;..Pin Change Interrupt Flag..
out GIFR,ia ;..loeschen
;
;INT0 Interrupt sperren
;
in ia,GIMSK ;General Interrupt Mask Register laden..
cbr ia,1<<INT0 ;..INT0 Interrupt sperren vorbereiten und..
out GIMSK,ia ;..ausfuehren..
;
;Systemtakt ( 4,8MHz ) durch 16 teilen ( 300kHz = 3,333µs )
;
ldi a,1<<CLKPCE ;Im Clock Prescaler Register Bit..
out CLKPR,a ;..Clock Prescaler Change Enable setzen..
ldi a,1<<CLKPS2 ;..Sicherheitsprozedur nun mit CLKPCE=0 und
out CLKPR,a ;..CLKPS[3:0] SYS-Takt aendern, abschliessen
_exit_INT0addr:
out SREG,s_sreg ;Statusregister restaurieren
sbi LED_PORT,led.ge ;LED-Gelb einschalten T E S T Z W E C K E #############################
cbi LED_PORT,led.ge ;LED-Gelb ausschalten T E S T Z W E C K E #############################
reti ;_INT0addr ISR verlassen
;
;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ QQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
; PIN CHANGE INTERRUPT 0
;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ QQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
;
_PCI0addr:
sbi LED_PORT,led.ge ;LED-Gelb einschalten T E S T Z W E C K E #############################
cbi LED_PORT,led.ge ;LED-Gelb ausschalten T E S T Z W E C K E #############################
sbi LED_PORT,led.ge ;LED-Gelb einschalten T E S T Z W E C K E #############################
cbi LED_PORT,led.ge ;LED-Gelb ausschalten T E S T Z W E C K E #############################
in s_sreg,SREG ;CPU-Statusregister sichern
;
;Timer0 ruecksetzen
;
clr ia
out TCNT0,ia
;
;Timer/Counter0 im Waveform Generation Mode 2 -> CTC betreiben
;und Compare Match A interrupt initialisieren
;
in ia,TIMSK0 ;Timer/Counter0 Masken Register laden und..
sbr ia,1<<OCIE0A ;..T/C0 Output Compare Match A Interrupt enabeln..
out TIMSK0,ia ;..und dies zurueckschreiben
ldi ia,1<<OCF0A ;Output Compare Flag 0 A..
out TIFR0,ia ;..im T/C0 Interrupt Flag Register loeschen
in ia,TCCR0A ;Timer/Counter0 Control Register A laden..
sbr ia,1<<WGM01 ;..Waveform Generations Mode 2 ( CTC ) einstellen..
out TCCR0A,ia ;..und
in ia,TCCR0B ;Timer/Counter0 Control Register B laden..
sbr ia,1<<CS00 ;..Timer0 mit 1:1 Teiler einstellen..
out TCCR0B,ia ;..und starten
;
;PCINT0 Interrupt sperren
;
in ia,GIMSK ;General Interrupt Masken Register laden und..
cbr ia,1<<PCIE ;..Pin Change Interruput 0 Freigabebit loeschen..
out GIMSK,ia ;..INT0 Interrupt freigeben und..
cbr flag_reg,1<<pdm ;Power-Down-Mode sperren
_exit_PCI0addr:
out SREG,s_sreg ;Statusregister restaurieren
sbi LED_PORT,led.ge ;LED-Gelb einschalten T E S T Z W E C K E #############################
cbi LED_PORT,led.ge ;LED-Gelb ausschalten T E S T Z W E C K E #############################
sbi LED_PORT,led.ge ;LED-Gelb einschalten T E S T Z W E C K E #############################
cbi LED_PORT,led.ge ;LED-Gelb ausschalten T E S T Z W E C K E #############################
reti ;_PCI0addr ISR verlassen
;
;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ QQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
; Timer/Counter0 Compare Match A ISR ( Interrupt Service Routine )
;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ QQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
;
_OC0Aaddr:
in s_sreg,SREG ;CPU-Statusregister sichern
sbi LED_PORT,led.pla ;LED-PLA einschalten T E S T Z W E C K E ##############################
cbi LED_PORT,led.pla ;LED-PLA ausschalten T E S T Z W E C K E ##############################
;
;CY800-Bits erfassen
;
sec ;High-Bit vorgeben
sbis CY800_PIN,cy800.data ;CY800 Signalpin = 1 ?..
clc ;..Nein -> Bit = 0 setzen
;
;Bits zusammenfassen
;
rol byte_0 ;Carry-Bit und weitere Bits links rotieren..
rol byte_1 ;Carry-Bit und weitere Bits links rotieren
rol byte_2 ;Carry-Bit und weitere Bits links rotieren..
dec bit_zlr ;Bitzaehler um eins verringern
brne _pla ;Alle 24 Bits erfasst? NEIN -> springen..
;
;Timer/Counter0 Compare Match A Interrupt sperren
;
_bits_erfasst:
in ia,TIMSK0 ;Timer/Counter0 Mask Register laden und..
cbr ia,1<<OCIE0A ;..T/C0 Output Compare Match A Interrupt..
out TIMSK0,ia ;...sperren
;
;CY800-Paket fertig FLAG setzen ( Vergleich in _main: veranlassen )
;
sbr flag_reg,1<<fertig ;CY800-Paket ( 24-Bits ) erfasst
_pla:
;
;Wert fuer den Timer0 CTC-Mode Compare Match speichern ( restlichen 23 Bits )
;
ldi ia,#ocr0a_rest ;Wert f. Timer0 CTC-Mode Compare Match A laden und..
out OCR0A,ia ;..ins Output Compare0 Match A Register schreiben
;
;Timer0 ruecksetzen
;
clr ia
out TCNT0,ia
_exit_OC0Aaddr:
out SREG,s_sreg ;Statusregister restaurieren
reti ;_OC0Aaddr ISR verlassen
Bernd_Stein