www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik DCF77 Codesammlung (ASM) funktioniert nicht


Autor: Ich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

ich baue gerade eine DCF77-Uhr mit dem Code aus der Codesammlung 
(http://www.mikrocontroller.net/attachment/highlight/12865), den ich nur 
leicht angepasst habe (am Anfang, und die zwei mit Großbuchstaben und 
!!! markierten Stellen). Der DCF77-Empfänger wird mittels ADC 
ausgemessen, da er eine niedrigere Betriebsspannung hat und nur ein paar 
µA treiben kann. Dabei beachte ich nur die zwei MSB (es ist ja 
eigentlich ein digitales Signal, wird nur nicht erkannt).
Das Problem ist, dass ich zwar an der roten LED das DCF-Signal sehen 
kann, ich habe es auch schon von Hand entschlüsselt. Jedoch lese ich aus 
dem SRAM (in der Hauptschleife hin und wieder mal) nur unsinnige immer 
gleiche Werte aus. Die Stelle an der sich die grüne LED ausschaltet, 
wird auch nach mehreren Minuten Laufzeit nicht erreicht.

Mein Code (in Auszügen):
.include "tn85def.inc"

.equ LEDROT = 0
...
.equ LEDGRUEN = 2
...
.equ DCF77DATA = 4

...

.def dcf77_input = r13
...
.def dcf77_count = r15
.def temp = r16
...
.def dcf77_reg0 = r20
.def dcf77_reg1 = r21
.def dcf77_reg2 = r22
.def dcf77_reg3 = r23

...

.org 0x0000
rjmp reset

...

.org OC0Aaddr
rjmp timer0_comp

reset:
ldi temp, LOW(RAMEND)
out SPL, temp
ldi temp, HIGH(RAMEND)
out SPH, temp

ldi r16, (1<<LEDROT) | ... (1<<LEDGRUEN) ...
out DDRB, r16

sbi PORTB, LEDGRUEN

...

rcall dcf77_init

ldi temp, (1<<MUX1)
out ADMUX, temp ; Input=PB4, Aref=Vcc
sbi ADCSRA, ADEN

ldi temp, (1<<CS01) ; CLK/8
out TCCR0B, temp
ldi temp, 125 ; 1MHz / 8 / 125 = 1kHz = 10/10ms
out OCR0A, temp
in temp, TIMSK
ori temp, (1<<OCIE0A)
out TIMSK, temp
clr dcf77_count

sei

loop:
...
rjmp loop

...

timer0_comp:
push temp
in temp, SREG
push temp
inc dcf77_count
ldi temp, 10
cp dcf77_count, temp
brne timer0_comp_
clr dcf77_count
clr dcf77_input
sbi ADCSRA, ADSC
timer0_comp__:
sbic ADCSRA, ADSC
rjmp timer0_comp__
in temp, ADCL
in temp, ADCH
cpi temp, 0
breq timer0_comp___
inc dcf77_input
timer0_comp___:
rcall dcf77_start
...
timer0_comp_:
pop temp
out SREG, temp
pop temp
reti

...

; DCF77-FUNKUHR BAUSTEIN in AVR Assembler


; Aufruf im 10 mSek. Zyklus (z.B. über Timer-Interrupt).

; Verwendete Register: dcf77_reg0 - dcf77_reg3, R28/R29 sowie R30/31 (Y,Z Pointer).

; Der statische Datenbereich belegt 12 Bytes für den DCF77-Decoder.
; Vor Verwendung ist zu dessen Initialisierung dcf77_init aufzurufen.
; Weitere 8 Bytes enthalten die aktuelle Zeitinformation im BCD-Format
; und können mit zusätzlich installierter Soft-RTC betrieben werden.
; Diese sollte dem Decoder vorangestellt werden und nach Möglichkeit
; auch 1/100 Sekunden zählen (zur Vermeidung von Sek.-Sprüngen beim
; Minutenwechsel).

; Bitte die 20 Variablen wie definiert beieinander lassen.
; Kurzbeschreibung/Initialisierungswerte siehe unten.

; Das DCF77-Signal wird mit Aktiv "Low" an Input PB0 erwartet
; (kann frei nach Bedarf angepasst werden). Die Impulslängenmessung
; erfolgt über die Bestimmung der Signal-Pausenzeiten (in x * 1/100 Sek.).  


dcf77_start:  ldi  YL,LOW(DCF77CT)    ;alle 10 mSek. aufzurufen
    ldi  YH,HIGH(DCF77CT)
    ldd  dcf77_reg0,Y+0
    ldd  dcf77_reg1,Y+1
    sbrc  dcf77_input, 0 ; Aktiv = 1
    rjmp  dcf77_5
    cbi PORTB, LEDROT
    inc  dcf77_reg0
    brne  dcf77_3
dcf77_1:  sbr  dcf77_reg1,$80      ;Fehler-Flag setzen
    std  Y+1,dcf77_reg1
dcf77_2:  clr  dcf77_reg0
dcf77_3:  std  Y+0,dcf77_reg0
dcf77_4:  ret

dcf77_5:  tst  dcf77_reg0      ;Auswertung fertig?
    breq  dcf77_4      ;Ja!
    sbi PORTB, LEDROT ; SELBST EINGEFÜGT!!!
    ldd  dcf77_reg2,Y+2      ;Nein!
    ldd  dcf77_reg3,Y+9
    ldd  ZL,Y+10
    ldd  ZH,Y+11

    cpi  dcf77_reg0,196      ;LastBit 0 Obere Zeitgrenze+1 x
    brsh  dcf77_1      ;überschritten -> Fehler
    cpi  dcf77_reg0,187      ;LastBit-Scheide x
    brsh  dcf77_11    ;187-195 = LastBit0
    cpi  dcf77_reg0,178      ;LastBit 1 Untere Zeitgrenze x
    brsh  dcf77_10    ;178-186 = Lastbit1
        
    sbrc  dcf77_reg1,7      ;Wenn inzwischen Fehler...
    rjmp  dcf77_2      ;dann Abbruch  

    cpi  dcf77_reg2,$15      ;STATE < 21:
    brlo  dcf77_8      ;Inc STATE
        
    cpi  dcf77_reg0,6      ;Störspikegrenze x
    brlo  dcf77_2      ;Störspike wird ignoriert
    cpi  dcf77_reg0,96      ;Datenbit obere Zeitgrenze+1 x
    brsh  dcf77_1      ;überschritten -> Fehler
    cpi  dcf77_reg0,78      ;Datenbit untere Zeitgrenze x
    brlo  dcf77_1      ;unterschritten -> Fehler
    cpi  dcf77_reg0,87      ;Bitscheide x
    brsh  dcf77_6      ;87-95 = Bit0        
    inc  dcf77_reg1      ;78-86 = Bit1
    std  Y+1,dcf77_reg1
    cpi  dcf77_reg2,$1c
    breq  dcf77_6      ;Prüfbit Minute!
    cpi  dcf77_reg2,$23
    breq  dcf77_6      ;Prüfbit Stunde!
    ld  dcf77_reg0,Z      ;dcf77_reg0 = (aktuelle NEWTIME) Zelle
    add  dcf77_reg0,dcf77_reg3      ;addiere SHIFTER
    st  Z,dcf77_reg0      ;zurückspeichern

dcf77_6:  lsl  dcf77_reg3      ;Bit0/1: SHIFTER um 1 nach links
    std  Y+9,dcf77_reg3
    cpi  dcf77_reg2,$1c
    brlo  dcf77_8      ;Minuten-Zyklus 
    breq  dcf77_9      ;Minute Prüfbit
    cpi  dcf77_reg2,$23
    brlo  dcf77_8      ;Stunden-Zyklus
    breq  dcf77_9      ;Stunden-Prüfbit
    cpi  dcf77_reg2,$29
    brlo  dcf77_8
    breq  dcf77_7      ;LastBit TAG
    cpi  dcf77_reg2,$2c
    brlo  dcf77_8
    breq  dcf77_7      ;LastBit WOCHENTAG
    cpi  dcf77_reg2,$31
    brne  dcf77_8
dcf77_7:  ldi  dcf77_reg3,1      ;LastBit MONAT
    adiw  ZH:ZL,1
    std  Y+9,dcf77_reg3
    std  Y+10,ZL
    std  Y+11,ZH    

dcf77_8:  inc  dcf77_reg2      ;Inc STATE
    std  Y+2,dcf77_reg2
    rjmp  dcf77_2                          

dcf77_9:  sbrc  dcf77_reg1,0      ;Prüfbit MIN/STU Auswertung
    rjmp  dcf77_1      ;Prüfbit Fehler
    rjmp  dcf77_7      ;Prüfbit OK

dcf77_10:  inc  dcf77_reg1      ;LastBit = 1: Inc CHECK
dcf77_11:  cpi  dcf77_reg2,$3a      ;58 DCF77-Bits erfasst?
    brne  dcf77_init    ;unvollständig -> dcf77_init
    andi  dcf77_reg1,$81
    brne  dcf77_init    ;Fehlerstatus -> dcf77_init

cbi PORTB, LEDGRUEN ; WIRD NICHT ERREICHT!!!
    ldi  dcf77_reg0,6      ;Erfolgreicher Empfang:
    ld  dcf77_reg1,Z      ;BCD-Zeitinformation
dcf77_12:  std  Z+11,dcf77_reg1    ;nach MIN...JHR sichern
    ld  dcf77_reg1,-Z
    dec  dcf77_reg0
    brne  dcf77_12
    std  Z+11,dcf77_reg0    ;Sek. = 0 setzen
    std  Z+10,dcf77_reg0    ;1/100 Sek. = 0 setzen  
  
dcf77_init:  ldi  ZL,LOW(DCF77CT)    ;DCF77-VARIABLEN RESET
    ldi  ZH,HIGH(DCF77CT)
    ldi  dcf77_reg1,LOW(NEWTIME)
    ldi  dcf77_reg2,HIGH(NEWTIME)
    ldi  dcf77_reg0,$09
    clr  dcf77_reg3
dcf77_14:  st  Z+,dcf77_reg3
    dec  dcf77_reg0
    brne  dcf77_14
    inc  dcf77_reg0
    st  Z+,dcf77_reg0
    st  Z+,dcf77_reg1
    st  Z,dcf77_reg2
    ret

.DSEG
;SRAM Variable  Definition  Init.Wert  Beschreibung
;------------------------------------------------------------------------------
DCF77CT:  .BYTE 1    ;0    DCF77 Impuls-Pausenzeit-Zähler
DCF77CHECK:  .BYTE 1    ;0    DCF77 Fehler-Flag + 1-Zähler
DCF77STATE:  .BYTE 1    ;0    DCF77 Aktuelle Bitnummer
NEWTIME:  .BYTE 6    ;0,0,0,0,0,0  DCF77 Zeit-Zwischenspeicher
DCF77SHIFT:  .BYTE 1    ;1    DCF77 Shifter
DCF77TAL:  .BYTE 1    ;LOW(NEWTIME)  DCF77 Pointer auf NEWTIME Low
DCF77TAH:  .BYTE 1    ;HIGH(NEWTIME)  DCF77 Pointer auf NEWTIME High
HSEK:    .BYTE 1    ;RTC verwaltet  BCD 1/100 Sekunde
SEK:    .BYTE 1    ;RTC verwaltet  BCD Sekunde
MIN:    .BYTE 1    ;RTC verwaltet  BCD Minute
STU:    .BYTE 1    ;RTC verwaltet  BCD Stunde
TAG:    .BYTE 1    ;RTC verwaltet  BCD Tag
WTAG:    .BYTE 1    ;RTC verwaltet  BCD Wochentag
MON:    .BYTE 1    ;RTC verwaltet  BCD Monat
JHR:    .BYTE 1    ;RTC verwaltet  BCD Jahr

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Der DCF77-Empfänger wird mittels ADC
>ausgemessen,

Was fürn Unsinn.

> da er eine niedrigere Betriebsspannung hat und nur ein paar
>µA treiben kann.

Dann nimm halt einen 1M Ohm Pullup.

>Das Problem ist, dass ich zwar an der roten LED das DCF-Signal sehen

Und wo ist diese ominöse rote LED angeschlossen?

Autor: Ich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, das mit 1MOhm Pullup werd ich machen (wusste schon, das der ADC 
sinnlos ist).

> .include "tn85def.inc"
>
> .equ LEDROT = 0

-> PB0

Autor: Ich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nee Pullup geht nicht, wegen "Current Source/Sink"

Autor: Ich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also kann mir keiner helfen :(

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.