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


von Paul H. (powl)


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
1
#include <avr/io.h>
2
#include <stdint.h>
3
#include <util/delay.h>
4
5
uint16_t delay;
6
7
int main(void)
8
{
9
  ADMUX = (1 << REFS1) | (1 << REFS0) | (0b00010);
10
  ADCSR = (1 << ADEN) | (0b101);
11
12
  while(1)
13
  {
14
    ADCSR |= (1 << ADSC);
15
    loop_until_bit_is_set(ADCSR, ADIF);
16
17
    delay = ADC;
18
19
    _delay_ms(delay);
20
  }
21
}

von Εrnst B. (ernst)


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:
1
void delay(int ms) {
2
  while(ms--) _delay_ms(1);
3
}

von holger (Gast)


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);
}

von Paul H. (powl)


Lesenswert?

wow Zeitgleich und noch mit gleichen Inhalt, nich schlecht ;-)

Danke!

von Εrnst B. (ernst)


Lesenswert?

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

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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.

von Paul H. (powl)


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.
1
#include <avr/io.h>
2
#include <stdint.h>
3
#include <util/delay.h>
4
5
#define ControlDDR DDRA
6
#define ControlPORT PORTA
7
8
#define Motor 6
9
#define Heizung 7
10
11
uint16_t delay;
12
13
int main(void)
14
{
15
  ADMUX = (1 << REFS1) | (1 << REFS0) | (0b00010);
16
  ADCSR = (1 << ADEN) | (0b101);
17
18
  ControlDDR |= (1 << Heizung);
19
20
  while(1)
21
  {
22
    if(bit_is_set(ControlPORT, Heizung))
23
  {
24
    ControlPORT &= ~(1 << Heizung);
25
  }
26
  else
27
  {
28
      ControlPORT |= (1 << Heizung);
29
  }
30
31
    ADCSR |= (1 << ADSC);
32
  loop_until_bit_is_set(ADCSR, ADIF);
33
34
    delay = ADC;
35
36
    while(delay--)
37
  {
38
    _delay_ms(1);
39
    }
40
  }
41
}

von Karl H. (kbuchegg)


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

von Paul H. (powl)


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

von Falk B. (falk)


Lesenswert?

http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Warteschleifen_.28delay.h.29

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

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.