www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ATmega8 16-Bit Timer Uhr zu langsam


Autor: Philipp (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

Ich habe mir heute eine Uhr für den  ATmega8 programmiert, die den 
16-Bit Timer (Timer1) benutzt. Die Uhrzeit soll immer um 2 10tel 
Sekunden erhöht werden. Dies wird auf einem LCD ausgegeben.

Der Takt des ATmega beträgt 16MHZ, ich verwende den Prescaler 64, Takt 
ist also 250.000 Hertz. Jetzt lasse ich über die Timer Compare Funktion 
bei jedem 50.0000 sten Takt ein Interrupt ausgeben, d.h. 5 
Interrupts/sek ==> 1 Interrupt pro 2 10tek sek.

Das Hochzählen und die Ausgabe am Bildschirm funktioniert soweit.
Mein Problem: Das Hochzählen geht viel zu langsam, die Zehntel Sekunden 
Stelle wir nur etwa alle 4 Sekunden erhöht.

Im Anhang befindet sich mein Programm.

Findet vielleicht jemand einen Fehler?

Danke schon mal im Voraus

mfg Philipp

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Läuft wahrscheinlich immer noch mit
Int-RC Osc. Fuses falsch programmiert.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier stimmt was nicht
Overflow:    cpi tel10, 8
        breq sekErhoehen
        add tel10, r28
        reti
sekErhoehen:  clr tel10
        cpi sek,6
        breq sek10Erhoehen
        inc sek
        reti
sek10Erhoehen:  clr sek
        cpi sek10, 6
        breq minErhoehen
        inc sek10
        reti
minErhoehen:  inc min
        clr  sek10
        reti

Der erste cpi
Warum 8?  Ich denke du kriegst den Interrupt alls 2/10 Sekunden. Dann 
brauchst aber 5 Interrupts bis eine Sekunde um ist.

sekErhoehen
Warum vergleichst du mit 6? Die Einerstelle muss bis 10 laufen, ehe der 
Übertrag in die nächste Stelle erfolgt.

Überhaupt: deine Technik des zuerst Vergleichens und dann mglw. Erhöhen 
ist nicht koscher.

Edit: Hab jetzt erst gesehen, dass du tel10 immer um 2 erhöhst, das 
machts zwar auch nicht richtiger aber zumindest nahe dran. Koscher ist 
die Sequenz trotzdem nicht.

Autor: PillePalle (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
moin


erstmal beim Eintritt in den IRQ das Statusregister sichern !

und das andere dann zB. so (für 5ms Int.)
Die Zeile cpi tock,200 musst du anpassen
tick:    
    in   status,SREG    ;preserve status register
    
    inc   tock    ;add one to 5 ms 'tock' counter
    cpi   tock,200  ;is one second up?
    breq   onesec    ;yes, add one to seconds
    nop      ;balance interrupt time
    nop
    rjmp   nosecond    ;no, escape
onesec:    inc   second    ;add one to seconds
    mov  timer,second  ; wegen cpi -geht nur in den oberen registern
    cpi  timer,60  ; is min. full
    brne  clsecond  ;no
    clr  second    ;yes,clear second
    inc  minute    ;add one to minute
    mov    timer,minute
    cpi  timer,60  ;is 1 hour 
    brne  clsecond  ;no
    clr  minute    ;yes
    inc  hour    ;inc hour
    mov  timer,hour
    cpi  timer,24  ;24 hour
    brne  clsecond  ;no  
    clr  hour    ;yes 24 full
    clr   minute
    clr  second
clsecond:  clr   tock    ;clear 5 ms counter
        
nosecond:  
    out   SREG,status    ;restore status register
    reti      ;return to main

Autor: Philipp (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich überprüfe zuerst auf 8, weil wenn ich zu 8 2 addiere muss danach die 
nächste Stelle auch erhöht werden.

Bei sek erhöhen muss ich aber dann auch auf 8 überprüfen, da diese ja 
bis 10 (also 0) gehen sollen.
An der Zählroutine muss ich noch eine kleine Änderung vornehmen.

Mein Hauptproblem ist, dass mein ATmega8 noch den internen Takt nimmt. 
Jetzt muss ich mich erstmal belesen, wie ich das ganze mit den Fuse Bits 
auf 16 MHZ External Quarz Resonator umstelle.

Autor: icke (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ldi temp, 0b00001000  ; CTC Modus aktivieren
out TCCR1B, temp   ????????

ldi temp, 0b00010000  ; Interrupt on Compare
out TIMSK, temp

ldi temp, 0b00000011  ; Prescaler 64  (250KHZ)
out TCCR1B, temp   ????????

wenn du das TCCR1B mit 0b00000011 ladest überschreibst du den CTC wert

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Philipp wrote:

> Mein Hauptproblem ist, dass mein ATmega8 noch den internen Takt nimmt.

Das ist wohl war. Icke hat ja schon das nächste Problem aufgezeigt (das 
erklärt aber auch noch nicht deinen Faktor 4)

> Bei sek erhöhen muss ich aber dann auch auf 8 überprüfen, da diese ja
> bis 10 (also 0) gehen sollen.

Du bist gerade drauf und drann, dich selbst auszutricksen :-)

Autor: Philipp (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stimmt, du hast natürlich recht, werde das gleich mal ändern.

Kann mir vielleicht jemand sagen, wie ich die Fuse Bits einstellen muss, 
damit der Controller auf 16 MHZ läuft? Habe beim googlen noch nichts 
hilfreiches gefunden.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du musst auf 'external crystal' fusen.

Details finden sich in deinem Datenblatt
http://www.mikrocontroller.net/articles/AVR_Fuses

Autor: Philipp (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe ich auch schon gelesen.
Leider gibt es für den ATmega8-16PU scheinbar kein Separates Datenblatt, 
es gibt nur das vom normalen ATmega8 und in diesem stehen die Fuse-Bit 
Einstellungen nur bis 8MHZ.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Philipp wrote:
> Habe ich auch schon gelesen.
> Leider gibt es für den ATmega8-16PU scheinbar kein Separates Datenblatt,
> es gibt nur das vom normalen ATmega8 und in diesem stehen die Fuse-Bit
> Einstellungen nur bis 8MHZ.
Nö. Es gibt eine Einstellung (nämlich mit CKOPT programmiert), die für 
alle Frequenzen gilt, die nicht in der Tabelle explizit aufgeführt 
sind...

Autor: Philipp (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ok, vielen Dank für eure Hilfe, ich habe die Einstellungen gefunden.

Die Einstellungen für 16MHZ:
CKSEL0 - CKSEL3: 1111
SUT0 - SUT1: 11
CKOPT: 0

Wichtig: In Ponyprog sind die Haken Invertiert, also wo eine Eins steht 
keinen Haken setzen!!!

Das Programm funktioniert jetzt wie es soll

Vielen Dank nochmal für eure Hilfe.

Im Anhang ist noch das verbesserte, Endgültige Programm

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kann jemand von den Regulars mal da drüber schaun.
Ich bin der Ansicht, dass die Uhr in der Sekundenanzeige nicht von 0 bis 
59 sondern von 1 bis 69 zählt.

Kanns aber im Moment nicht ausprobieren.

Autor: Volker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Philipp:

Du solltest zumindest das Statusregister retten da cpi einige Flaggen 
ändert.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Karl heinz Buchegger

Jepp! Und die Anzahl der Zehntel (tel10) stimmt auch nicht

Testprogramm in Python
#!/path/to/python 
import time

"""
Overflow:    cpi tel10, 8
        breq sekErhoehen
        inc tel10
        reti
sekErhoehen:  clr tel10
        cpi sek,9
        breq sek10Erhoehen
        inc sek
        reti
sek10Erhoehen:  clr sek
        cpi sek10, 6
        breq minErhoehen
        inc sek10
        reti
minErhoehen:  clr  sek10
        cpi min, 9
        breq min10Erhoehen
        inc min
        reti
min10Erhoehen:  clr min
        inc min10
        reti
"""

def Overflow():
    global tel10
    if tel10 == 8:
        sekErhoehen()
    else:
        tel10 = tel10 + 1
    return

def sekErhoehen():
    global tel10
    global sek
    tel10 = 0
    if sek == 9:
        sek10Erhoehen()
    else:
        sek = sek + 1
    return

def sek10Erhoehen():
    global sek
    global sek10
    sek = 0
    if sek10 == 6:
        minErhoehen()
    else:
        sek10 = sek10 + 1
    return

def minErhoehen():
    global sek10
    global min1
    sek10 = 0
    if min1 == 6:
        min10Erhoehen()
    else:
        min1 = min1 + 1
    return

def min10Erhoehen():
    global min1
    global min10
    min1 = 0
    min10 = min10 + 1
    return

def main():
    for i in range(0,36000):
        print "%d%d:%d%d.%d" % (min10, min1, sek10, sek, tel10),
        Overflow()
        # time.sleep(0.1)
    return

if __name__ == "__main__":
    tel10 = 0
    sek = 0
    sek10 = 0
    min1 = 0
    min10 = 0
    main()
  

Ausgabe:
00:00.0 00:00.1 00:00.2 00:00.3 00:00.4 00:00.5 00:00.6 00:00.7 00:00.8 
00:01.0 00:01.1 00:01.2 00:01.3 00:01.4 00:01.5 00:01.6 00:01.7 00:01.8 
00:02.0 00:02.1 00:02.2 00:02.3 00:02.4 00:02.5 00:02.6 00:02.7 00:02.8 
00:03.0 00:03.1 00:03.2 00:03.3 00:03.4 00:03.5 00:03.6 00:03.7 00:03.8
00:04.0 00:04.1 00:04.2 00:04.3 00:04.4 00:04.5 00:04.6 00:04.7 00:04.8 
00:05.0 00:05.1 00:05.2 00:05.3 00:05.4 00:05.5 00:05.6 00:05.7 00:05.8 
00:06.0 00:06.1 00:06.2 00:06.3 00:06.4 00:06.5 00:06.6 00:06.7 00:06.8 
00:07.0 00:07.1 00:07.2 00:07.3 00:07.4 00:07.5 00:07.6 00:07.7 00:07.8 
00:08.0 00:08.1 00:08.2 00:08.3 00:08.4 00:08.5 00:08.6 00:08.7 00:08.8 
00:09.0 00:09.1 00:09.2 00:09.3 00:09.4 00:09.5 00:09.6 00:09.7 00:09.8 
00:10.0 00:10.1 00:10.2 00:10.3 00:10.4 00:10.5 00:10.6 00:10.7 00:10.8 
00:11.0 00:11.1 00:11.2 00:11.3 00:11.4 00:11.5 00:11.6 00:11.7 00:11.8 
00:12.0 00:12.1 00:12.2 00:12.3 00:12.4 00:12.5 00:12.6 00:12.7 00:12.8 
00:13.0 00:13.1 00:13.2 00:13.3 00:13.4 00:13.5 00:13.6 00:13.7 00:13.8 
00:14.0 00:14.1 00:14.2 00:14.3 00:14.4 00:14.5 00:14.6 00:14.7 00:14.8 
00:15.0 00:15.1 00:15.2 00:15.3 00:15.4 00:15.5 00:15.6 00:15.7 00:15.8 
00:16.0 00:16.1 00:16.2 00:16.3 00:16.4 00:16.5 00:16.6 00:16.7 00:16.8 
00:17.0 00:17.1 00:17.2 00:17.3 00:17.4 00:17.5 00:17.6 00:17.7 00:17.8 
00:18.0 00:18.1 00:18.2 00:18.3 00:18.4 00:18.5 00:18.6 00:18.7 00:18.8 
00:19.0 00:19.1 00:19.2 00:19.3 00:19.4 00:19.5 00:19.6 00:19.7 00:19.8 
00:20.0 00:20.1 00:20.2 00:20.3 00:20.4 00:20.5 00:20.6 00:20.7 00:20.8 
00:21.0 00:21.1 00:21.2 00:21.3 00:21.4 00:21.5 00:21.6 00:21.7 00:21.8 
00:22.0 00:22.1 00:22.2 00:22.3 00:22.4 00:22.5 00:22.6 00:22.7 00:22.8 
00:23.0 00:23.1 00:23.2 00:23.3 00:23.4 00:23.5 00:23.6 00:23.7 00:23.8 
00:24.0 00:24.1 00:24.2 00:24.3 00:24.4 00:24.5 00:24.6 00:24.7 00:24.8 
00:25.0 00:25.1 00:25.2 00:25.3 00:25.4 00:25.5 00:25.6 00:25.7 00:25.8 
00:26.0 00:26.1 00:26.2 00:26.3 00:26.4 00:26.5 00:26.6 00:26.7 00:26.8 
00:27.0 00:27.1 00:27.2 00:27.3 00:27.4 00:27.5 00:27.6 00:27.7 00:27.8 
00:28.0 00:28.1 00:28.2 00:28.3 00:28.4 00:28.5 00:28.6 00:28.7 00:28.8 
00:29.0 00:29.1 00:29.2 00:29.3 00:29.4 00:29.5 00:29.6 00:29.7 00:29.8 
00:30.0 00:30.1 00:30.2 00:30.3 00:30.4 00:30.5 00:30.6 00:30.7 00:30.8 
00:31.0 00:31.1 00:31.2 00:31.3 00:31.4 00:31.5 00:31.6 00:31.7 00:31.8 
00:32.0 00:32.1 00:32.2 00:32.3 00:32.4 00:32.5 00:32.6 00:32.7 00:32.8 
00:33.0 00:33.1 00:33.2 00:33.3 00:33.4 00:33.5 00:33.6 00:33.7 00:33.8 
00:34.0 00:34.1 00:34.2 00:34.3 00:34.4 00:34.5 00:34.6 00:34.7 00:34.8 
00:35.0 00:35.1 00:35.2 00:35.3 00:35.4 00:35.5 00:35.6 00:35.7 00:35.8 
00:36.0 00:36.1 00:36.2 00:36.3 00:36.4 00:36.5 00:36.6 00:36.7 00:36.8 
00:37.0 00:37.1 00:37.2 00:37.3 00:37.4 00:37.5 00:37.6 00:37.7 00:37.8 
00:38.0 00:38.1 00:38.2 00:38.3 00:38.4 00:38.5 00:38.6 00:38.7 00:38.8 
00:39.0 00:39.1 00:39.2 00:39.3 00:39.4 00:39.5 00:39.6 00:39.7 00:39.8 
00:40.0 00:40.1 00:40.2 00:40.3 00:40.4 00:40.5 00:40.6 00:40.7 00:40.8 
00:41.0 00:41.1 00:41.2 00:41.3 00:41.4 00:41.5 00:41.6 00:41.7 00:41.8 
00:42.0 00:42.1 00:42.2 00:42.3 00:42.4 00:42.5 00:42.6 00:42.7 00:42.8 
00:43.0 00:43.1 00:43.2 00:43.3 00:43.4 00:43.5 00:43.6 00:43.7 00:43.8 
00:44.0 00:44.1 00:44.2 00:44.3 00:44.4 00:44.5 00:44.6 00:44.7 00:44.8 
00:45.0 00:45.1 00:45.2 00:45.3 00:45.4 00:45.5 00:45.6 00:45.7 00:45.8 
00:46.0 00:46.1 00:46.2 00:46.3 00:46.4 00:46.5 00:46.6 00:46.7 00:46.8 
00:47.0 00:47.1 00:47.2 00:47.3 00:47.4 00:47.5 00:47.6 00:47.7 00:47.8 
00:48.0 00:48.1 00:48.2 00:48.3 00:48.4 00:48.5 00:48.6 00:48.7 00:48.8 
00:49.0 00:49.1 00:49.2 00:49.3 00:49.4 00:49.5 00:49.6 00:49.7 00:49.8 
00:50.0 00:50.1 00:50.2 00:50.3 00:50.4 00:50.5 00:50.6 00:50.7 00:50.8 
00:51.0 00:51.1 00:51.2 00:51.3 00:51.4 00:51.5 00:51.6 00:51.7 00:51.8 
00:52.0 00:52.1 00:52.2 00:52.3 00:52.4 00:52.5 00:52.6 00:52.7 00:52.8 
00:53.0 00:53.1 00:53.2 00:53.3 00:53.4 00:53.5 00:53.6 00:53.7 00:53.8 
00:54.0 00:54.1 00:54.2 00:54.3 00:54.4 00:54.5 00:54.6 00:54.7 00:54.8 
00:55.0 00:55.1 00:55.2 00:55.3 00:55.4 00:55.5 00:55.6 00:55.7 00:55.8 
00:56.0 00:56.1 00:56.2 00:56.3 00:56.4 00:56.5 00:56.6 00:56.7 00:56.8 
00:57.0 00:57.1 00:57.2 00:57.3 00:57.4 00:57.5 00:57.6 00:57.7 00:57.8 
00:58.0 00:58.1 00:58.2 00:58.3 00:58.4 00:58.5 00:58.6 00:58.7 00:58.8 
00:59.0 00:59.1 00:59.2 00:59.3 00:59.4 00:59.5 00:59.6 00:59.7 00:59.8 
00:60.0 00:60.1 00:60.2 00:60.3 00:60.4 00:60.5 00:60.6 00:60.7 00:60.8 
00:61.0 00:61.1 00:61.2 00:61.3 00:61.4 00:61.5 00:61.6 00:61.7 00:61.8 
00:62.0 00:62.1 00:62.2 00:62.3 00:62.4 00:62.5 00:62.6 00:62.7 00:62.8 
00:63.0 00:63.1 00:63.2 00:63.3 00:63.4 00:63.5 00:63.6 00:63.7 00:63.8 
00:64.0 00:64.1 00:64.2 00:64.3 00:64.4 00:64.5 00:64.6 00:64.7 00:64.8 
00:65.0 00:65.1 00:65.2 00:65.3 00:65.4 00:65.5 00:65.6 00:65.7 00:65.8 
00:66.0 00:66.1 00:66.2 00:66.3 00:66.4 00:66.5 00:66.6 00:66.7 00:66.8 
00:67.0 00:67.1 00:67.2 00:67.3 00:67.4 00:67.5 00:67.6 00:67.7 00:67.8 
00:68.0 00:68.1 00:68.2 00:68.3 00:68.4 00:68.5 00:68.6 00:68.7 00:68.8 
00:69.0 00:69.1 00:69.2 00:69.3 00:69.4 00:69.5 00:69.6 00:69.7 00:69.8 
01:00.0 01:00.1 01:00.2 01:00.3 01:00.4 01:00.5 01:00.6 01:00.7 01:00.8 
01:01.0 01:01.1 01:01.2 01:01.3 01:01.4 01:01.5 01:01.6 01:01.7 01:01.8 
01:02.0 01:02.1 01:02.2 01:02.3 01:02.4 01:02.5 01:02.6 01:02.7 01:02.8 


Autor: Philipp (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ja, ihr habt natürlich recht, habe noch vergessen, bei den 10 tel 
Sekunden die 8 zu einer 9 zu ändern. Hier im Anhang nochmal der 
endgültige, funktionierende Code.

Jetzt stimmt die Zeit auch, habe es mit einer Uhr verglichen.

gruß Philipp

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.