www.mikrocontroller.net

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

Autor: Christian M. (Gast)
Datum: 29.03.2008 17:57

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: 29.03.2008 17:59

Es soll AVRs mit integrierten Timern geben...

...
Autor: Andreas Kaiser (a-k)
Datum: 29.03.2008 18:00

Und die CKDIV8 Fuse?
Autor: Christian M. (Gast)
Datum: 29.03.2008 18:13

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 Kaiser (a-k)
Datum: 29.03.2008 18:22

Takt im Studio auf 1MHz definieren, dann passt das Delay wieder.
Autor: Christian M. (Gast)
Datum: 29.03.2008 18:32

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 Kaiser (a-k)
Datum: 29.03.2008 18:50

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: 29.03.2008 20:51

Danke!

Sofern ich das jetzt Richtig kapiert habe, ist das entsprechende
Fuse-bit gesetzt.
Autor: Andreas Kaiser (a-k)
Datum: 29.03.2008 20:56

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: 29.03.2008 21:06

Optimierung aktiviert?  Gibt zwar eine Warnung, wenn du's nicht
machst, aber hast du dir die Warnungen auch angesehen?
Autor: Christian M. (Gast)
Datum: 29.03.2008 21:36

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 Kaiser (a-k)
Datum: 29.03.2008 22:27

Yep, stimmt so. Wenn also CKDIV8=0 dabei rauskam passt es, denn der
effektive Takt ist dann 1MHz.
Autor: Andreas Kaiser (a-k)
Datum: 29.03.2008 22:39

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: 30.03.2008 00:28

Okay, danke!
Autor: Christian M. (chrisreg)
Datum: 30.03.2008 14:21

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 Kaiser (a-k)
Datum: 30.03.2008 19:25

Der USB Takt ist von der Fuse nicht betroffen.

Antwort schreiben

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

Wichtige Regeln - erst lesen, dann posten!

  • Suchfunktion und Betreffsuche benutzen - vielleicht gibt es schon einen ähnlichen Beitrag
  • Aussagekräftigen Betreff wählen
  • Im Betreff angeben um welchen Controllertyp es geht (AVR, PIC, ...)
  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
  • JPEG-Dateien (.jpg) nur für Fotos verwenden, Schaltpläne, Screenshots usw. als PNG oder GIF anhängen

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [pre]vorformatierter Text (z.B. Code in anderen Sprachen)[/pre]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel






webmaster@mikrocontroller.netImpressumWerbung auf Mikrocontroller.net