-
        

Ergebnis 1 bis 10 von 10

Thema: Binär Uhr - Zehnerstellen...

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    31.08.2008
    Beiträge
    5

    Binär Uhr - Zehnerstellen...

    Anzeige

    Ich bin gerade dabei eine binär-uhr zu basteln.
    ich benutze einen atmega16 und habe an den porta die sekunden, portb die minuten und c die stunden.
    die uhr läuft soweit ganz gut und auch ordentlich.
    Bis:
    Die Leds werdem einzeln angesteuert.
    Mein Problem ist, wie kann ich es jetzt umsetzen, dass in der 2.reihe die zehnersekunden angezeigt werden?

    also so:
    Code:
          | O
        O | O
        O | O
        O | O
     10er | 1er

    grüße,
    ein handwerker

  2. #2
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    24.02.2006
    Ort
    3. Planet eines kleinen Sonnensystems in einem Seitenarm der Milchstraße
    Alter
    63
    Beiträge
    622
    Hallo handwerker,

    wenn ich Deine Frage richtig verstehe, zeigst Du zur Zeit 8-Bit Binärwerte an, möchtest diese aber lieber als BCD-Werte darstellen. Dann brauchst Du eine kleine Routine, die Dir Binärwerte<60 in BCD (Zehnerstelle höherwertiges Nibble, Einerstelle niederwertiges Nibble) umwandelt.
    Das könnte man ganz primitiv durch mehrfache Subtraktion von 10 lösen:
    Code:
    ; r16 enthält Binärwert <60
    ; r17 wird als Zehner-Zähler verwendet
    ; Ergebnis in r16: Zehner-Stelle b4-b7, Einerstelle b0-b3
    
    to_bcd:
        ser r17         ; Zehner-Zähler = -1
    bcd_lp:
        inc r17         ; ++Zehner-Zähler 
        subi r16, 10    ; -10
        brpl bcd_lp     ; noch einmal, wenn >=0
    
        swap r17        ; Zehnerstellen: b4-b7
        subi r16,-10    ; letzte Subtraktion rückgängig machen
        or r16,r17      ; Einerstellen: b0-b3
    Habe ich schnell mal so hingeschrieben -- ist sicher noch optimierbar; wobei die Optimierung für eine Uhr aber wohl eher unkritisch ist.

    Gruß

    Fred
    Only entropy comes easy. - Anton Checkhov

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    31.08.2008
    Beiträge
    5
    genauso meine ich das.
    entweder bin ich zu blöde, nur funktioniert es nicht so, wie ich das denke.
    ich habe das jetzt so eingebaut.

    Code:
    sekunde:
    	cpi sekunde, 60
    	breq minute
    	cpi sekunde, 10
    	brsh bcd
    	out	ddra, sekunde
    	rjmp sekunde
    
    
    bcd:
    	ser sekunde2 
    
    to_bcd:
    	inc sekunde2
    	subi sekunde, -10
    	brpl to_bcd
    	swap sekunde2
    	subi sekunde, -10
    	or sekunde, sekunde2
    	out	ddra, sekunde
    	rjmp sekunde

  4. #4
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    24.02.2006
    Ort
    3. Planet eines kleinen Sonnensystems in einem Seitenarm der Milchstraße
    Alter
    63
    Beiträge
    622
    Hi,

    Du kannst die Konversionsroutine für die Sekunden, Minuten und Stunden nutzen. Ich würde die Konversion in ein Unterprogramm packen (mit RCALL anspringen und mit RET verlassen).
    Der in die Konversionsroutine gehende Wert darf <=10 sein; ein vorheriges Testen (Deine Zeile "cpi sekunde, 10") ist nicht nötig.
    Du verwendest "sekunde" sowohl als Label als auch als Namen eines Registers. Welcher Assembler kann damit umgehen?

    Gruß

    Fred
    Only entropy comes easy. - Anton Checkhov

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    31.08.2008
    Beiträge
    5
    okay, das habe ich jetzt gemacht. nur leuchten dann jetzt alle leds für die sekunden. bis auf die erste, die blinkt im sekundentakt.
    ich nutze AVR studio und es hat deswegen nicht rumgemeckert.
    habe mal die label geändert, daran scheint es aber nicht zu liegen.
    *grübel*


    Code:
    sekunden:
    	cpi sekunde, 60
    	breq minuten
    	rcall bcd
    	out ddra, sekunde
    	rjmp sekunden
    
    
    bcd:
    	ser sekunde2
    to_bcd:
    	inc sekunde2
    	subi sekunde, -10
    	brpl to_bcd
    	swap sekunde2
    	subi sekunde, -10
    	or sekunde, sekunde2
    	ret

  6. #6
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    24.02.2006
    Ort
    3. Planet eines kleinen Sonnensystems in einem Seitenarm der Milchstraße
    Alter
    63
    Beiträge
    622
    Hi,

    zur Fehlersuche musst Du schon mehr Code posten. Nimm doch einfach mal einen festen Wert für die Sekunden, um die BCD-Darstellung zu testen. Meine Konversionsroutine funktioniert im AVRStudio-Simulator problemlos. Wird "sekunde2" anderswo (z.B. in einer Interrupt Service Routine) mibenutzt? Wie schaltest Du die Zeit weiter?
    Statt "out DDRA, register" willst Du sicher "out PORTA, register" schreiben!

    Gruß

    Fred
    Only entropy comes easy. - Anton Checkhov

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    31.08.2008
    Beiträge
    5
    uffz...
    sekunde2 wird nur in der bcd-routine genutzt, ansonsten gar nicht.

    also insgesamt sieht es so aus:

    Code:
    .nolist
    .include"m16def.inc"
    
    .equ	xtal	= 8000000
    .equ	debounce = 256
    .equ	remainder = xtal - xtal / debounce * debounce
    
    .def	isreg = r15
    .def	wr0	= r16
    .def	iwr0 = r17
    .def	prescaler = r18
    
    .def	sekunde = r19
    .def    sekunde2 = r20
    .def    minute = r21
    .def    stunde = r22
    
    .list
    	rjmp	init
    	.org	OC1Aaddr
    	rjmp	OC1Aint
    ;-------------------------------------------------------------------------
    OC1Aint:
    	in	isreg, sreg
    
    	ldi	iwr0, high( xtal / debounce - 1 )
    	out	ocr1ah, iwr0
    	ldi	iwr0, low( xtal / debounce - 1 )
    	out	ocr1al, iwr0
    
    	dec	prescaler
    	brne	_oci1
    
    	ldi	prescaler, debounce
    	inc	sekunde
    
    	ldi	iwr0, high( xtal / debounce + remainder - 1 )
    	out	ocr1ah, iwr0
    	ldi	iwr0, low( xtal / debounce + remainder - 1 )
    	out	ocr1al, iwr0
    _oci1:
    	out	sreg, isreg
    	reti
    ;-------------------------------------------------------------------------
    init:
    	ldi	wr0, 0x0
    	out	ddra, wr0
    	out ddrb, wr0
    	out ddrc, wr0
    	ldi sekunde, 0
    
    
    	ldi	wr0, high( ramend )
    	out	sph, wr0
    	ldi	wr0, low( ramend )
    	out	spl, wr0
    
    	ldi	wr0, 1<<WGM12^1<<CS10
    	out	TCCR1B, wr0
    
    	ldi	wr0, high( xtal / debounce - 1 )
    	out	ocr1ah, wr0
    	ldi	wr0, low( xtal / debounce - 1 )
    	out	ocr1al, wr0
    	out	tcnt1l, wr0
    	ldi	prescaler, debounce
    
    	ldi	wr0, 1<<OCIE1A
    	out	TIMSK, wr0
    	sei
    
    
    
    
    main:
    	ldi	sekunde, 0
    	
    sekunden:
    	cpi sekunde, 60
        breq minuten 
    	rcall bcd
    	out ddra, sekunde
    	rjmp sekunden
    
    
    bcd:
    	ser sekunde2
    to_bcd:
    	inc sekunde2
    	subi sekunde, -10
    	brpl to_bcd
    	swap sekunde2
    	subi sekunde, -10
    	or sekunde, sekunde2
    	ret
    
    
    
    minuten:
        inc minute
    	cpi minute, 60
    	breq stunden
    	out ddrb, minute
    	rjmp main
    
    
    
    stunden:
        ldi minute, 0
    	out ddrb, minute
    	inc stunde
    	cpi stunde, 24
    	breq tag
    	out ddrc, stunde
    	rjmp main
    
    
    tag:
        ldi stunde, 0
    	out ddrc, stunde
    	rjmp main

  8. #8
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    24.02.2006
    Ort
    3. Planet eines kleinen Sonnensystems in einem Seitenarm der Milchstraße
    Alter
    63
    Beiträge
    622
    Hi,

    lies noch einmal meinen letzten Satz im letzten Posting. Falls es dann noch nicht klappt, sehe ich mir mal Deinen kompletten Code an.

    Gruß

    Fred

    PS: Auch bei den Minuten und Stunden musst Du DDRx durch PORTx ersetzen!
    Only entropy comes easy. - Anton Checkhov

  9. #9
    Neuer Benutzer Öfters hier
    Registriert seit
    31.08.2008
    Beiträge
    5
    Nein, mit PortA funktioniert es nicht.
    Ich habe den beispielcode genutzt.
    http://www.mikrocontroller.net/artic...l_in_Assembler

  10. #10
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    24.02.2006
    Ort
    3. Planet eines kleinen Sonnensystems in einem Seitenarm der Milchstraße
    Alter
    63
    Beiträge
    622
    Hi,

    Zitat Zitat von handwerker
    Nein, mit PortA funktioniert es nicht. ...
    obwohl Du in Deinem ersten Posting schreibst:
    ...die uhr läuft soweit ganz gut und auch ordentlich
    ?

    Sieh Dir mal genau Deine Intialisierung an (hier von mir kommentiert):
    Code:
    ldi   wr0, 0x0 
       out  ddra, wr0 ;  PORTA als Eingang!
       out ddrb, wr0  ;  PORTB als Eingang!
       out ddrc, wr0  ;  PORTC als Eingang!
       ldi sekunde, 0
    PORTA-C sind alle als Eingänge deklariert!

    Gruß

    Fred
    Only entropy comes easy. - Anton Checkhov

Berechtigungen

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