mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik [winavr] _delay_ms dauert zu lange


Autor: Christian M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab mir dieses Ding gekauft: eStick 
http://www.technikum-wien.at/studien/bachelorstudi...
Das Ding wird von der FH Technikum Wien für wenig Geld am Tag der 
offenen Tür verkauft.

Das ist ein µC Starterkit mit einem at90usb162 der mit 8Mhz getaktet ist 
und per Flip über USB Programmiert wird.

Funktioniert auch wunderbar nur folgendes:

Wenn ich eine Schleife Programmiere die ein _delay_ms enthält zB:
  while(1)
  {
  PORTB = 0xFF;

    for(i=0;i<256;i++)
    {
      PORTB = ~i;  /* Wert an LED */
      _delay_ms(10);
   
    }
  }
Dann dauert ein Durchlauf der for-Schleife nicht 2,56 Sekunden sondern 
20,5 Sekunden. Exakt 8-mal solange wie eigentlich gewünscht.

Die Frequenzangabe im AVR-Studio ist mit 8000000 auch korrekt 
eingestellt und das Ding ist wirklich mit 8Mhz getaktet (oder zumindest 
ungefähr, habe es nur mit dem Oszi überprüft)

Man verzeihe mir meine blöde Frage: Was mache ich falsch?
Kann da noch irgendwo irgendwas falsch eingestellt sein?

Danke schon mal im Voraus

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es soll AVRs mit integrierten Timern geben...

...

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und die CKDIV8 Fuse?

Autor: Christian M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für den Hinweis!
Mit Flip kann ich Fusebits weder auslesen noch verändern.

Irgendwie Doof, ich mal ein pin togglen und schauen ob ich so irgendwie 
auf den Takt komme.

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Takt im Studio auf 1MHz definieren, dann passt das Delay wieder.

Autor: Christian M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, das stimmt natürlich auch wieder.
Es wundert mich nur, weil in den Beispielen und in den Unterlagen von 
8Mhz die Rede ist.

Ich werde mich bei Gelegenheit mal dort erkundigen.

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Man kann die Fuses auch ohne Programmer per Programm auslesen.
#ifndef SPMCSR
#define SPMCSR SPMCR
#endif

void fuses(void)
{
    SPMCSR = 1<<BLBSET | 1<<SPMEN;
    uint8_t lo = pgm_read_byte(0);
    SPMCSR = 1<<BLBSET | 1<<SPMEN;
    uint8_t hi = pgm_read_byte(3);
    PRINTF("Fuses: low=%02X high=%02X\n", lo, hi);
}
Obacht: Die exakte Code-Sequenz ist hier wichtig, die ersten 4 Zeilen 
der Funktion sollten also exakt so bleiben und Optimierung muss 
eingeschaltet sein. Getestet mit WinAVR 20070525 ATmega32.

Autor: Christian M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke!

Sofern ich das jetzt Richtig kapiert habe, ist das entsprechende 
Fuse-bit gesetzt.

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Obacht Sprache. Bei einer gesetzten (programmierten) Fuse ist das 
Fusebit gelöscht und umgekehrt:

CKDIV=1 = /1 = Fuse gelöscht
CKDIV=0 = /8 = Fuse programmiert

Das hat schon manchen Einsteiger aus der Kurve geworfen.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Optimierung aktiviert?  Gibt zwar eine Warnung, wenn du's nicht
machst, aber hast du dir die Warnungen auch angesehen?

Autor: Christian M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Controller hat 4 Fusebytes
void fuses(void)
{
    SPMCSR = 1<<BLBSET | 1<<SPMEN;
    uint8_t lo = pgm_read_byte(0);
    SPMCSR = 1<<BLBSET | 1<<SPMEN;
    uint8_t hi = pgm_read_byte(3);
//    PRINTF("Fuses: low=%02X high=%02X\n", lo, hi);
  PORTB = lo;
}

So komme ich IMO an das richtige Fusebit
(Wie das Wirklich funktioniert habe, ich gestehe, überhauptnicht 
verstanden)

Gesetzt = 0, ist mir klar!



Warnung hats nicht gegeben (ausgenommen, die nicht verwendete Variable 
"hi")

Optimierung hab ich im Avr-Studio unter "Project Options"
auf "-Os" gestellt(also nichts verändert). Ist das Richtig?

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Yep, stimmt so. Wenn also CKDIV8=0 dabei rauskam passt es, denn der 
effektive Takt ist dann 1MHz.

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian M. wrote:

