mikrocontroller.net

Forum: Compiler & IDEs AVR GCC erzeugt unmengen an code?


Autor: Paul H. (powl)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi!

Ich habe die ganze zeit in Assembler programmiert und probiere nun mal 
C. Leider klappt es noch nicht so. Ich habe hier versucht eine LED zum 
blinken zu bringen. Die Blinkfrequenz sollte mit einem Potentiometer 
(Spannungsteiler) am ADC2 bestimmt werden. Hierzu muss der ADCwert als 
delay-Wert genommen werden.

Allerdings erzeugt mir dieser kleine Code 4kb?!

Program:    3956 bytes (193.2% Full)
(.text + .data + .bootloader)

Data:        266 bytes (207.8% Full)
(.data + .bss + .noinit)

Was habe ich da denn falsch gemacht? Wenn ich in delay einen normalen 
Wert eintrage funktioniert es. Wenn ich ADC zuerst in eine andere 
Variable einlese und dann in delay kopiere geht es wieder nicht. Wenn 
ich ADC direkt in die funktion _delay_ms(); einsetze funktioniert es 
auch nicht. Unabhängig vom Optimierungsgrad.

nutze AVRStudio und die neuste Version von GCC.

lg PoWl
#include <avr/io.h>
#include <stdint.h>
#include <util/delay.h>

uint16_t delay;

int main(void)
{
  ADMUX = (1 << REFS1) | (1 << REFS0) | (0b00010);
  ADCSR = (1 << ADEN) | (0b101);

  while(1)
  {
    ADCSR |= (1 << ADSC);
    loop_until_bit_is_set(ADCSR, ADIF);

    delay = ADC;

    _delay_ms(delay);
  }
}

Autor: Εrnst B✶ (ernst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
_delay_ms darf nur mit Konstanten als Parameter aufgerufen werden, sonst 
zieht der GCC da die gesamte float-math Library mit rein.

wenns dynamisch sein soll, geht sowas:
void delay(int ms) {
  while(ms--) _delay_ms(1);
}

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>    _delay_ms(delay);

delay muss eine Konstante sein. Sonst fängst du dir ne komplette
Floating Point Lib ein.

void delay1ms(unsigned int time)
{
 while(time--) _delay_ms(1);
}

Autor: Paul H. (powl)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wow Zeitgleich und noch mit gleichen Inhalt, nich schlecht ;-)

Danke!

Autor: Εrnst B✶ (ernst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hehe... Die Frage kommt recht häufig... Bin ich doch nicht der einzige, 
der die Antwort auf ne Funktionstaste gelegt hat ;)

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

Bewertung
0 lesenswert
nicht lesenswert
Besser: Timer benutzen.  Den ADC-Wert nimmst du als Eingabe ins OCR1A
(passend nach links geschoben) und betreibst den Teiler 1 im CTC-Modus.

Autor: Paul H. (powl)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja das mit Timern kommt noch, ist nur zum Probieren. Die LED, hier als 
"Heizung" gekennzeichnet, flackert allerdings bei niedrigen ADC-Werten 
bzw. wenn ich den Eingang auf Masse lege. Woran könnte das denn nur 
liegen?

//Edit: mit einem 100nF Kerko zwischen GND und AREF funktionierts 
besser, flackert aber immernoch etwas.

//Edit2: Des Rätsels Lösung: mein doofes Steckboard ist wiedermal dran 
schuld. Die eine Masseschiene ist nicht gut mit der anderen verbunden.
#include <avr/io.h>
#include <stdint.h>
#include <util/delay.h>

#define ControlDDR DDRA
#define ControlPORT PORTA

#define Motor 6
#define Heizung 7

uint16_t delay;

int main(void)
{
  ADMUX = (1 << REFS1) | (1 << REFS0) | (0b00010);
  ADCSR = (1 << ADEN) | (0b101);

  ControlDDR |= (1 << Heizung);

  while(1)
  {
    if(bit_is_set(ControlPORT, Heizung))
  {
    ControlPORT &= ~(1 << Heizung);
  }
  else
  {
      ControlPORT |= (1 << Heizung);
  }

    ADCSR |= (1 << ADSC);
  loop_until_bit_is_set(ADCSR, ADIF);

    delay = ADC;

    while(delay--)
  {
    _delay_ms(1);
    }
  }
}

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Paul Hamacher wrote:
> Ja das mit Timern kommt noch, ist nur zum Probieren. Die LED, hier als
> "Heizung" gekennzeichnet, flackert allerdings bei niedrigen ADC-Werten
> bzw. wenn ich den Eingang auf Masse lege. Woran könnte das denn nur
> liegen?

Hast du den Optimizer eingeschaltet?
_delay_ms liefert nur dann einigermassen korrekte Zeiten,
wenn der Optimizer an ist.

Ansonsten:
Du solltest dir eher Sorgen um die langen Zeiten machen.
Der ADC liefert bei voller Aussteuerung einen Wert von 1023.
1023 mal 1ms macht weit über 1 Sekunde Zeit-Differnz zwischen
ein und aus der LED

Autor: Paul H. (powl)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie gesagt, ist nur ein kleiner Test. ich probiere nur etwas rum um 
Erfahrungen mit C und dem Compiler zusammeln :-) Danke für die Hilfe!

lg PoWl

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
http://www.mikrocontroller.net/articles/AVR-GCC-Tu...

Wer lesen kann ist klar im Vorteil. Sogar auf Deutsch.

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.