Hallo Forum,
ich habe ein Problem mit dem atmega8-16pu. Ich habe ein Programm mit
Bascom entwickelt um nach definierbarer zeit einen Lichtschalter zu
betätigen. Das Problem ist, dass der atmega zu langsam läuft. eine 500ms
schleife dauert ca. 2 sekunden. Es ist als ob das ckdiv8 (clock divide)
aktiviert wäre, nur gibt es dieses fuse beim atmega8-16pu nicht. ich
habe schon das datenblatt gewälzt, im internet gesucht, und diverse
cksel einsetllungen durchprobiert. das problem tritt bei auswahl und
beschaltung vom internen rc oszillator als auch beim externen crystal
auf (hier habe ich es mit 4MHZ versucht). der atmega ist immer zu
langsam. andere taktgeber habe ich noch nicht probiert, aber es muss
doch möglich sein den atmega auch wie oben dargestellt zu betreiben.
durch den fehler kann ich zum beispiel auch nicht die
rs232-schnittstelle nutzen (es kommt nur müll auf dem terminal-emulator
an).
folgende fuses hat das teil:
rstdisbl 0
wtdon 0
spien 1
eesave 0
bootsz boot flash size=1024 words Boot address=$0C00
bootrst 0
ckopt 0
bodlevel vrown-out detection at vcc=2.7v
boden 0
sut_cksel int. rc osc. 1 MHz
ich programmiere mit avr studio und habe schon alle kombination von
ckopt (0,1) und sut_cksel (internen rc osc., externer crystal) durch.
der atmega8-16pu läuft immer zu langsam. Kann das ganze vielleicht an
bascom liegen?
meine bascom defs:
$regfile = "m8def.dat"
$crystal = 4000000 ' 4 MHz
$baud = 38400
Baud = 38400
woran könnte das noch liegen? was mache ich falsch?
Dankeschön
Jens
hallo sauger,
das $crystal = 4000000 bei bascom hatte ich bei den einstellungen für
den externen crystal verwendet. beim internen rc oszillator hatte ich
dort $crystal = 1000000 stehen. der atmega8-16pu war aber immer noch zu
langsam. was mir aber noch einfällt war, dass er bei der der kombi
($crystal = 1000000, int. rc osc. 1 MHz) langsamer war als beim externen
crystal versuch.
irgendwie bekomme ichs nicht hin...
Hi
Da könnte man aber auch selber drauf kommen 500ms soll eine Schleife
dauern, doch du hast 2 Sek. Interner Clockk ist 1 MHz und zugeschaltet.
Auch wenn ich nicht viel von Bascom verstehe, so sehe ich doch, das du
dem Prozessor vorlügst, er hätte 4 MHz. Extern mag das vielleicht
stimmen, aber ist der externe Clock über die Fuses auch zugeschaltet?
Ich glaub das nicht... weil bei der Annahme, mit 4 MHz getaktet zu
werden eben diese Zeit sich bei 1 MHz vervierfacht. Deine RS 232 läuft
dann natürlich auch nicht, weil sie ebenfalls von der Takteinstellung
abhängt. Wie du die Fuses in Bascom setzen mußt, kann ich dir nicht
dagen, aber schau mal ins Tutorial.
Gruß oldmax
Moin,
wie Martin Vogel anmerkte sollte es direkt auffallen:
4 * 0,5 Sekunden = 2 Sekunden
Entweder passt das Programm nicht zu den Fuses (nach Änderung übersetzt
und übertragen?) oder die Fuses nicht zum Programm (auf den AVR
übertragen?)
MfG
Hallo nochmal,
ich habe jetzt alles nochmal durchgemessen und das programm samt
schaltung vereinfacht. die schaltung enthält nur noch den atmega, die
rs232 schnittstelle und eine led zur schleifenkontrolle. die rs232
schnittstelle funktioniert jetzt komischerweise. allerdings läuft die
schleife immer noch viel zu langsam (ca. 2 sekunden, statt 500ms). das
problem kann ich auf 2 zeilen eingrenzen, aber zunächst das programm:
1
$regfile = "m8def.dat" ' atmega8-16pu, wenn ich den atmega48-20pu
2
' nutze, stand hier natürlich "m48def.dat"
3
$crystal = 1000000 ' intern RC 1 MHZ, wenn ich den 4MHz extern
Meine Messungen habe ich mit einem atmega8-16pu und einem atmega48-20pu
durchgeführt. dabei habe ich mit den entsprechenden fuses beim 1MHz
internen RC und einem externen 4MHZ crystal getestet. es kam immer
dasselbe heraus.
------------------
zu langsam
------------------
Wie kann man erklären, dass meine Schleife zu langsam läuft, an diesen
zwei zeilen liegt? Sollte ich besser auf C umsteigen?
Grüsse
Hi
Zur Frage, ob der Umstieg auf eine andere Programmiersprache die Lösung
ist : Falsch ist in jeder Programmiersprache falsch, denn ein µC liest
kein Assembler und auch keinen C- Code, er kennt nur Bitmuster....
Also, wenn die Einstellung der Fuses zur Taktquelle richtig ist und auch
der Datenverkehr über die RS 232 läuft, dann kann nur der Prescaler des
Timers nicht richtig eingestellt sein. Die 10 ms, die du erwartest,
werden durch den "Vorteiler" auf 40ms gesetzt. Ein Prozessor wird nicht
von allein auf die Idee kommen, einfach langsamer zu sein.. . sowas
können nur Menschen. :)
Da ich auch nicht davon ausgehe, das du einen Sonder IC hast, bleibt nur
der Prescaler. Schau dir nochmal das Datenblatt an.
Gruß oldmax
>>> eine 500ms schleife dauert ca. 2 sekunden.>>> Es ist als ob das ckdiv8 (clock divide) aktiviert wäre,
2/0,5 = 8 --> Das ist der Anfang von Dyskalkulie :-o
> allerdings läuft die schleife immer noch viel zu langsam> (ca. 2 sekunden, statt 500ms)
Läuft die Schleife evtl. in 1 sec durch?
So ist sie nämlich programmiert:
1
Do
2
:
3
Waitms 500
4
:
5
Waitms 500
6
Loop
> die rs232 schnittstelle funktioniert jetzt komischerweise.
Glück gehabt mit dem internen Takt.
> Sollte ich besser auf C umsteigen?
Dann müsstest du dich nicht auf irgendwelche Funktionen incl. aller
seiteneffekte verlassen und hoffen, dass die laufen, sondern du wärst
selber verantwortlich dafür.
ebenso werden delay oder wait funktionen hart unterbrochen wenn der
interrupt kommt
wenn man nun einen ISR hat der schnell ist können aus 500ms schonmal ne
menge mehr werden
und da hier ein problem besteht wenn der interrupt kommt .. siht das
fast danach aus
siehe
1
ConfigServos=1,Servo1=Portb.0,Reload=10
2
EnableInterrupts
------------------
zu langsam
------------------
für servos brauch man glaube auch T = 20ms mit einer Ton von 1-2ms ( je
nach stellung des servos)
bist du sicher das dort Millisekunden angegeben werden ?
wenn es jetz 10µs wären würde es den verlängerten wait 500 effekt
erklären
mach dir einfach einen timer der die LED anseuert
und das alle 500ms ...
und vermeide gleich am anfang dieses wait gesabbel ...
ist das selbe in C _delay_ms() ...
bei initialisierungen ist eine verwendung von solchen warteschleifen ok
..
sobald die hauptschleife kommt ist das ding jedoch tödlich da es ALLES
was hier kommt ausbremst
und dann wundern sich viele das der µC trotz 16MHz so langsam ist
Hier hilft Lesen der Bascom-Hilfe.
Der Config Servo Befehl verursacht einen Interrupt alle Reload µs.
Bei einem Reload von 10 kommt bei 1MHz alle 10 Takte ein Interrupt.
Dein Controller ist also ständig mit Interrupts beschäftigt.
Klar, daß da keine Zeit für das Hauptprogramm übrig ist.
...
So...bin jetzt wieder zuhause. Erstmal danke für die Antworten.
Wie konfiguriere ich denn die Servos richtig, so dass ich den Servo
erstens noch auslösen kann, aber gleichzeitig ein präzises timing
bekomme?
Also wenn die waitms schleife nicht läuft, wie ich es mir vorstelle,
sollte ich dann:
1. den reload-wert bei den servos ändern (was wäre denn ein guter wert,
um nebenbei berechnungen durchzuführen? immerhin sagt das bascom manual:
"The reload value should be set to 10. After 20 mS, a new pulse will be
generated.")
2. einen timer nutzen für das toggle-led, der auch einen interrupt
generiert
3. erstens und zweitens zusammen
4. oder kann man den servo auch erst mitten in der programmausführung
initialisieren, bzw. bascom sagen, dass er den servo nur reloaden soll,
wenn ich ihn brauche. d.h. während der wartezeit wird der servo dann gar
nicht mehr refresht.
Grüsse
jens
was für ein servo willst du denn benutzen? Wenn du ein digitales nutzen
willst kannst du die ansteuerung per pwm realisieren da man nicht auf
die 20mS zyklen achten muss. man kann durch die kürzeren zyklen sogar
die gewünschte stellung schneller erreichen.