Forum: Mikrocontroller und Digitale Elektronik atmega8-16pu zu langsam


von Jens Träger (Gast)


Lesenswert?

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

von Sauger (Gast)


Lesenswert?

Moin,

sut_cksel int. rc osc. 1 MHz
kontra
$crystal = 4000000   ' 4 MHz


MFG

von Jens Träger (Gast)


Lesenswert?

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...

von Martin V. (oldmax)


Lesenswert?

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

von Sauger (Gast)


Lesenswert?

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

von Jens T. (jenstraeger)


Lesenswert?

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
4
                           ' crystal nutze stand hier natürlich 4000000
5
$baud = 19200
6
7
Config Portc.5 = Output
8
9
Config Servos = 1 , Servo1 = Portb.0 , Reload = 10  ' problemzeile 1
10
Enable Interrupts                                   ' problemzeile 2
11
12
13
Dim Durchlauf As Integer
14
Durchlauf = 0
15
16
Do
17
  Main:
18
19
  Portc.5 = 1
20
  Durchlauf = Durchlauf + 1
21
  Print "Main: Durchlauf=" ; Durchlauf
22
  Waitms 500
23
  Portc.5 = 0
24
  Waitms 500
25
Loop
26
27
End

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.
1
'Config Servos = 1 , Servo1 = Portb.0 , Reload = 10
2
'Enable Interrupts
------------------
ok
------------------
1
Config Servos = 1 , Servo1 = Portb.0 , Reload = 10
2
'Enable Interrupts
------------------
ok
------------------
1
Config Servos = 1 , Servo1 = Portb.0 , Reload = 10
2
'Enable Interrupts
------------------
ok
------------------
1
Config Servos = 1 , Servo1 = Portb.0 , Reload = 10
2
Enable Interrupts
------------------
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

von Martin V. (oldmax)


Lesenswert?

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

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

>>> 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.

von gass (Gast)


Lesenswert?

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
Config Servos = 1 , Servo1 = Portb.0 , Reload = 10
2
Enable Interrupts
------------------
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

von Bascommer (Gast)


Lesenswert?

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.
...

von Jens T. (jenstraeger)


Lesenswert?

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

von sebek (Gast)


Lesenswert?

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.

von kg (Gast)


Lesenswert?

Hallo!

Bei Benutzung des Servo Befehl sollte der Systemtakt
mindestens! 8MHz sein.

MfG

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.