Archiv verlassen und diese Seite im Standarddesign anzeigen : Exakter Sekundentakt mit wenig Aufwand
Hallo,
ich wollte einen ATtiny2313 so programmieren, das die LED am PINB 0 im Sekundentakt blinkt. Leider liegt die Blinkfrequenz 4x niedriger.
Ich dachte, wenn ich den Hardwarezähler so vorstelle, dass er nur noch 125 Takte bis zum Überlauf und somit zum Auslösen des Interrupts zählt, könnte ich durch weiteres Teilen / 125 den Sekundentakt bekommen.
4 000 000 / 256 / 125 / 125 = 1
Kann mal jemand schauen, was an dem Code oder meinen Überlegungen nicht stimmt?
.include "tn2313def.inc"
.def rSreg = R1
.def rTCNT0 = R16
.def Leds = R17
.def rVT1 = R18
.def temp = R19
rjmp main ; Springe zum Anfang
; Die Interrupt-Vektoren
reti ; Int0-Interrupt
reti ; Int1-Interrupt
reti ; TC1-Capture
reti ; TC1-Compare A
reti ; TC1-Overvlow
reti ; TC0-Overvlow
reti ; UART0 RX
reti ; UART0 UDRE
reti ; UART Tx
reti ; Analog COMP
reti ; PCINT
reti ; Timer/Counter1 Compare Match B
rjmp timer0_overflow ; Timer/Counter0 Compare Match A
reti ; Timer/Counter0 Compare Match B
reti ; USI Start
reti ; USI Overflow
reti ; EEReady
reti ; WDT Overflow
main:
ldi temp, LOW(RAMEND) ; Stackpointer initialisieren
out SPL, temp
ldi temp, 0xFF ; Port B auf Ausgang
out DDRB, temp
ldi leds, 0xFF
ldi temp, 4 ; Teiler auf Frequenz / 256 setzen
out TCCR0, temp
ldi temp, 0b00000001 ; TOIE0: Interrupt bei Timer Overflow
out TIMSK, temp
ldi rTCNT0, 131 ; Voreinstellung des Hardwarezählers
sei ; Interrupts aktivieren
loop:
OUT PORTB, Leds
rjmp loop
timer0_overflow:
in rSreg,SREG ; Status retten
OUT TCNT0, rTCNT0 ; Hardwarezähler so stellen, dass bei 125 Impulsen der Überlauf erfolgt
inc rVT1 ; unteres Byte erhoehen
cpi rVT1,125 ; Wenn 125 erreicht, ist 1 Sekunde um: (4000000 / 256 / 125/ 125 = 1)
BRCS intret ; nein, warte nachsten Int ab
clr rVT1 ; unterer Zaehler auf Null
dec Leds ; Register dekrementieren
intret:
out SREG,rSreg ; Status wieder herstellen
reti ; Rueckkehr vom Interrupt
MfG LotharK
Hi,
hab Deinen Code mal im Simulator vom AVR-Studio laufen lassen (hast Du das? Wenn nicht solltest Du Dir das ganz schnell besorgen ;-) )
Die Zeile
dec Leds ; Register dekrementieren
auf die es Dir ja ankommt wird genau alle 1008 ms angesprungen.
Daraus läßt sich schließen, das vermutlich Dein Prozessor mit den standardmäßigen internen 1 MHz läuft, hast du die Fusebits richtig eingestellt?
Dann mußt Du Dich auf die Suche machen, wo die 8 ms zu viel herkommen, vermutlich wird Dein überlauf einen Takt zu spät erzeugt.
Dann wäre noch interessant, ob Du einmal weiterzählen pro sekunde willst oder ob die LED mit 1 Hz blinken soll, da jetzt nur alle 1 s gezählt wird, bekommst Du nur 0,5 Hz auf bit 0
greetz Rajko
Hallo Rajko,
Ja ich habe das Studio und auch das STK500. Ich beschäftige mich erst einige wenige Tage mit der ganzen Materie.
Wenn der Controller intern mit 1 MHz läuft, erklärt das alles. Ich dachte, er liefe mit 4 MHz, weil es ja auch im Studio so angezeigt wird.
Die 8 ms kommen sicher fon der Zeile
ldi rTCNT0, 131 ; Voreinstellung des Hardwarezählers und sollten auf 132 geändert werden.
Wie hast Du die Erkenntnis von 1008 erhalten? Gibst Du mir bitte einen Tipp?
Eigentlich habe ich mit dem Code nichts weiter vor. Ich wollte nur mal sehen, ob ich das mit dem Counter richtig verstanden habe. Leider ging das ja in die Hose, wie Du sahst.
An die Fusebits habe ich mich noch nicht getraut, obwohl ich Quarze da habe. Ich weiß nicht, was ich beim ATtiny2313 einstellen muss.
Vielen Dank für Deine Mühe.
MfG LotharK
Hi
Im Simulator mußt Du den Takt einstellen, mit dem der AVR in der Zielschaltung laufen soll, damit die Laufzeitangaben auch entsprechend stimmen. Die Einstellung ist im Menü "Debug" ->"AVR Simulator Options", das geht aber nur, wenn Du auch im Simulator-Modus bist. Die Einstellung wirkt sich nur auf den Simulator aus.
Die Fusebits solltest Du auch nur verändern, wenn das Quarz angeschlossen ist, sonst läßt Dich der AVR nicht mehr ran. Aber sonst brauchste keine Scheu haben ;-) Die genaue Einstellung findet sich im Datenblatt. Dort findest Du auch, mit welchem Takt der AVR standardmäßig läuft, wenn er frisch ausgeliefert wird, ich glaube das sind immer 1MHz mit dem internen Oszillator.
Für Laufzeitmessungen im Simulator gibt es die Breakpoints. Du gehst mit dem Cursor auf eine Zeile mit Programmcode und setzt mit der rechten Maustaste mit 'toggle breakpoint' eine Stoppmarke.
Dann muß der Workspace eingeschaltet sein: "View"->"Workspace" Dort suchst Du dir das Register I/O. Hiermit kannst Du schon mal jedes einzelne Bit des gesamten Prozessors zur Laufzeit analysieren. Unter Processor gibt es auch noch die "StopWatch". Wenn Dein Simulator dann das erste mal am breakpoint anhält, setzt Du die Stoppuhr mit Rechtsklick auf Null. Dann läßt Du Dein Programm weiterlaufen, bis es wieder am breakpoint anhält. Die Stoppuhr zeigt Dir nun mykrosekundengenau an, wie lange das im Prozessor mit Deiner eingestellten Taktfrequenz dauert.
Mußt halt einfach mal bissl rumspielen mit dem Simulator ;-)
greetz Rajko
Hallo Rajko,
vielen Dank für die ausführliche Information!
StoppWatch zeigt mir nun 999999.00 µs. Sollte also funktionieren.
Mit den Fusebits kämpfe ich gerade. Ich sitze hier mit einem Quarz - 2 MHz. (Das ist meiner Meinung nach eh der Beste, der sich für den Sekundentakt eignet.)
Alle Änderungen sind irgendwie unwirksam.
Die Fusebits sind irgendwie anders angegeben, als ich in Beschreibungen finde.
Ich dachte, wenn ich die Fusebits setze, dürfte das Programm am Ende ja erst Mal nicht mehr laufen. Wenn ich auf dem STK500 dann den Quarz einstecke, müßte alles wieder funktionieren.
Ich dachte, wenn ich
Ext. Crystal Osc.;Frequency 0.9-3.0 MHz
setze, sollte der interne Oszilator abgeschalten und der externe ein sein.
MfG LotharK
(Das ist meiner Meinung nach eh der Beste, der sich für den Sekundentakt eignet.)
Nö, da gibts Baudratenquarze mit "schiefen" Frequenzen wie 3,686400MHz oder 7,372800MHz da kannste gleich mit nem Timervorteiler von 1024 arbeiten
MfG der RoFo
Da kann ich jetzt leider nix zu sagen, da ich nicht weiß, wie das Studio und das STK500 die Fusebit-Programmierung handhabt.
Ich benutze einen parallelen ISP und das kleine Programm TwinAVR, dort werden mit die fuses so angezeigt, wie sie im Datenblatt stehen.
Bei den Fuses gibt es immer etwas durcheinander, weil die "programmierten" logisch 0 sind. Da hilft nur dreimal das "kleingedruckte" auf dem Datenblatt lesen und die Darstellungsart des Programmers genau ergründen.
greetz Rajko
Hallo Rajko,
schade, leider gibt es wohl niemanden, der sich mit den Fuses und dem Studio auskennt.
Ich habe schon vor einigen Tagen einen Thread eröffnet. Leider erfolglos. Auch die Suche im Net hat noch nichts gebracht.
MfG LotharK
Die Fusebits solltest Du auch nur verändern, wenn das Quarz angeschlossen ist, sonst läßt Dich der AVR nicht mehr ran.
Zumindest wenn er ein STK500 hat und das AVR Studio benutzt kann er diesen Punkt komplett außer acht lassen. Verfusen kann man sich damit nämlich nicht wirklich (Ausnahmen bestätigen wie immer die Regel). Im übrigen bestitzt das STK sowohl einen Quarz Sockel als auch einen programmierbaren Oszillator.
schade, leider gibt es wohl niemanden, der sich mit den Fuses und dem Studio auskennt.
1. auf das "AVR" Symbol klicken.
2. Programmer & Port auswählen.
3. auf "Connect" klicken
4. bei "Device" den richtigen Controller einstellen
5. auf die Reiterkarte Fuses klicken.
6. Staunen wie einfach es gehen kann.
Grüße,
Hanni
Hallo Hanni,
mittlerweile habe ich es selber hinbekommen. Wo die Fusebits im Studio einzustellen sind, mir völlig klar. Welche Option ich bei Externer Quarz auswähle, das wußte ich nicht. Am Ende hab ich dann noch den Fehler gemacht, und das Board nicht umgejumpert. Mittlerweile funktioniert es aber. Wozu die vielen Optionen bei Ext. Quarz sind, ist mir immer noch unklar.
@RoFo
Ich habe bei Conrad schon mal nach solchen Quarzen mit krummer Frequenz geschaut, bin aber nicht fündig geworden. Natürlich wäre so ein Quarz viel einfacher zu handhaben.
MfG LotharK
Ich habe bei Conrad schon mal nach solchen Quarzen mit krummer Frequenz geschaut, bin aber nicht fündig geworden. Natürlich wäre so ein Quarz viel einfacher zu handhaben.
MfG LotharK
Dann wäre die nächste "Lektion" es mit Timer1 (16bit) und im CTC-Mode zu programmieren. Mit Vorteiler 64 und Zählgrenze 31250 kommst Du bei 2MHz auch ohne weiten Aufwand auf den Sekundentakt.
greetz Rajko
Hm,
soweit bin ich wohl noch nicht. Werde es mir aber auf alle Fälle anschauen.
Danke - LotharK
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.