www.mikrocontroller.net

Forum: GCC Code Explodiert - Tiny13


Important announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Stefan Marquardt (joker)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Hallo zusammen,

so Ostern ist da. Das heißt wieder Zeit zum Basteln ;)

Ich habe folgendes Problem:

Ich will einen Tiny 13 als Taktgeber für zwei Servos nehmen.

Wenn ich aber eine Pinabfrage mit einer if schleife mache explodiert mir 
der Code auf über 4 kB.

Kommentiere ich sie aus, dann ist alles kein Problem.

Die Abfrage ist dazu da, um einen Variablenwert zu ändern.

Also alle

If (Pin Low)
{
 Variable = Wert X
}

Woran liegt das? Im Netz gibt es so viele codes für den Tiny13, die auch 
if Schleifen enthalten.

Auf eure Hilfe freue ich mich

Gruß Stefan

Autor: guenni (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Ersetze die IF-Schleife durch eine FOR-Abfrage!

Autor: Floh (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Stefan Marquardt schrieb:
> Wenn ich aber eine Pinabfrage mit einer if schleife mache explodiert mir
>
> der Code auf über 4 kB.

Wahrscheinlich baust du in die if eine float-Variable ein?
Zeig mal den richtigen Code.

Autor: strunz (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Zufällig delay_ms mit einer Variable aufgerufen?

Autor: Stefan Marquardt (joker)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Hallo,

bin gerade unterwegs.

Aber:

die Variablen sind alt int deklariert.

Wie schon richtig erraten:

Ich habe Delay_ms drinne.

Aber nur das hbelegt mir gerade mal 6 % im Flash.

sobald ich aber eine If-Abfrage wieder einkommentiere sprengt's den Tiny

Grüße Stefan

Autor: Marius Wensing (mw1987)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Dann hast du sicherlich delay_ms mit nicht-konstanten Parametern 
aufgerufen... Dann kommt automatisch das ganze Floating-Point-Zeug mit 
in den Code und sprengt den Flash.

Aber ohne Code können wir hier eigentlich nur die Glaskugel befragen und 
die ist im Osterurlaub.

Gruß
Marius

Autor: Stefan Marquardt (joker)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Alles klar.

Melde mich später wieder.

Tut mir Leid. Wollte keine Glaskugelfragen stellen ;)

Grüße Stefan

Autor: Stefan Marquardt (joker)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
So jetzt:

das ist der Code:

#include <avr/io.h>
#include <stdlib.h>
#include <stdint.h>
#ifndef F_CPU
#define F_CPU 1000000UL
#endif
#include <util/delay.h>

int clk_servo_u;
int clk_servo_o;


int main (void)
{

clk_servo_u = 1.5;

DDRB = 0b00000011;     // PINB0, PINB1 sind Augänge --- PINB2 - PINB7 Eingänge
PORTB = 0b11111100;    // Interne Pullups an PINB2 - PINB7 aktiv


  while(1)
    {
      if (PINB &= ~ (1<<PINB2))  
      {
        clk_servo_u = 20;
      }
//
  //    else if (PINB & (1<<PB2))
  //      {
  //      clk_servo_u = 1.5;
  //      }



  //    if (PINB &= ~ (1<<PINB3)) 
  //    {
  //      clk_servo_o = 20;
  //    }
  //    else if (PINB & (1<<PB3))
  //      {
  //      clk_servo_o = 1.5;
  //      }


      PORTB |= (1<<PB0);
      _delay_ms(clk_servo_u);
      PORTB &= ~ (1<<PB0);
      _delay_ms(20-clk_servo_u);

      PORTB |= (1<<PB1);
      _delay_ms(clk_servo_u);
      PORTB &= ~ (1<<PB1);
      _delay_ms(20-clk_servo_u);
    }


}    


Autor: Patrick (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Stefan Marquardt schrieb:
> _delay_ms(clk_servo_u);

Na, da haben wir's ja auch schon, was bereits die Vorposter vermuteten: 
Delay mit nicht-konstanten Parametern aufgerufen...

Autor: Peter II (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
wie schon oben vermutet,  _delay_ms muss mit einer konstanden aufgerufen 
werden!

> int clk_servo_u;
> clk_servo_u = 1.5;

was soll das, glaubst du wirklich das in ein int soetwas reinpasst?

Autor: Stefan Marquardt (joker)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Wieso explodiert der code erst wenn ich die If-Abfrage einkommentiere?

Autor: Sparfuchs (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Stefan Marquardt schrieb:
> int clk_servo_u;
> int clk_servo_o;

Reichen nicht uint8_t? Sonst platzt auch noch das RAM. ;-)

Autor: Roland Praml (pram)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
ist die IF-Abfrage weg, kann zur Compilezeit schon bestimmt werden, dass 
_delay_ms IMMER mit dem gleichen Parameter aufgerufen wird und wird 
wegoptimiert.

Rufe _delay_ms immer nur mit konstanten Werten auf.
Setze dir Flags oder mach es in etwa so:

if (clk_servo_u == 20) _delay_ms(20);
if (clk_servo_u == 2) _delay_ms(1.5);


Sowas ist ebenso sinnfrei (Mischung int/float):
int clk_servo_u;
clk_servo_u = 1.5;

Gruß
Roland

Autor: Peter II (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Stefan Marquardt schrieb:
> Wieso explodiert der code erst wenn ich die If-Abfrage einkommentiere?

weil du damit clk_servo_u änderst, damit kann es der optimerer für 
_delay_ms  nicht mehr sinnvoll verwenden. Das Problem ist also nicht das 
IF sonder der code in der {} vom If.

Autor: Stefan Marquardt (joker)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
wie kann ich meinen  Code so Optimieren?

es soll ja nur der wert geändert werden der High-zeit bei einer 0 am PB2 
bzw PB3

Autor: Edi R. (edi_r)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Bist Du Dir sicher, dass Du weißt, was in der Zeile
      if (PINB &= ~ (1<<PINB2))
passiert? Das ist nämlich eine Zuweisung. Meinst Du vielleicht:
      if (PINB & (1<<PINB2))

Autor: Stefan Marquardt (joker)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Er soll ja auch bei einem Low Pegel reagieren. So Kann ich die Internen 
Pullups aktivieren und brauche keine externen

Autor: Marcus B. (raketenfred)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
 while(1)
    {
      bool pin_low=PINB &= ~ (1<<PINB2);



      PORTB |= (1<<PB0);
if(pin_low){
      _delay_ms(20);
}
else
{
_delay_ms(1.5);//TODO: Float ändern
}
      PORTB &= ~ (1<<PB0);
if(!pin_low)
      _delay_ms(20-1.5);

      PORTB |= (1<<PB1);
if(pin_low){
      _delay_ms(20);
}
else
{
_delay_ms(1.5);//TODO: Float ändern
}
      PORTB &= ~ (1<<PB1);
if(!pin_low)
      _delay_ms(20-1.5);
    }





Nicht getestet, sollte aber kompakten Flash liefern. Den Floatwert (1.5) 
musst du unbedingt noch irgendwie ändern(Takt verdoppeln-> 3 raus machen 
z.b. - ist aber auch wieder mehr Strom...)


Ganz elegant würde man das ganze mit Timern(überhaupt vorhanden?!) 
lösen, die einen Interupt zum wieder aufwachen auslösen und der 
Controller ist solange im Sleepmodus-> sehr Strom effektiv

Autor: Peter II (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Marcus B. schrieb:
> Den Floatwert (1.5)
> musst du unbedingt noch irgendwie ändern(Takt verdoppeln-> 3 raus machen

warum sollte er das machen? Das sollte keine auswirkung auf den größe 
von dem code haben. Es hat schon einen sinn das jemand  _delay_ms mit 
float zugelassen hat.

Autor: Peter II (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Marcus B. schrieb:
> Den Floatwert (1.5)
> musst du unbedingt noch irgendwie ändern(Takt verdoppeln-> 3

die zeit im ms ist auch mit den 10 fachen takt gleich

Autor: Stefan Marquardt (joker)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Meint ihr das funktioniert auch so???


#include <avr/io.h>
#include <stdlib.h>
#include <stdint.h>
#ifndef F_CPU
#define F_CPU 1000000UL
#endif
#include <util/delay.h>

uint8_t clk_servo_u;
uint8_t clk_servo_o;


int main (void)
{

clk_servo_u = 1.5;

DDRB = 0b00000011;     // PINB0, PINB1 sind Augänge --- PINB2 - PINB7 Eingänge
PORTB = 0b11111100;    // Interne Pullups an PINB2 - PINB7 aktiv


  while(1)
    {
      if (PINB &= ~ (1<<PINB2))  
      {
        PORTB |= (1<<PB0);
        _delay_ms(18.5);
        PORTB &= ~ (1<<PB0);
        _delay_ms(1.5);
      }

      else if (PINB & (1<<PB2))
        {
          PORTB |= (1<<PB0);
          _delay_ms(18);
          PORTB &= ~ (1<<PB0);
          _delay_ms(2);
        }



      if (PINB &= ~ (1<<PINB3)) 
      {
      PORTB |= (1<<PB1);
      _delay_ms(18.5);
      PORTB &= ~ (1<<PB1);
      _delay_ms(1.5);
      }
      else if (PINB & (1<<PB3))
        {
          PORTB |= (1<<PB1);
          _delay_ms(18);
          PORTB &= ~ (1<<PB1);
          _delay_ms(2);
        }

    }


}    


Autor: Stefan Marquardt (joker)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Ich kenne mich mit Timern nicht aus und kapier das mit den Registern 
auch nicht. Sonst würde ich das ganze (wenns geht) 2 mal im atmega32 
laufen lassen und bräuchte den Tiny nicht

Autor: Peter II (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Stefan Marquardt schrieb:
> Ich kenne mich mit Timern nicht aus und kapier das mit den Registern
> auch nicht. Sonst würde ich das ganze (wenns geht) 2 mal im atmega32
> laufen lassen und bräuchte den Tiny nicht

warum lernst du es dann nicht?

Oder fragst wenn du nicht weiter kommst?

Man kann bequem 8 servos mit einem AtMega32 oder sogar einen Tiny wenn 
er genug anschlüsse hätte betreiben.

Autor: Stefan Marquardt (joker)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Weil ich es nicht versteh wie es im GCC Tutorial geschrieben ist.

In dem Fall anders gesagt.

Wir programmieren einen roboter. Die Servus brauchen wir für einen 
Greifarm. Nur sollte das Hauptprogramm nicht unterbrochen werden weil 
sonst Schritte verloren gehen könnten bei den Schrittmotoren.

Kann mir jemand das in anderen worten erklären?

Autor: Trolljäger (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Stefan Marquardt schrieb:
> Weil ich es nicht versteh wie es im GCC Tutorial geschrieben ist.
Und 'Servus' ist eine bayrische Begrüßung, keine Bezeichnung für einen 
Servomotor. Ich schäme mich mitlerweile, in diesem Land zu leben.

Autor: Peter II (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Stefan Marquardt schrieb:
> Nur sollte das Hauptprogramm nicht unterbrochen werden weil
> sonst Schritte verloren gehen könnten bei den Schrittmotoren.

eigentlich braucht man dafür gar kein Hauptprogramm.

Die Motoren werden in TIMER ISR angesteuert. Die Servos können dann 
eventuell der geleichen ISR oder auch ein der vom 2. Timer angesprochen 
werden. Dann hast du im hauptprogramm zeit zu berechnen was die Motoren 
und Servos machen sollen, musst dich aber nicht um die ansteuerung 
kümmern.

eine Timer ISR wird einfach alles X ms aufgerufen. Dazu sollte man 
erstmal gedanken machen wie gross X gewählt wird. Das ist abhänging der 
der kleinsten Zeiteinheit die du überbrücken musst.

Wenn also dein Schrittmotor alls min 2ms einen neuen Takt braucht, dann 
kann man stellt man den Timer so das er alles 2ms aufgerufen wird.

> Kann mir jemand das in anderen worten erklären?
wird schwer wenn es an den Grundlagen fehlt. Dafür musst du schon 
konrekte Frage stellen.

Autor: Marcus B. (raketenfred)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Peter II schrieb:
> Marcus B. schrieb:
>> Den Floatwert (1.5)
>> musst du unbedingt noch irgendwie ändern(Takt verdoppeln-> 3 raus machen
>
> warum sollte er das machen? Das sollte keine auswirkung auf den größe
> von dem code haben. Es hat schon einen sinn das jemand  _delay_ms mit
> float zugelassen hat.

Idee war einfach gar nicht sich mit der Fließkomma-lib sich rum zu 
schlagen, weil es unnötig ist, dass der Compiler das auch schafft direkt 
weg zu optimieren wusste ich nicht.

Trolljäger schrieb:
> Und 'Servus' ist eine bayrische Begrüßung

Servus lat. Sklave, auch wenn wir die schon längst abgeschafft haben?! 
;-)

Autor: Stefan Marquardt (joker)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Trolljäger schrieb
> Und 'Servus' ist eine bayrische Begrüßung, keine Bezeichnung für einen
> Servomotor. Ich schäme mich mitlerweile, in diesem Land zu leben.


Ach ja so schlimm ist es auch nicht

Autor: Stefan Marquardt (joker)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Es läuft ein Hauptptogramm in dem ein schrittmotr angesteuert wird. Der 
robo Fährt seine Strecke. Am Wettkampf fährt er seine Strecke ab und 
schiebt die Spielzeuge hin und Her. Für eine Aufgabe haben wir einen 
Greifarm konstruiert. Dieser Soll mit einem Servo hoch und runter 
fahren. Der Servo braucht aber immer einen Takt. Wie programmier ich 
einen Timer? Kann mir jemand einen beispielcode schreiben? Also mit 
Variablen die dann halt geändert werden im Hauptprogramm (1 ms für bsp 
unten und 2 ms für arm oben

Autor: Peter II (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Stefan Marquardt schrieb:
> Wie programmier ich
> einen Timer? Kann mir jemand einen beispielcode schreiben?
einfach mal ins datenblatt lesen oder in der Artikelübersicht suchen.

Fang am besten erstmal mit einer LED an die blinkt und das ganze ohne 
_delay_ms, dann sollte dir die verwendung vom Timer klar werden.

Klar könnte ich dir ein Beispiel schreiben, aber ich finde da lernt man 
nichts. erarbeitet es dir lieber selber, dann weisst du auch warum man 
es so macht. Und alles Infos die du dafür braucht stehen im Datenblatt 
zu deinem controler und wie man im GCC eine ISR definiert steht in dem 
GCC artikel auf dieser webseite mehr braucht man dafür nicht.

Autor: Stefan Marquardt (joker)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Ich lerne eher an Codebeispielen.

Die Stumpfe Theorie ist nichts für mich.

Autor: Rolf Magnus (rmagnus)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Stefan Marquardt schrieb:
> uint8_t clk_servo_u;

> clk_servo_u = 1.5;

Wie dir schon einmal erklärt wurde, funktioniert das nicht. Ein int kann 
nur ganze Zahlen aufnehmen. Deine 1.5 werden abgerundet auf 1, und die 
wird dann in clk_servo_u gespeichert.

Autor: Peter II (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Stefan Marquardt schrieb:
> Ich lerne eher an Codebeispielen.

nein machst du nicht, du probierst so lange rum bis du einen vorhandenen 
code zu abänderst damit er macht was du willst. Lernen ist das aber 
nicht.

Ausserdem kannst du damit nur sachen Programmieren die jemand vor dir 
schon mal geamcht hat, da kommt nie etwas neue raus.

> Die Stumpfe Theorie ist nichts für mich.
ein Datenblatt ist nicht Theorie das ist die Praixis, und man sollte es 
auf jeden Fall mal geslesen haben damit man weiss was der controller 
kann und wir er arbeitet.

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




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 erkennst du die Nutzungsbedingungen an.

webmaster@mikrocontroller.netImpressumNutzungsbedingungenWerbung auf Mikrocontroller.net