Forum: Mikrocontroller und Digitale Elektronik Geschwindigkeit von Programm


von torsten (Gast)


Lesenswert?

Hallo.

Ich habe ein Testprogramm auf einem ATMega48, der ständig ein Zeichen 
über die UART ausgibt. An den Ausgängen des Treibers LTC485 hängen zwei 
antiparallel geschaltete LEDs, die auch so leuchten, wie ich es erwartet 
hatte.
Allerdings kommt mir die Übertragungsgeschwindigkeit etwas langsam vor:

int main(void)
{
  uart_init();

    while(1)
    {
       while (!(UCSR0A & (1<<UDRE0)))
     {
     }

     UDR0 = '!';

    _delay_ms(100);

    }

Ich habe ungefähr 140 Wechsel/Minute gezählt, also dauert ein Durchlauf 
~0,43 Sekunden. Allerdings sollte durch _ms_delay(100); doch eigentlich 
100ms + Übertragungsdauer verzögert werden!?

Bei einer Testweise eingestellten Baudrate von 300bd kommt mir die 
Übertragung auch langsam vor, da ja ein Byte 1/30 Sekunden dauert.

So, könnt Ihr mir sagen, wie ich herausfinden kann, ob die 
Geschwindigkeiten stimmen, bzw. ob ich vielleicht im Unklaren über 
<util/delay.h> bin?

vielleicht ist auch F_CPU (400000) nicht richtig eingestellt!?
Viele Grüße, torsten;)

von Peter II (Gast)


Lesenswert?

torsten schrieb:
> vielleicht ist auch F_CPU (400000) nicht richtig eingestellt!?

dafür müsste man wissen mit welchen Takt denn der µC läuft. Und auch die 
Fuse sind dafür entscheident.

von Falk B. (falk)


Lesenswert?


von Christian F. (cmf) Benutzerseite


Lesenswert?

F_CPU ändert nichts an der "wahren" Geschwindigkeit des µCs. Ist kein 
Quarz am µC angeschlossen und wird der interne Quarz verwendet, dann 
sind die Zeiten nunmal sehr ungenau, weil der Quarz ungenau ist.

Bei der Verwendung des UART sollte man aber im Idealfall einen externen 
Quarz verwenden.
(Ich habe selber einen Atmega8 mit internem Quarz in Betrieb, BAUD Rate 
bis 4600 funktioniert tadellos, aber dass ist eben nicht wirklich 
schnell)

von Peter II (Gast)


Lesenswert?

Christian F. schrieb:
> Ich habe selber einen Atmega8 mit internem Quarz in Betrieb

sehr unwahlscheinlihc, dann ein Atmel hat gar keinen internen Quartz.

Drin ist nur ein RC schwinkreis.

von Christian F. (cmf) Benutzerseite


Lesenswert?

Peter II schrieb:
> Christian F. schrieb:
>> Ich habe selber einen Atmega8 mit internem Quarz in Betrieb
>
> sehr unwahlscheinlihc, dann ein Atmel hat gar keinen internen Quartz.
>
> Drin ist nur ein RC schwinkreis.

Ja ok. Meine ich doch ;)

von Thomas E. (thomase)


Lesenswert?

torsten schrieb:
> vielleicht ist auch F_CPU (400000) nicht richtig eingestellt!?
400000 sieht eher nach Unsinn aus.

Christian F. schrieb:
> BAUD Rate bis 4600
4600 ist keine Standardbaudrate.

Es ist jetzt müssig zu raten, was du eigentlich meintest. Deshalb poste 
deinen Code, vollständig, kompilierbar, no Errors, no Warnings als 
Anhang.

mfg.

von torsten (Gast)


Lesenswert?

Nicht im Anhang, aber:


#include <avr/io.h>

#define F_CPU 4000000
#define BAUD 300

#include <util/setbaud.h>
#include <util/delay.h>




void uart_init(void)
{
  UBRR0H = UBRRH_VALUE;
  UBRR0L = UBRRL_VALUE;

  UCSR0B |= (1<<TXEN0);
    UCSR0C |= (1<<UMSEL01) | (1<<UCSZ01) | (1<<UCSZ00);



}



int main(void)
{
  uart_init();

    while(1)
    {
       while (!(UCSR0A & (1<<UDRE0)))
     {
     }
   UDR0 = '!';

    _delay_ms(100);

    }
}


Build succeeded.
========== Build: 1 succeeded or up-to-date, 0 failed, 0 skipped 
==========

Hoffe, das hilft weiter;)

von Peter II (Gast)


Lesenswert?

hast du am PC auch 300Baud eingestellt und wird das ! sauber übertragen?

von Werner (Gast)


Lesenswert?

Christian F. schrieb:
> Bei der Verwendung des UART sollte man aber im Idealfall einen externen
> Quarz verwenden.
>
> (Ich habe selber einen Atmega8 mit internem Quarz in Betrieb, BAUD Rate
> bis 4600 funktioniert tadellos, aber dass ist eben nicht wirklich
> schnell)

Ob die serielle Übertragung mit dem internen Oszillator bei der 
aktuellen Temperatur/Versorgungsspannung und ... funktioniert, hängt 
überhaupt nicht von der Baudrate ab, sondern nur vom relativen 
Taktfrequenzfehler des Baudratengenerators.

von Christian F. (cmf) Benutzerseite


Lesenswert?

Ich wollte damit auch nur zeigen, dass selbst bei einem ungenauen Takt 
der Uart immerhin bis 4800 Baud funktioniert. Klar heißt das nicht, dass 
das bei jedem so ist. Nur bei 300 sollte es selbst mit interner 
Taktversorgung immer ordentlich funktionieren.

von Falk B. (falk)


Lesenswert?

Christian F. schrieb:
> Ich wollte damit auch nur zeigen, dass selbst bei einem ungenauen Takt
> der Uart immerhin bis 4800 Baud funktioniert. Klar heißt das nicht, dass
> das bei jedem so ist. Nur bei 300 sollte es selbst mit interner
> Taktversorgung immer ordentlich funktionieren.

Noe, denn der relative Fehler bleibt immer noch. Prozentrechnung und so.

von lanai (Gast)


Lesenswert?

Man sollte vielleicht erstmal ermitteln, ob torsten einen 
Quarz/Quarz-Oszilator dran hat oder den internen RC-Schwingkreis nutzt.

torsten schrieb:
> Hoffe, das hilft weiter;)
Nein, wie deine Hardware funktioniert und wie du den µC konfiguriert 
hast (z.B. Fuses) ist auch noch sehr wichtig.
Also, Quarz ja/nein, Fuses richtig gesetzt, halt alles was in der [[AVR 
Checkliste]] zu deinem Problem passt. Die Liste hatte Falk Brunner im 
übrigen schon angegeben.

von torsten (Gast)


Lesenswert?

Habe mal die Fuses angeschaut:

Die Taktquelle war als interner Oszillator 8 MHz definiert.
Außerdem war dieses Bit gesetzt, was den Takt durch 8 teilt, das habe 
ich rausgenommen und schon läuft das ganze angemessen schnell.

Allerdings scheint es, dass ich mir einen Controller verfused habe, 
nachdem ich bei Taktquelle EXTFSXTAL_16KCK_14CK_65MS, da er nichts mehr 
macht.

Bei dem anderen Controller habe ich EXTFSXTAL_16KCK_14CK_4MS1 gesetzt.

Kann die Taktquelle der Grund für die Deaktivierung des einen 
Controllers gewesen sein? Warum?

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.