> (Wie das Wirklich funktioniert habe, ich gestehe, überhauptnicht
> verstanden)

Ist nichts anderes als das was im Datasheet steht (Boot Loader../Self 
Programming.../Reading the Fuse...). Die 2 Bits setzen und innerhalb von 
3 Takten das entsprechende Byte per LPM lesen.

Autor: Christian M. (chrisreg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Okay, danke!

Autor: Christian M. (chrisreg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eine, möglicherweise blöde, Frage habe ich noch.

Kann die USB Funktion und der Bootloader funktionieren, wenn das CKDIV8 
fuse versehentlich gesetzt ist?

Spricht wäre es möglich, dass das Fuse-Bit falsch programmiert ist aber 
der  Controller trotzdem funktioniert nur langsamer?

danke, Christian

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der USB Takt ist von der Fuse nicht betroffen.

Autor: Andi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas K. schrieb:
> Man kann die Fuses auch ohne Programmer per Programm auslesen.

Geht das auch umgekehrt? Kann ich über die Software die Fuses setzen?
In einem Programm habe ich folgendes gefunden:

FUSES =
{
   .low      = 0xFF,
   .high     = 0xD9,
   .extended = 0xFD,
};

Kann mir hier jemand diesbezüglich weiterhelfen?

Autor: Philipp Schaefer (pschaefer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
möglich ist das. Aber der Programmer muss das unterstützen.

siehe hier: 
http://www.nongnu.org/avr-libc/user-manual/group__...

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Philipp Schaefer schrieb:
> möglich ist das. Aber der Programmer muss das unterstützen.

Ich glaube eher er meint, ob das Programm auf dem µC selber direkt die 
Fuses schreiben kann. Und das geht nicht.

Autor: Verwirrter Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Soweit ich weiss kann man die CKDIV8 fuse auch aus dem Programm heraus 
setzen. Beim Atmega32u4 zum Beispiel über das CLKPR – Clock Prescaler 
Register.

Autor: Verwirrter Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Für den AT90USB162 sollte das auch gehen:
// 8 MHz
CLKPR &= ~((1 << CLKPS3) | (1 << CLKPS2) | (1 << CLKPS1) | (1 << CLKPS0));

// 1 MHz
CLKPR &= ~((1 << CLKPS3) | (1 << CLKPS2));
CLKPR |=   (1 << CLKPS1) | (1 << CLKPS0);

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Soweit ich weiss kann man die CKDIV8 fuse auch aus dem Programm heraus
>setzen. Beim Atmega32u4 zum Beispiel über das CLKPR – Clock Prescaler
>Register.

Ein gesetzte CKDIV8-Fuse bewirkt, das CLKPR nach einem Reset auf einen 
Teiler von acht gesetzt wird. Das Überschreiben von CLKPR hat aber 
keinen Einfluss auf die CKDIV8-Fuse.

MfG Spess

Autor: Verwirrter Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
spess53 schrieb:
> Hi
>
>>Soweit ich weiss kann man die CKDIV8 fuse auch aus dem Programm heraus
>>setzen. Beim Atmega32u4 zum Beispiel über das CLKPR – Clock Prescaler
>>Register.
>
> Ein gesetzte CKDIV8-Fuse bewirkt, das CLKPR nach einem Reset auf einen
> Teiler von acht gesetzt wird. Das Überschreiben von CLKPR hat aber
> keinen Einfluss auf die CKDIV8-Fuse.
>
> MfG Spess

Das stimmt natürlich, da hab ich mich sehr schlecht ausgedrückt.

Was ich eigentlich sagen wollte, ist das dies für den OP ein einfacher 
workaround ist, wenn er Programme mit 8MHz ausführen will.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Verwirrter Anfänger schrieb:
> Was ich eigentlich sagen wollte, ist das dies für den OP ein einfacher
> workaround ist, wenn er Programme mit 8MHz ausführen will.

Um den OP geht es aber gar nicht mehr (mal auf das Datum geschaut?).
Es geht momentan um
> Andreas K. schrieb:
>> Man kann die Fuses auch ohne Programmer per Programm auslesen.
>
> Geht das auch umgekehrt? Kann ich über die Software die Fuses setzen?
Und da lautet die Antwort ganz simpel: Nein.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.