Code braucht extrem viel Speicher

Gast #2130814
Lesenswert?

Hallo,

habe mir gerade einen ATMEGA 48-20 geholt, der 4KB Speicher hat.
4KB sind nicht die Welt, sollten für meine Zwecke jedoch ausreichen.

Ich habe 3 LEDs an PORTB angeschlossen.
Diese will ich zum Test ein- und ausblenden.

Dafür habe ich folgenden kurzen Code geschrieben:
1
#define F_CPU 1000000UL
2

3
//-----------------------------------------------------------------------------
4
// INCLUDES
5
//-----------------------------------------------------------------------------
6
#include <avr/io.h>
7
// #include <avr/interrupt.h>
8
// #include <avr/sleep.h>
9
#include <util/delay.h>
10

11

12
int main(void)
13
{
14
  //directions
15
  DDRB = 0b00000111;
16

17
  PORTB |= 0b00000111;
18

19
  uint8_t up = 1;      //Zaehlrichtung
20
  uint8_t counter = 0; //Zaehlvariable
21

22
  while(1)
23
  {
24
    _delay_us(counter);  //warte 0-255us
25
    PORTB &= 0b11111000;
26
    _delay_us(255-counter);  //warte 255-0us
27
    PORTB |= 0b00000111;
28

29
    if (counter == 255) up=0;  //IF1
30
    if (counter == 0) up=1;    //IF2
31

32
    if (up==1)                 //IF3
33
    {
34
      counter++;
35
    }
36
        else
37
    {
38
      counter--;
39
    }
40
  }
41
}

Nach dem Kompilieren mit der (-Os)-Option kommt eine Code-Größe von 4602 
Bytes raus. Das ist viel zu viel für meinen µC.

Zum test habe ich die drei IF-Abfragen mal auskommentiert. Größe nach 
dem Kompilieren: 176 Bytes!

Was mache ich falsch???
Kann es sein, dass diese 3 IF-Abfragen wirklich den Code von 176 Bytes 
auf 4602 Bytes aufblähen?

Danke für eure Tipps!
Gast #2130820
Lesenswert?

>_delay_us(counter);  //warte 0-255us
und
> _delay_us(255-counter);

..machtens möglich. Mach stattdessen Warteschleifen a la
1
for (uint8_t i = 0; i < counter; i++) _delay_us(1);

Details stehen in der Doku.
#2130832
Lesenswert?

g457 schrieb:
>>_delay_us(counter);  //warte 0-255us
> und
>> _delay_us(255-counter);
>
> ..machtens möglich. Mach stattdessen Warteschleifen a la
1
for
2
> (uint8_t i = 0; i < counter; i++) _delay_us(1);
>
> Details stehen in der Doku.

Genau, wenn man sich den erzeugten Assemblercode ansieht stehen da 
solche Monster wie 0x430 <__floatunsisf> und ähnliches was auf dazu 
gelinkten Floatbloat hinweist. Das Verursacht das enorme Aufblähen des 
Codes.
Gast #2130837
Lesenswert?

Vielen Dank, das hat tatsächlich geholfen!!!
Verrückt, was eine For-Schleife gleich ändert...

Kann ich die Floating-Point-Option auch in den "configuration options" 
vom AVR Studio abschalten? Nutze im Moment noch kein Makefile, muss mich 
da erst noch etwas mehr einarbeiten...
Gast #2130841
Lesenswert?

In 
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Warteschleifen_.28delay.h.29 
steht "Die Bibliotheksfunktionen funktionieren allerdings nur dann 
korrekt, wenn sie mit zur Übersetzungszeit (beim Compilieren) bekannten 
konstanten Werten aufgerufen werden. Der Quellcode muss mit 
eingeschalteter Optimierung übersetzt werden, sonst wird sehr viel 
Maschinencode erzeugt und die Wartezeiten stimmen nicht mehr mit dem 
Parameter überein."

Aber am Ende ists sowieso wurscht: in der Realität wird wohl keiner mit 
Delay Funktionen arbeiten
#2131403
Lesenswert?

http://www.nongnu.org/avr-libc/user-manual/group__util__delay.html

In order for these functions to work as intended, compiler optimizations 
must be enabled, and the delay time must be an expression that is a 
known constant_at_compile-time. If these requirements are not met, the 
resulting delay will be much longer (and basically unpredictable), and 
applications that otherwise do not use floating-point calculations will 
experience severe code bloat by the floating-point library routines 
linked into the application.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren