Hallo,
ich möchte einen Rechteckgenerator mit dem Controller Atmega8 bauen.
Es sollen Frequenzen von 1 Hz bis 1MHz ausgewählt werden.
Die Menüsteuerung mit einlesen der Werte (Frequenzbereich,
Tastverhältnis und Frequenz) funktioniert bereits.
Ein Problem was ich habe ist die Gestalltung der Warteschleife für die
Impulszeit und die Pausenzeit.
In etwa habe ich mir das so vorgestellt:
Bsp 1Hz und Tastverhältnis 50%:
Do
PORTB.0=1
warteschleife für Impuls (0,5s)
PORTB.0=0
warteschleife für Pause (0,5s)
Loop
Mein Problem ist die Durchführung der Takte (z.B. 0,5s)
Weil meine Prozessortaktung 3,686411Mhz beträgt müssen für 1s Wartezeit
3686411 Takte durchgeführt werden.
Für 0,5s also 1823405,5 Takte (die Hälfte).
Jetzt zu meinem Problem:
i=0
Do
i=i+1
Loop XX
Wenn ich das jetzt richtig verstehe besteht diese Schleife aus 3 Takten
also muss Sie 1823405,5/3=607802 mal Wiederhohlt werden.
Ist das Richtig so?
MfG Tmelle
Die Schleife besteht aus erheblich mehr als 3 Takten, schau Dir mal den
generierten Assemblercode an. Da siehst Du genau, was passiert.
Grob geschätzt: Mit einem Takt von 3MHz kannst Du 1MHz max. Frequenz
vergessen (siehe oben).
Mit Atmegas hab ich keine Erfahrung aber nur mal so als Tip: Bei einem
PIC ist der Systemtakt nur ein viertel des Oszilatortaktes, d.h.u.a. es
müssen vier Ozilatortakte vergehen bis sich überhaupt ein Portpin ändern
kann bzw. eine Änderung im PIC ankommt. Beim Atmega könnte ich mir
vorstellen ist es ähnlich und dann wird es aber eng mit ca. 3 Mhz
Oszilatortakt 1 Mhz Takt an den Pins zu generieren.
Hallo Tmelle,
also ich kann dich beruhigen, der Atmega macht pro Oszilatortakt ein
Prozessortakt. Allerdings kommen mir für ein 1MHz Rechtecksignal 3,6Mhz
Prozessortakt recht wenig vor. Ich würde höher gehen und vor allem einen
Timer inkl. Interrupt und Timercompareregister benutzen. Damit erfolgt
das Pintoggeln automatisch und Du brauchst dich überhaupt nicht mehr um
irgendwelche Warteschleifen zu kümmern. Im Hauptprogramm werden die
Werte eingelesen und nur die entsprechenden Register des Timers gesetzt.
Siehe auch: http://www.mikrocontroller.net/articles/AVR-Tutorial:_Timer
Gruß, Steffen
Hallo,
danke für eure Antworten, ich werde das Mal mit den Timern Probieren.
Mein Problem ist, dass bei dem Generator das Tastverhältnis, also das
Verhältnis Pausenzeit/Impulszeit einstellbar sein soll.
Das Hauptprogramm ließt die gewünschte Frequenz und das Tastverhältnis
ein.
(bereits Fertig).
Der Prozessortakt wird beim fertigen Gerät dann auf 16MHz erhöht. Zum
Entwickeln werde ich erstmal einen Frequenzbereich von 1-100Hz benutzen.
Es wäre nett wenn ihr mir helfen könntet.
Sry für Tripplepost aber der Timer funktioniert jetzt auch mit der
Einstellung des Tastverhältnisses.
Jetzt fehlt mir die Möglichkeit den Prescaler des Timers umzuändern bzw.
zu senken, damit höhere Frequenzen möglich sind.
Ich habe das wiefolgt versucht:
Disable
Reset Timer1
If Presc = 8 Then Config Timer1 = Timer , Prescale = 8
If Presc = 64 Then Config Timer1 = Timer , Prescale = 64
Das Funktioniert leider nicht weil (ich denke), der Compiler (in diesem
Falle Bascom) sich die ganzen Configzeilen am Anfang raussucht und diese
zuerst in hexcode umwandelt.
Gibt es eine möglichkeit den Prescaler innerhalb des Programms zu
ändern?
MfG Tmelle
@ Tmelle (Gast)
>Gibt es eine möglichkeit den Prescaler innerhalb des Programms zu>ändern?
Sicher. Einfach das Register TCCR1B direkt beschreiben. Siehe
Datenblatt.
MFG
Falk
Also ich habe das bei meinem ersten Projekt so gemacht, dass ich nen
kleinen prescaler verwendet habe.
Dann wird mit jedem Interrupt des Timers einfach ein Register
Decrementiert. Ist ein bestimmter Wert erreicht, von mir aus EA, war
meine Periode zu Ende und der Wert wurde wieder auf 00 gesetzt.
Das gleiche Register habe ich benutzt um das Tastverhältnis einzustellen
also wird z.b. bei FA einfach der Portpin invertiert und bei 00 noch
einmal.
Du brauchst quasi 3 Register: Zähler, Wert-Tastverhältniss und
Wert-Frequenz.
Ich gebe aber zu bedenken, dass diese Methode wohl nicht die effektivste
ist, da du nur 255 stufen hast - man könnte ggf. 2 register zum Zählen
nehmen. Das mit den die vergehen bis der Portpin invertiert wird Takten
sollte sich aber ausgleichen, bzw. minimal sein vllt. 2 takte, da er
immer die gleiche schleife fährt.
Anfänger-Idee halt.
Hallo,
eure Beträge haben mich schonmal weiter gebracht. Aber leider muss ich
euch mit einem weiteren Problem nerven:
Frequenzbereich 1: 1Hz-100Hz Prescaler=64
Frequenzbereich 2: 100Hz-1kHz Prescaler=8
Die Einstellung der Frequenz (F bzw 2f), des Tastverhältnisses (Tv) und
des Prescalers (Presc) werden durch das Hauptprogramm eingelesen bzw.
festgelegt (funktioniert so wie es soll).
Der Frequenzbereich 1Hz-100Hz funktioniert auch so wie er soll (Toleranz
ca 0.4 Hz)
Nur der Frequenzbereich 100Hz - 1kHz Funktioniert nicht so wie er soll,
die Werte für die Warteschleifen berechnen sich jedoch korekt. Ich weiss
nicht woran das liegt, sitze hier jetzt schon 2 Std. und suche den
Fehler.
Ich hoffe ihr als erfahrenen Mikrocontroller-Programmierer/innen könnt
mir auch hier weiterhelfen.
Hier noch der Code des Programmteils welche für den Betrieb zuständig
ist:
Das du den Timer einsetzt ist schon OK.
Aber du solltest ihn besser Nutzen, besonderst je näher
deine Ausgabefrequen an die Taktfrequenz heranreicht.
Du willst ein Rechtecksignal mit variabler Frequenz und
einstellbarem Verhältnis.
Das einstellen eines bestimmten Dutys ist eigentlich
eine PWM. Das kann der Timer 1 in Hardware machen und
dabei einen Pin (OSC1A/B) ansteuern.
Einmal gestartet braucht sich das Programm nicht mehr
darum kümmern, kann die Werte jedoch bei Bedarf
ändern (OCR1A/B-Register).
Die variable Frequenz ergibt sich aus dem TOP-Wert des Timers.
Bei einer 8 Bit PWM ist er 255 bei 10 sind es 1023.
Aber der Mega kann (wenn man es ihm sagt ICR1-Register) auch bis
617 Zählen.
Die Frequenz ist immer
Jetzt versuch mal in deinem Programm zuerst ein PWM und dann das
Verändern des TOP-Wertes.
Tutorial und Datenblatt helfen.
Am Ende dann ICR1 aus Frequenzeingabe berechnen und den Duty
OCR1 als Prozentualen Anteil von ICR1.
Möglich sind bei deinem Quarz ca. 3,6 kHz mit 0,1% Schritten.
avr
Hallo,
ich bin jetzt schonmal weiter, die PWM funktioniert jetzt. Ich habe nur
noch keine Idee wie ich den TOPwert des Zählers ändere.
Also die Timer im PWM Modus arbeiten ja wenn ich das richtig aus den
Tutorials verstanden habe so:
-Zählen (vorwärts)
-Bei ereichen des Comparewertes Port auf High.
-TOPwert ereicht.
-Zählen (rückwärts)
-Bei ereichen des Comparewertes Port wieder auf Low.
-Bei ereichen von 0 wieder von vorne beginnen.
Den Comparewert berechne ich wie du sagtest über das Tastverhältnis. Was
auch schon gut Funktioniert (100% Prüfen konnte ich das noch nicht weil
mein Oszilloskop gerade repariert wird).
Jetzt fehlt mir nur noch die Möglichkeit den TOPwert festzulegen (Aus
dem Datenblatt bin ich auch nicht sonderlich schlau geworden weil mir
als Einsteiger in Microcontroller noch der Überblick darin fehlt).
MfG Tmelle
Hallo,
ich komme mit den ganzen Einstellungen in den Registern irgendwie nicht
zurecht. Ich bekomme mit meinen Einstellungen zwar Frequenzen heraus
aber nicht die die ich will. Evtl könnte mir ja jemand eine Timer Config
erstellen, wäre echt net.
MfG
Hi,
dein Problem sind nicht die Register sondern das Grundverständnis.
Angenommen du hast eine 1Mhz Clock und willst ein 100Hz Signal
haben(Prescaler 1).
Der Timer muss dazu 100 Mal von 0 nach top und wieder nach 0. Das wird
dann alle 1000000hz/100Hz = 10000 Taktzyklen passiert sein müssen. Um
den Top Wert zu erhalten wird das noch durch 2 geteilt. Also müsste das
Top Register 5000 haben. Für ein Tasverhältnis von 30% muss in das
Output Compare Register also 1500.
Jetzt musst du nur noch den Prescaler setzen damit die Werte in die
Register passen.
Condi
Genau so habe ich das ja berechnet, also ich denke das Prinzip habe ich
schon verstanden.
Ich weiss nur noch nicht was der Unterschied von z. B. ICR1L und ICR1H
ist.
Hi
>Ich weiss nur noch nicht was der Unterschied von z. B. ICR1L und ICR1H>ist.
ICR1 ist ein 16 Bit Register. ICR1L sind davon die niederwertigen und
ICR1H die höherwertigen 8 Bit. Gleiches gilt für die OC-Register. Zu
beachten ist, das erst das H-Byte und danach das L-Byte geschrieben
wird. Beim Lesen erst L-Byte, danach H-Byte.
MfG Spess
Also wenn ich jetzt zum Beispiel in IRC1 987 schreiben möchte, muss ich
dann 987 erst in binärcode umwandeln um den Wert in das Register zu
schreiben, oder wie stelle ich das am besten an?
MfG
Tmelle
Sry, war gerade bei 10 Bit. 987 geht natürlich nicht, als Beispiel
könnte natürlich der Wert 234 sein. Oder ist das Regiter beim 10 Bit
Modus auch in 2x 5 Bit eingeteilt?
Hi
>muss ich dann 987 erst in binärcode umwandeln...
987=$03DB=0000001111011011b
Bascom ist egal, wie du einen Wert angibst. Richtig geschrieben versteht
es dich schon.
>Sry, war gerade bei 10 Bit. 987 geht natürlich nicht,...
Wieso? 10 Bit: 0...1023
>Genau so habe ich das ja berechnet, also ich denke das Prinzip habe ich>schon verstanden.
Wenn ich deinen letzten Post lese, würde ich das bezweifeln.
MfG Spess
Ich habe oben schon von 10 Bit geredet aber im Post davor ging es um
8bit, deshalb habe ich mich korrigiert.
Ich meinte: Ich war gerade bei 10 Bit, 987 geht natürlich bei 8 Bit
nicht.
Sry habe mich unverständlich ausgedrückt.
Mein Problem mit in Binär umwandeln war weil ich in zb. ICR1H zB. die 4
höherwertigen Bits und in ICR1L die 4 niederwertigen Bits
hineinschreiben muss.
Bascom erkennt aber leider nicht das komplette Register IC1R (wird nicht
durch Bascom in Großbuchstaben und in andere Farbe geändert) somit muss
ich ja den umweg über ...H und ...L gehen.
Hier müsste eine Frequenz von 3686411/(1024*1000)= 3,6Hz herauskommen,
aber der Ausgang verändert sich nicht, sprich f=0Hz.
Entschuldigung das ich euch mit meinen "einfachen" Problemen nerve, ich
hoffe ihr helft mir trozdem.
Gruß Tmelle
Hi
> 'Input Capture Register (TOP-Wert)> 'Ich kann mir denken das das falsch ist, aber wie Teile ich am> besten die Dezimalzahl?> Icr1l = 1000> Icr1h = 1000
Die 1000 passen nicht in ICR1L oder ICR1H.
In Bascom sollte es etwa so gehen(ohne Gewähr):
DIM i as Word
i=1000
ICR1H= High(i)
ICR1L= Low(i)
MfG Spess
Hi
>Hm, ähm was sagt denn die Hilfe dazu?>http://avrhelp.mcselec.com/config_timer1.htm....
Hier wird gerade versucht dem OT etwas 'fortgeschrittenere'
BASCOM-Programmierung zu vermitteln. Und dann kommst du mit dem
Urschleim aus der Hilfe.
MfG Spess