- LiTime Speicher und Akkus         
Ergebnis 1 bis 8 von 8

Thema: ATtiny13A: HESUNSE (CY800) Funksteckdosenprotokoll auswerten

  1. #1
    Erfahrener Benutzer Roboter-Spezialist Avatar von Bernd_Stein
    Registriert seit
    19.09.2008
    Ort
    Deutschland : Nordrhein-Westfalen ( NRW )
    Alter
    53
    Beiträge
    407

    ATtiny13A: HESUNSE (CY800) Funksteckdosenprotokoll auswerten

    Anzeige

    LiFePo4 Akku selber bauen - Video
    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/in...=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:
    Code:
    ;
    ;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
    ; Headerdatei
    ;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
    ;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 ).
    ;
    ;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
    ; Einbinden der Controllerspezifischen Definitionsdatei
    ;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
    ;
    .NOLIST                 ;List-Output ausschalten
    ;.INCLUDE "tn13Adef.inc"  ;AVR-Definitionsdatei einbinden
    .LIST                   ;List-Output wieder einschalten
    ;
    ;RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
    ;RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
    ; Arbeitsregister umbenennen
    ;RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
    ;RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
    ;
    .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
    ;
    ;KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
    ;KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
    ; Konstanten als Symbole
    ;KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
    ;KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
    ;
    .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:
    Code:
    ;
    .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
    ;
    ;IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
    ;IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
    ;I Erstinitialisierungen
    ;IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
    ;IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
    ;
    _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
    ;
    ;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
    ;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
    ;H Hauptprogrammschleife
    ;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
    ;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
    ;
    _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
    ; 
    ;UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
    ;UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
    ;U Beginn der verwendeten Unterprogramme
    ;UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
    ;UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
    ;
    .include "UP.inc";Unterprogramme
    ;
    ;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
    ;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
    ;Q Beginn der verwendeten Interrupt Service Routinen ( ISR )
    ;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
    ;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
    ;
    .include "ISR.inc"          ;Interrupt Service Routinen
    ;
    ;KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
    ;KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
    ;K Beginn der Programmkonstanten
    ;KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
    ;KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
    ;
    _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:
    Code:
    ;
    ;*******************************************************************************
    ;* 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 ):

    Code:
    ;
    ;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
    ; Interruptvektortabelle des ATtiny13 Mikrocontrollers
    ;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
    ;
    ; ***** 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 ):
    Code:
    ; 
    ;UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
    ;UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
    ;U Beginn der verwendeten Unterprogramme
    ;UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
    ;UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
    ;
    _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 ):
    Code:
    ; 
    ;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
    ;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
    ;Q Beginn der verwendeten Interrupt Service Routinen ( ISR )
    ;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
    ;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
    ;
    ;
    ;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
    ; INTERRUPT REQUEST 0 INT0 
    ;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
    ;
    _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
    ;
    ;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
    ; PIN CHANGE INTERRUPT 0
    ;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
    ;
    _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
    ;
    ;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
    ; Timer/Counter0 Compare Match A ISR ( Interrupt Service Routine )
    ;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
    ;
    _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
    CRS Robotics A255, TRONXY X3A, TinkerCAD, c´t-Lab, ProfiLab Expert, AVR8 Assembler

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von Searcher
    Registriert seit
    07.06.2009
    Ort
    NRW
    Beiträge
    1.702
    Blog-Einträge
    133
    Zitat Zitat von Bernd_Stein Beitrag anzeigen
    Das 1te Bit lese ich nach 550µs ein und alle weiteren im Abstand von 1100µs.
    Hallo,

    ich kann das Timing im Programm nicht nachvollziehen.

    Im Unterprogramm _loeschen wird der 4,8MHz Systemtakt durch 8 geteilt und OCR0A mit 66 beschrieben.
    Da der Timer mit prescaler 1:1 läuft, bedeutet das zu diesem Zeitpunkt ein Timer0 Comparematch nach 111µs wenn er bei 0 beginnt ( 4,8MHz/ 8 =600kHz. (1/600kHz)*(66+1) = 111µs )

    In der INT0 ISR wird mit CLKPS2 der 4,8MHz Systemtakt durch 16 geteilt (SYSCLK=300kHz), daß dann ein Comparematch in Timer0 nach der doppelten Zeit, also nach 222µs auslösen würde.

    In der PCINT ISR wird Timer0 im CTC gestartet aber OCR0A nicht neu gesetzt; Inhalt immer noch 66. Der erste Comparematch findet demnach nach 222µs statt, nicht nach 550µs!?

    In der Comparematch A ISR wird dann 192 in das OCR0A geladen. Das macht bei 300kHz dann eine Zeit von (1/300kHz)*(192+1) = 643µs und keine 1100µs.

    Kann auch sein, das ich den Faden durch die ganzen Umtaktungen verloren habe.

    Abstände von 1100µs, Werte zwischen 1092µs und 1098µs annehmen

    1. könnte der Systemtakt nicht 100%ig stimmen und
    2. Wenn der µC mit 300kHz läuft, dauert ein Cycle 3,33µs. Bei Branch- oder Test
    befehlen kommen da schnell 6µs Unterschiede je nach Ergebnis zustande. Müßte man aber nochmal genauer betrachten.

    Dort bitte auf die XYZ.jpg Datei klicken um den Screenshot zu sehen :
    https://www.edv-dompteur.de/forum/in...=4113#post4113
    Ich finde die XYZ.jpg zum Verr... nicht. Ich will auch nicht mehr danach suchen!


    Gruß
    Searcher
    Hoffentlich liegt das Ziel auch am Weg
    ..................................................................Der Weg zu einigen meiner Konstruktionen

  3. #3
    Erfahrener Benutzer Roboter-Spezialist Avatar von Bernd_Stein
    Registriert seit
    19.09.2008
    Ort
    Deutschland : Nordrhein-Westfalen ( NRW )
    Alter
    53
    Beiträge
    407

    CY800-Funksteckdosenempfänger: Programmbesprechung

    Zitat Zitat von Searcher Beitrag anzeigen

    Ich finde die XYZ.jpg zum Verr... nicht. Ich will auch nicht mehr danach suchen!
    Sorry, XYZ sollte als Platzhalter für die richtigen Namen der zwei Screenshots stehen :

    https://www.edv-dompteur.de/forum/index.php?page=Thread&postID=4113#post4113


    Zitat Zitat von Searcher Beitrag anzeigen
    Im Unterprogramm _loeschen wird der 4,8MHz Systemtakt durch 8 geteilt und OCR0A mit 66 beschrieben.
    Da der Timer mit prescaler 1:1 läuft, bedeutet das zu diesem Zeitpunkt ein Timer0 Comparematch nach 111µs wenn er bei 0 beginnt ( 4,8MHz/ 8 =600kHz. (1/600kHz)*(66+1) = 111µs )
    Ich freue mich, dass du da durchblickst. Ja, soweit stimmt alles.
    Nur ist der interne RC-Oszillator bei mir dermaßen ungenau, dass er statt mit den 600kHz mit ca. 410kHz läuft, wie man im Scrennshot zum 1ten Bit sehen kann ( 550µs ).



    Zitat Zitat von Searcher Beitrag anzeigen
    In der INT0 ISR wird mit CLKPS2 der 4,8MHz Systemtakt durch 16 geteilt (SYSCLK=300kHz), daß dann ein Comparematch in Timer0 nach der doppelten Zeit, also nach 222µs auslösen würde.
    In der PCINT ISR wird Timer0 im CTC gestartet aber OCR0A nicht neu gesetzt; Inhalt immer noch 66. Der erste Comparematch findet demnach nach 222µs statt, nicht nach 550µs!?
    Jaaa... nicht ganz, aber auch hier wieder den ungenauen RC-Oszillator beachten. Die 300kHz werden bereits in der INT0-ISR eingestellt und gelten somit für die darauf folgende PCI0-IRQ und schließlich immer für die OC0A-IRQ.
    Hier kommt der Trick, denn dass 1te Bit wird wirklich noch mit OCR0A=66 bei 300kHz in der OC0A-ISR erfasst, aber für die restlichen 23 Bits wird OCR0A=192 am Ende der OC0A-ISR gesetzt, so dass diese dann alle 1100µs erfasst werden ( siehe anderen Screenshot ).

    Nur eben nicht immer genau im gleichen Abstand, obwohl immer Haargenau die gleichen Codeabläufe stattfinden, was mich ja verwundert.
    Diese Werte für OCR0A wurden experimentell ermittelt, so dass es mit den 550µs und 1100µs passte.


    Bernd_Stein








    CRS Robotics A255, TRONXY X3A, TinkerCAD, c´t-Lab, ProfiLab Expert, AVR8 Assembler

  4. #4
    Erfahrener Benutzer Robotik Einstein Avatar von Searcher
    Registriert seit
    07.06.2009
    Ort
    NRW
    Beiträge
    1.702
    Blog-Einträge
    133
    Zitat Zitat von Bernd_Stein Beitrag anzeigen
    Nur ist der interne RC-Oszillator bei mir dermaßen ungenau, dass er statt mit den 600kHz mit ca. 410kHz läuft, wie man im Scrennshot zum 1ten Bit sehen kann ( 550µs ).

    .....

    Jaaa... nicht ganz, aber auch hier wieder den ungenauen RC-Oszillator beachten. Die 300kHz werden bereits in der INT0-ISR eingestellt und gelten somit für die darauf folgende PCI0-IRQ und schließlich immer für die OC0A-IRQ.
    Hallo Bernd,

    irgendetwas stimmt da nicht. Der PCINT tritt auf, wenn sich an Data was tut. Zu dem Zeitpunkt ist OCR0A mit dem Wert 66 geladen und der Systemtakt auf 1/16 in INT0 mit CLKPS2 gestellt (die theoretischen 300kHz). In der PCINT ISR wird dann der TIMER0 gestartet und soll damit eine Zeit von 550µs bis CTC Comparematch machen? oder wo soll man die 410kHz im Screenshot ablesen?

    550µs/(66+1) = 8,2µs für einen Timerstep. Der Timer wird also mit 1/8,2µs=121,951kHz getaktet.
    Wegen 1/16 ist der Systemtakt = 16*121,951kHz= 1,951219MHz und nicht die theoretischen 4,8MHz. (Dann komme ich aber statt 1100µs aber auf über 1500µs bei OCR0A = 192 und 1/16 SYSCLK)

    Läuft der Timer mit 1/8 SYSCLK wären das 1,951219MHz/8 = 243,902kHz und nicht 410kHz.

    Bitte überprüfen und/oder Korrekturrechnung bzw jetzt genau mal den SYSCLK explizit über zB OC0A toggle messen. Ist der Systemtakt stabil? Ist die Stromversorgung stabil und sauber?

    Der µC geht zwischen den Comparematch Interrups immer wieder in den Idle Sleep. Laß ihn doch mal durchlaufen ohne Sleep. Sind die Zeiten dann konstanter?

    Die Diskrepanz von 4,8Mhz zu 1,9Mhz ist arg. Vielleicht mal einen neuen µC probieren?

    Gruß
    Searcher

    PS und das auf 0 Setzen des TCNT0 in der Comparematch ISR ist doch eigentlich nicht nötig. Der Timer ist doch auf Comparematch eingestellt. Es reicht das OCR0A beim ersten Mal auf 192 zu stellen und von mir aus jedes Mal. Rücksetzen von TCNT0 an der Stelle verkompliziert die Berechnung, da ja die Zeit von Aufruf der ISR bis Rücksetzten des Timers ja uach noch verrechnet werden muß.
    Geändert von Searcher (05.05.2020 um 20:00 Uhr) Grund: TCNT nicht immer Rücksetzen
    Hoffentlich liegt das Ziel auch am Weg
    ..................................................................Der Weg zu einigen meiner Konstruktionen

  5. #5
    Erfahrener Benutzer Roboter-Spezialist Avatar von Bernd_Stein
    Registriert seit
    19.09.2008
    Ort
    Deutschland : Nordrhein-Westfalen ( NRW )
    Alter
    53
    Beiträge
    407

    LA Screenshot : Anfang erklärt

    Zitat Zitat von Searcher Beitrag anzeigen

    ...
    In der PCINT ISR wird dann der TIMER0 gestartet und soll damit eine Zeit von 550µs bis CTC Comparematch machen? oder wo soll man die 410kHz im Screenshot ablesen?

    Die 410kHz hatte ich mal mit dieser Codesequenz und dem DSO ermittelt und den SYS-Takt dann ausgerechnet :
    Code:
    
    sbi    PINB,led.pla                ;Systemtakt ->  Gemessene Frequenz..
    rjmp pc-1                           ;..mal 8  nehmen 
    

    Jetzt nicht verzagen, der Screenshot wird ja im Detail erklärt :

    https://www.edv-dompteur.de/forum/in...=4148#post4148

    Ab ca. 420µs ( blauer senkrechter Strich ) geht die Aufzeichnung mit der fallenden Flanke des Monoflops los ( 1% davor wird auch noch erfasst ).


    Irgendwann wird dann die INT0 Low-Level IRQ erzeugt.
    Am Anfang der INT0-ISR wird der erste Impuls mit LED-Gelb erzeugt. Dieser ist 4,958µs lang und entspricht somit einer Frequenz von 403,388kHz, was eigentlich die nominalen 600kHz sind ( 4,958µs:2 wegen sbi, cbi ).

    Am Ende der INT0-ISR ist der SYS-Takt ja bereits auf nominal 300kHz umgestellt und somit der 2te Impuls bei LED-Gelb 9,875µs lang, was der wahren Frequenz von 202,532kHz entspricht.

    Die Pulse an LED-Orange lass ich jetzt erstmal raus damit es nicht zu umfangreich wird.


    Dann kommt es an IN/Data ( PB0 bzw. PCINT0 ) zu der steigenden Flanke. Hier wird leider durch dass Schattenmessfenster der Marker für Bit 1 bei +1310µs überblendet, deshalb habe ich dies selbst beschriftet. Der Messwert zeigt 549,375µs an. Die 1,098ms sind der Abstand zu Bit 2.

    Die PCI0-ISR habe ich zu Anfang und zu Ende durch zwei Impulse kenntlich gemacht.

    Meine ganzen Zeitangaben beziehen sich also auf Messungen im Logic Analyser Programm.



    Zitat Zitat von Searcher Beitrag anzeigen

    ...
    Ist der Systemtakt stabil? Ist die Stromversorgung stabil und sauber?

    Der µC geht zwischen den Comparematch Interrups immer wieder in den Idle Sleep. Laß ihn doch mal durchlaufen ohne Sleep. Sind die Zeiten dann konstanter?
    Zitat Zitat von Searcher Beitrag anzeigen
    Die Diskrepanz von 4,8Mhz zu 1,9Mhz ist arg. Vielleicht mal einen neuen µC probieren?


    Ok, wird aber dauern bis ich davon berichte.

    Zitat Zitat von Searcher Beitrag anzeigen
    PS und das auf 0 Setzen des TCNT0 in der Comparematch ISR ist doch eigentlich nicht nötig. Der Timer ist doch auf Comparematch eingestellt. Es reicht das OCR0A beim ersten Mal auf 192 zu stellen und von mir aus jedes Mal. Rücksetzen von TCNT0 an der Stelle verkompliziert die Berechnung, da ja die Zeit von Aufruf der ISR bis Rücksetzten des Timers ja uach noch verrechnet werden muß.

    Hatte ich mal gemacht, da aber das Timming wieder nicht stimmte habe ich es wieder reingenommen und die zwei Takte stören bisher auch nicht.
    Und wie bereits geschrieben, rechne ich da gar nichts aus, sondern habe die Werte für das OCR0A-Register durch experimentieren gefunden, da sämtliche Rechnungen irgendwie nicht hinhauten.


    Bernd_Stein
    CRS Robotics A255, TRONXY X3A, TinkerCAD, c´t-Lab, ProfiLab Expert, AVR8 Assembler

  6. #6
    Erfahrener Benutzer Robotik Einstein Avatar von Searcher
    Registriert seit
    07.06.2009
    Ort
    NRW
    Beiträge
    1.702
    Blog-Einträge
    133
    Zitat Zitat von Bernd_Stein Beitrag anzeigen
    Irgendwann wird dann die INT0 Low-Level IRQ erzeugt.
    Am Anfang der INT0-ISR wird der erste Impuls mit LED-Gelb erzeugt. Dieser ist 4,958µs lang und entspricht somit einer Frequenz von 403,388kHz, was eigentlich die nominalen 600kHz sind ( 4,958µs:2 wegen sbi, cbi ).

    Am Ende der INT0-ISR ist der SYS-Takt ja bereits auf nominal 300kHz umgestellt und somit der 2te Impuls bei LED-Gelb 9,875µs lang, was der wahren Frequenz von 202,532kHz entspricht.
    Klingt plausibel. Vielleicht bringt der idle mode meine Rechnung so durcheinander. Damit hab ich kaum Erfahrung. Wer weiß, was der für Zeiten auch beim Aufwachen braucht. Im DB finde ich dazu nicht wirklich was Konkretes. Am Einfachsten mal den Sleep überhaupt nicht verwenden und das Timing (OCR0A Werte) entsprechend anpassen.

    Hab sonst keine Idee mehr. In Assembler sollte der Programmablauf schon taktgenau nachvollzogen werden können

    Gruß
    Searcher

    PS: Trotzdem könnte man den Takt nachmessen und mit Oszi schauen, ob er nicht jittert oder schwankt. Hab das kürzlich bei einem Tiny45 über den OC0A gemacht. Man mißt mit folgendem Programm den halben Systemtakt:

    Bascom file zum Takt messen. Sollte leicht auf Deine IDE für Tiny13 anpaßbar sein.
    Code:
    $regfile = "attiny45.dat"
    $framesize = 10
    $swstack = 10
    $hwstack = 10
    $crystal = 1000000
    
    
    $asm
      ;OCR0A vom System auf 0
      sbi ddrb , 0            ;PB0 (OC0A) auf Ausgang stellen
      ldi r16 , &B0100_0010   ;COM0A0 (toggle OC0A), WGM01 (CTC mit OCR0A als top)
      out tccr0a , r16        ; ...
      ldi r16 , &b0000_0001   ;CS00 (no Timer prescaling)
      out tccr0b , r16        ;timer0 einschalten
    $end Asm
    Hoffentlich liegt das Ziel auch am Weg
    ..................................................................Der Weg zu einigen meiner Konstruktionen

  7. #7
    Erfahrener Benutzer Roboter-Spezialist Avatar von Bernd_Stein
    Registriert seit
    19.09.2008
    Ort
    Deutschland : Nordrhein-Westfalen ( NRW )
    Alter
    53
    Beiträge
    407
    Hallo,

    möchte nur mal wieder eine kleine Rückmeldung geben, da der Code jetzt geändert wurde und funktioniert. Genaueres werde ich zu einem späteren Zeitpunkt bekannt geben.


    Zitat Zitat von Searcher Beitrag anzeigen


    Klingt plausibel. Vielleicht bringt der idle mode meine Rechnung so durcheinander. Damit hab ich kaum Erfahrung. Wer weiß, was der für Zeiten auch beim Aufwachen braucht. Im DB finde ich dazu nicht wirklich was Konkretes...
    Evtl. habe ich den Grund für die unregelmäßigen Aufrufe der OC0A-ISR gefunden, bin mir aber nicht sicher, da ich dies wiedermal nicht verstehe. Leider ist dieser Teil nicht übersetzt worden und gilt für den ATmega8, was aber nicht das Problem ist ( Siehe dort Systemtakt und Takteinstellungen -> Systemtakt-Vorteiler ) :

    https://www-user.tu-chemnitz.de/~heh.../ATmegaX8.chm/


    " The ripple counter that implements the prescaler runs at the frequency of the undivided clock, which may be faster than the CPU's clock frequency. Hence, it is not possible to determine the state of the prescaler - even if it were readable, and the exact time it takes to switch from one clock division to the other cannot be exactly predicted. From the time the CLKPS values are written, it takes between T1 + T2 and T1 + 2 * T2 before the new clock frequency is active. In this interval, 2 active clock edges are produced. Here, T1 is the previous clock period, and T2 is the period corresponding to the new prescaler setting. "

    " Der Welligkeitszähler, der den Vorteiler implementiert, läuft mit der Frequenz des ungeteilten Takts, die möglicherweise schneller als die Taktfrequenz der CPU ist.
    Daher ist es nicht möglich, den Zustand des Vorteilers zu bestimmen - selbst wenn er lesbar wäre, und die genaue Zeit, die zum Umschalten von einer Taktteilung zur
    anderen benötigt wird, kann nicht genau vorhergesagt werden. Ab dem Zeitpunkt, an dem die CLKPS-Werte geschrieben werden, dauert es zwischen T1 + T2 und T1 + 2 * T2,
    bis die neue Taktfrequenz aktiv ist. In diesem Intervall werden 2 aktive Taktflanken erzeugt. Hier ist T1 die vorherige Taktperiode und T2 die Periode, die der neuen
    Prescaler-Einstellung entspricht. "

    Ist jetzt aber nicht mehr wichtig, da die Periodendauern der einzelnen Elemente ( 0, 1, f, Sync ) auch nicht konstant sind.
    Deshalb war es keine gute Idee immer den gleichen Abstand von Bit zu Bit zu wählen. Hier sieht man dass es bei Bit13 & 19 schon recht knapp wird mit der
    Erkennung des richtigen Pegels.

    https://www.edv-dompteur.de/forum/in...tachmentID=817

    Deshalb habe ich eine neue Strategie ausgearbeitet und bei jeder steigenden Flanke eines Datenelementes einen INT0-IRQ ausgelöst, wo jedesmal der TCNT0 neu geladen wurde.
    Beim Testen habe ich festgestellt, dass Taste B+C gleichzeitig gedrückt, den Code der Taste A wiedergibt. Dies sei nur am Rande erwähnt.


    Bernd_Stein

    CRS Robotics A255, TRONXY X3A, TinkerCAD, c´t-Lab, ProfiLab Expert, AVR8 Assembler

  8. #8
    Erfahrener Benutzer Roboter-Spezialist Avatar von Bernd_Stein
    Registriert seit
    19.09.2008
    Ort
    Deutschland : Nordrhein-Westfalen ( NRW )
    Alter
    53
    Beiträge
    407
    Ich habe mir überlegt, die Sache hier fortzuführen, da ich dort einfach die visuell besseren Möglichkeiten habe :

    https://www.edv-dompteur.de/forum/in...=4200#post4200


    Bernd_Stein
    CRS Robotics A255, TRONXY X3A, TinkerCAD, c´t-Lab, ProfiLab Expert, AVR8 Assembler

Ähnliche Themen

  1. [ERLEDIGT] ATtiny13A: Wo kommt der eine Takt her?
    Von Bernd_Stein im Forum Assembler-Programmierung
    Antworten: 27
    Letzter Beitrag: 03.05.2020, 17:04
  2. [ERLEDIGT] ATtiny13A: Frage(n) zum Register GTCCR
    Von Bernd_Stein im Forum Assembler-Programmierung
    Antworten: 8
    Letzter Beitrag: 01.05.2020, 18:04
  3. [ERLEDIGT] ATtiny13A: Pin Change Interrupt vs. INT0
    Von Bernd_Stein im Forum Assembler-Programmierung
    Antworten: 7
    Letzter Beitrag: 17.04.2020, 17:17
  4. [ERLEDIGT] Empfängersignal mit ATtiny13A erkennen
    Von Lichti01 im Forum Elektronik
    Antworten: 14
    Letzter Beitrag: 24.06.2017, 08:19
  5. Attiny13a RS232
    Von flecralf im Forum C - Programmierung (GCC u.a.)
    Antworten: 1
    Letzter Beitrag: 09.10.2013, 19:27

Stichworte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

LiTime Speicher und Akkus