-
        

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 11

Thema: 'volatile' funktioniert nicht mehr wie erwartet?

  1. #1
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    22.11.2005
    Ort
    Braunschweig
    Alter
    41
    Beiträge
    685

    'volatile' funktioniert nicht mehr wie erwartet?

    Anzeige

    Moin, ich bins mal wieder

    Da es mittlerweile einen Treiber für meinen USBTinyISP für 64bit gibt, hab ich mal AVRStudio 4.18 und WinAVR 2010 auf meinem Rechner installiert. Nun habe ich da ein kleines Problem :

    Ich habe von meinem MiniPanoBot ein Programm für den Tiny2313, das bisher wunderbar tat, was es sollte. Nun habe ich gerade einen kleinen Fehler behoben (an 2 Stellen für die Berechnung der Anzahl Schritte pro ° eine 69 durch eine 67 ersetzt, sonst nichts!!) und nun geht mal wieder was nicht. Alerdings habe ich das selbe Phänomen auch bei meiner aktuellen Schaltung festgestellt. In der Motoransteuerung gibt es eine Beschleunigungsrampe, die über eine feste Anzahl Schritte geht. Dafür benutze ich die Variable 'ramp', die ich also 'volatile int ramp=400' global definiert habe. Dies hat wunderbar geklappt, aber nun nicht mehr.... Bei meinem neuen Projekt ging es erst, als ich die Variable direkt in der Funktion deklariert habe, vorher schien die Varible entweder '0' oder irgendetwas undefiniertes kleines zu sein. Leider weiß ich nicht mehr, mit welcher WinAVR Version ich das vorher kompiliert hatte, allerdings haben zwei Versuche mit einer 2009er und einer 2008er Version das witzige Ergebnis geliefert, dass das Programm nicht mehr in das FlashROM passte.... hat einer eine schlaue Idee, ob es da einen Bug gibt oder verstehe ich da was falsch? Meines erachtens ist doch eine volatile Variable quasi sowas wie eine globale Variable?

    Mal mein Code:

    Code:
    #include <avr/io.h>
    #include <util/delay.h>
    #include <avr/interrupt.h>
    #include <stdlib.h>
    #include "uart.h"
    #include <avr/interrupt.h>
    #include <stdint.h> 
    
    //#include <avr/pgmspace.h>
    
    #define UART_BAUD_RATE      250000
    #define m_delay 1500
    volatile  uint16_t motor1=0;
    volatile  uint16_t motor2=0;
    //absolute direction in degree (-180 to 180, -90 to 90)
    volatile int16_t xpos = 0;
    volatile int16_t ypos = 0;
    //#define speed 400
    volatile int8_t speed = 40;
    volatile int ramp = 400;
    //const unsigned char step[4]={5,9,10,6};
    const unsigned char halfstep[8]={5,1,9,8,10,2,6,4}; 
    //const unsigned char halfstep[8]={0b00001010,0b00001000,0b00001001,0b00000001,0b00000010,0b00000110,0b00000100,0b00000101}; 
    
    void init()
    {
     DDRA = 0b00000011;
     DDRB = 0b11111111;
     DDRD = 0b00000000;
     uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) ); 
     sei();
    }
    void _vdelay_us(int delay)
    {
     int cnt;
     for (cnt=0;cnt<delay;cnt++)
     {
      _delay_us(10);
     }
    }
    void _vdelay_ms(int delay)
    {
     int cnt;
     for (cnt=0;cnt<delay;cnt++)
     {
      _delay_ms(1);
     }
    }
    
    void step_x(int dir)
    {
     motor1 = motor1 + dir;
     PORTB = (halfstep[(motor1 & 7)])| (PORTB & (0b11110000));
     _vdelay_us(speed);
    }
    void step_y(int dir)
    {
     motor2 = motor2 + dir;
     PORTB = (halfstep[(motor2 & 7)]) << 4| (PORTB & (0b00001111));
     _vdelay_us(speed);
    }
    void turn_x(int steps)
    {
     int cnt; 
    // int ramp = 400;
     int rf=4;
     int shortramp=0;
     char m=0;
     m = motor1;
     if (abs(steps)<(ramp*2))
     {
      shortramp=ramp-(abs(steps)/2);
      ramp= abs(steps)/2;
     }
     else 
      shortramp=0;
     
     PORTA |= (1<<0);
     if (steps>0)
     {
      for (cnt=0;cnt<=steps;cnt++)
      {
       step_x(1);
       // ramp start/stop
       if (cnt<ramp) //start
       {
        _vdelay_us((ramp-cnt+shortramp)*rf);
       }
      
       if (cnt>(steps-ramp)) //stop
       {
        _vdelay_us((cnt-(steps-ramp-shortramp))*rf);
       }
      }
     }
     else
     if (steps<0)
     {
      for (cnt=0;cnt>=steps;cnt--)
      {
       step_x(-1);
       // ramp start/stop
       if (abs(cnt)<ramp) //start
       {
        _vdelay_us((ramp-abs(cnt)+shortramp)*rf);
       }
      
       if (abs(cnt)>(abs(steps)-ramp)) //stop
       {
        _vdelay_us((abs(cnt)+(steps+ramp)+shortramp )*rf);
       }
      }
     }
     motor1 += steps;
     PORTA&=~(1<<0); //motor disable
    }
    void turn_y(int steps)
    {
     int cnt; 
    // int ramp = 400;
     int rf=4;
     int shortramp=0;
     char m=0;
     m = motor2;
     if (abs(steps)<(ramp*2))
     {
      shortramp=ramp-(abs(steps)/2);
      ramp= abs(steps)/2;
     }
     else 
      shortramp=0;
     
     PORTA |= (1<<1);
     if (steps>0)
     {
      for (cnt=0;cnt<=steps;cnt++)
      {
       step_y(1);
       // ramp start/stop
       if (cnt<ramp) //start
       {
        _vdelay_us((ramp-cnt+shortramp)*rf);
       }
      
       if (cnt>(steps-ramp)) //stop
       {
        _vdelay_us((cnt-(steps-ramp-shortramp))*rf);
       }
      }
     }
     else
     if (steps<0)
     {
      for (cnt=0;cnt>=steps;cnt--)
      {
       step_y(-1);
       // ramp start/stop
       if (abs(cnt)<ramp) //start
       {
        _vdelay_us((ramp-abs(cnt)+shortramp)*rf);
       }
      
       if (abs(cnt)>(abs(steps)-ramp)) //stop
       {
        _vdelay_us((abs(cnt)+(steps+ramp)+shortramp )*rf);
       }
      }
     }
     motor2 += steps;
     PORTA&=~(1<<1); //motor disable
    }
    void turn_deg_x(int16_t deg)
    {
      turn_x(deg*67);
    }
    void turn_deg_y(int16_t deg)
    {
      turn_y(deg*67);
    }
    unsigned char serialin(void)
    {
     unsigned int c;
     c = uart_getc();
        while ( c & UART_NO_DATA )
      c = uart_getc();
     return c;
    }
    void remote_move()
    {
     int16_t x,y;
     x=serialin()+(serialin()<<8);
     y=serialin()+(serialin()<<8);
     turn_deg_x(x-(xpos));
     turn_deg_y(y-(ypos));
     xpos = x;
     ypos = y;
     uart_putc(0);
    }
    
    void remote(void)
    { 
     unsigned int c;
        c = uart_getc();
        if ( c & UART_NO_DATA )
        {
            /* 
             * no data available from UART 
             */
        }
        else
        {
            /*
             * new data available from UART
             * check for Frame or Overrun error
             */
            if ( c & UART_FRAME_ERROR )
            {
                /* Framing Error detected, i.e no stop bit detected */
                //uart_puts_P("UART Frame Error: ");
            }
            if ( c & UART_OVERRUN_ERROR )
            {
                /* 
                 * Overrun, a character already present in the UART UDR register was 
                 * not read by the interrupt handler before the next character arrived,
                 * one or more received characters have been dropped
                 */
                //uart_puts_P("UART Overrun Error: ");
            }
            if ( c & UART_BUFFER_OVERFLOW )
            {
                /* 
                 * We are not reading the receive buffer fast enough,
                 * one or more received character have been dropped 
                 */
                //uart_puts_P("Buffer overflow error: ");
            }
           //doing commands
      switch(c)
      {
       case 1:
        remote_move(); 
       break;
      } 
        }
    }
    
    int main(void)
    {
     init();
     while (1)
     {
      remote();
     }
    }
    MfG
    Volker
    Meine kleine Seite
    http://home.arcor.de/volker.klaffehn
    http://vklaffehn.funpic.de/cms
    neuer Avatar, meine geheime Identität

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.801
    Auf Variablen > 8 Bit, die sich ISR und der Anwendung teilen, muss von der Anwendung aus atomar zugegriffen werden!
    Disclaimer: none. Sue me.

  3. #3
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    22.11.2005
    Ort
    Braunschweig
    Alter
    41
    Beiträge
    685
    Aber ich habe doch gar keine ISR? Eigentlich war der Plan, per RS232 die länge der Rampe vartiieren zu können, aber im Moment gibt es nur eine Funktion, in der die Variable genutzt wird?
    Meine kleine Seite
    http://home.arcor.de/volker.klaffehn
    http://vklaffehn.funpic.de/cms
    neuer Avatar, meine geheime Identität

  4. #4
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Ohne Interrupts ist das volatile in der Regel nicht nötig. Durch volatile wird dem Compiler gesagt, dass sich die variable z.B. durch einen Interrupt ändern kann, und entsprechend die Optimierung eingeschränkt. Volatile mach die Variable nicht global - macht aber praktisch nur bei globalen Variablen Sinn.

    Ein Problem könnte sein, das das RAM ausgeht. Der Tiny2313 hat davon nicht so viel. Der RAM bedarf kann sich ggf. je nach Compiler Version ändern.
    Was gibt den der Compiler als RAM-bedarf aus.

    Konstanten wie speed sollte man besser per #Define festlegen, nicht per const int ... , so wie es auch schon auskommentiert da steht. Da spart RAM und ist meist auch noch schneller. Das volatile ist hinsichtlich des RAM-Verbrauchs auch eher hinderlich.

    Einige Compiler Versionen brauchen für ein Case Statement viel RAM für eine Tabelle - hier ist noch ein Case drin, auch wenn ich nicht glaube das da der Compiler eine lange Tabelle draus macht.

  5. #5
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    22.11.2005
    Ort
    Braunschweig
    Alter
    41
    Beiträge
    685
    Bei Data sagt der Compiler 68% bzw. 87 bytes. const benutze ich eigetnlich nur für die Bitfolge der Schrittmotoren und ramp kann ich schlecht per #define machen, da sich der Wert unter Umständen.... mir kommt da grad ein Gedanke : ich ändere ja den Wert von ramp, wenn die Anzahl Schritte kleiner als die Rampe selber ist, aber ich setze ihn nie wieder zurück.... also doch ein #define für den Standardwert und eine lokale Variable zum Arbeiten, da ich das ja nur in der eine Funktion brauche.... manchmal hilft Kaffee .-) Danke auf alle Fälle fürs Drüberschauen!!
    Meine kleine Seite
    http://home.arcor.de/volker.klaffehn
    http://vklaffehn.funpic.de/cms
    neuer Avatar, meine geheime Identität

  6. #6
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Da wird schon ziemlich viel RAM für die globalen Variablen verbraucht. Die restlichen 32% müssen noch für den Stack und die lokalen Variablen reichen. Da könnten such eventuell die Schachtelungstiefe der Funktionen rächen. Da wäre ggf. ein lauf im Simulator angesagt um zu testen ob der Platz reicht.

    Ein Punkt um etwas Platz auf dem Stack zu sparen wäre es Funktionen wie turn_deg_x, die nicht so oft genutzt werden als "static inline " deklariert. Es könnte sein das der Compiler auch schon so darauf kommt und ohne den Hinweis die entsprechende Optimierung macht.

  7. #7
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    22.11.2005
    Ort
    Braunschweig
    Alter
    41
    Beiträge
    685
    So, nun sieht es so aus und funktioniert auch, wei geplant Dafür klkappts noch nicht mit der Bluetooth+Bresenham Variante, ich zeig die gleich nochmal.

    Code:
    #include <avr/io.h>
    #include <util/delay.h>
    #include <avr/interrupt.h>
    #include <stdlib.h>
    #include "uart.h"
    #include <avr/interrupt.h>
    #include <stdint.h> 
    
    //#include <avr/pgmspace.h>
    
    #define UART_BAUD_RATE      250000
    #define m_delay 1500
    volatile  uint16_t motor1=0;
    volatile  uint16_t motor2=0;
    //absolute direction in degree (-180 to 180, -90 to 90)
    volatile int16_t xpos = 0;
    volatile int16_t ypos = 0;
    #define speed 50
    #define deframp 200
    #define rf 2
    const unsigned char halfstep[8]={5,1,9,8,10,2,6,4}; 
    
    void init()
    {
     DDRA = 0b00000011;
     DDRB = 0b11111111;
     DDRD = 0b00000000;
     uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) ); 
     sei();
    }
    void _vdelay_us(int delay)
    {
     int cnt;
     for (cnt=0;cnt<delay;cnt++)
     {
      _delay_us(10);
     }
    }
    void _vdelay_ms(int delay)
    {
     int cnt;
     for (cnt=0;cnt<delay;cnt++)
     {
      _delay_ms(1);
     }
    }
    
    void step_x(int dir)
    {
     motor1 = motor1 + dir;
     PORTB = (halfstep[(motor1 & 7)])| (PORTB & (0b11110000));
     _vdelay_us(speed);
    }
    void step_y(int dir)
    {
     motor2 = motor2 + dir;
     PORTB = (halfstep[(motor2 & 7)]) << 4| (PORTB & (0b00001111));
     _vdelay_us(speed);
    }
    void turn_x(int steps)
    {
     int cnt; 
     int ramp = deframp;
     
     int shortramp=0;
     char m=0;
     m = motor1;
     if (abs(steps)<(ramp*2))
     {
      shortramp=ramp-(abs(steps)/2);
      ramp= abs(steps)/2;
     }
     else 
      shortramp=0;
     
     PORTA |= (1<<0);
     if (steps>0)
     {
      for (cnt=0;cnt<=steps;cnt++)
      {
       step_x(1);
       // ramp start/stop
       if (cnt<ramp) //start
       {
        _vdelay_us((ramp-cnt+shortramp)*rf);
       }
      
       if (cnt>(steps-ramp)) //stop
       {
        _vdelay_us((cnt-(steps-ramp-shortramp))*rf);
       }
      }
     }
     else
     if (steps<0)
     {
      for (cnt=0;cnt>=steps;cnt--)
      {
       step_x(-1);
       // ramp start/stop
       if (abs(cnt)<ramp) //start
       {
        _vdelay_us((ramp-abs(cnt)+shortramp)*rf);
       }
      
       if (abs(cnt)>(abs(steps)-ramp)) //stop
       {
        _vdelay_us((abs(cnt)+(steps+ramp)+shortramp )*rf);
       }
      }
     }
     motor1 += steps;
     PORTA&=~(1<<0); //motor disable
    }
    void turn_y(int steps)
    {
     int cnt; 
     int ramp = deframp;
     
     int shortramp=0;
     char m=0;
     m = motor2;
     if (abs(steps)<(ramp*2))
     {
      shortramp=ramp-(abs(steps)/2);
      ramp= abs(steps)/2;
     }
     else 
      shortramp=0;
     
     PORTA |= (1<<1);
     if (steps>0)
     {
      for (cnt=0;cnt<=steps;cnt++)
      {
       step_y(1);
       // ramp start/stop
       if (cnt<ramp) //start
       {
        _vdelay_us((ramp-cnt+shortramp)*rf);
       }
      
       if (cnt>(steps-ramp)) //stop
       {
        _vdelay_us((cnt-(steps-ramp-shortramp))*rf);
       }
      }
     }
     else
     if (steps<0)
     {
      for (cnt=0;cnt>=steps;cnt--)
      {
       step_y(-1);
       // ramp start/stop
       if (abs(cnt)<ramp) //start
       {
        _vdelay_us((ramp-abs(cnt)+shortramp)*rf);
       }
      
       if (abs(cnt)>(abs(steps)-ramp)) //stop
       {
        _vdelay_us((abs(cnt)+(steps+ramp)+shortramp )*rf);
       }
      }
     }
     motor2 += steps;
     PORTA&=~(1<<1); //motor disable
    }
    void turn_deg_x(int16_t deg)
    {
      turn_x(deg*67);
    }
    void turn_deg_y(int16_t deg)
    {
      turn_y(deg*67);
    }
    unsigned char serialin(void)
    {
     unsigned int c;
     c = uart_getc();
        while ( c & UART_NO_DATA )
      c = uart_getc();
     return c;
    }
    void remote_move()
    {
     int16_t x,y;
     x=serialin()+(serialin()<<8);
     y=serialin()+(serialin()<<8);
     turn_deg_x(x-(xpos));
     turn_deg_y(y-(ypos));
     xpos = x;
     ypos = y;
     uart_putc(0);
    }
    
    void remote(void)
    { 
     unsigned int c;
        c = uart_getc();
        if ( c & UART_NO_DATA )
        {
            /* 
             * no data available from UART 
             */
        }
        else
        {
            /*
             * new data available from UART
             * check for Frame or Overrun error
             */
            if ( c & UART_FRAME_ERROR )
            {
                /* Framing Error detected, i.e no stop bit detected */
                //uart_puts_P("UART Frame Error: ");
            }
            if ( c & UART_OVERRUN_ERROR )
            {
                /* 
                 * Overrun, a character already present in the UART UDR register was 
                 * not read by the interrupt handler before the next character arrived,
                 * one or more received characters have been dropped
                 */
                //uart_puts_P("UART Overrun Error: ");
            }
            if ( c & UART_BUFFER_OVERFLOW )
            {
                /* 
                 * We are not reading the receive buffer fast enough,
                 * one or more received character have been dropped 
                 */
                //uart_puts_P("Buffer overflow error: ");
            }
           //doing commands
      switch(c)
      {
       case 1:
        remote_move(); 
       break;
      } 
        }
    }
    
    int main(void)
    {
     init();
     while (1)
     {
      remote();
     }
    }
    Meine kleine Seite
    http://home.arcor.de/volker.klaffehn
    http://vklaffehn.funpic.de/cms
    neuer Avatar, meine geheime Identität

  8. #8
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    22.11.2005
    Ort
    Braunschweig
    Alter
    41
    Beiträge
    685
    Hier das Ganze mal mit Bluetooth (ist ja auch bloß RS232) und Bresenham, statt nacheinander fahrenden Achsen.

    Code:
    #include <avr/io.h>
    #include <util/delay.h>
    #include <avr/interrupt.h>
    #include <stdlib.h>
    #include "uart.h"
    #include <avr/interrupt.h>
    #include <stdint.h> 
    
    #include <avr/pgmspace.h>
    
    #define UART_BAUD_RATE      9600
    volatile  uint16_t motor1=0;
    volatile  uint16_t motor2=0;
    //absolute direction in degree (-180 to 180, -90 to 90)
    volatile int16_t xpos = 0;
    volatile int16_t ypos = 0;
    #define speed 400
    #define deframp 200
    #define rf 2
    const unsigned char halfstep[8]={5,1,9,8,10,2,6,4}; 
    void init()
    {
     DDRA = 0b00000011;
     DDRB = 0b11111111;
     DDRD = 0b00000100;
     PORTA=0b00000000;
     uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) ); 
     sei();
     
     //Bluetooth module config
     PORTD |= (1<<2);
     uart_puts_P("AT+NAME=MiniPanoBot_BT\r\n");
     uart_puts_P("AT+PSWD=0815\r\n");
     uart_puts_P("AT+UART=9600,0,0\r\n");
     uart_puts_P("AT+RESET\r\n");
     PORTD &= ~(1<<2); 
    }
    void _vdelay_us(int delay)
    {
     int cnt;
     for (cnt=0;cnt<delay;cnt++)
     {
      _delay_us(1);
     }
    }
    void _vdelay_ms(int delay)
    {
     int cnt;
     for (cnt=0;cnt<delay;cnt++)
     {
      _delay_ms(1);
     }
    }
    void step_x(int dir)
    {
     motor1 = motor1 + dir;
     PORTB = (halfstep[(motor1 & 7)])| (PORTB & (0b11110000));
     _vdelay_us(speed);
    }
    void step_y(int dir)
    {
     motor2 = motor2 + dir;
     PORTB = (halfstep[(motor2 & 7)]) << 4| (PORTB & (0b00001111));
     _vdelay_us(speed);
    }
    
    /* signum function */
    int sgn(int x){
      return (x > 0) ? 1 : (x < 0) ? -1 : 0;
    }
     
    void line(int xstart,int ystart,int xend,int yend)
    /*--------------------------------------------------------------
     * Bresenham-Algorithmus: Linien auf Rastergeräten zeichnen
     *
     * Eingabeparameter:
     *    int xstart, ystart        = Koordinaten des Startpunkts
     *    int xend, yend            = Koordinaten des Endpunkts
     *
     * Ausgabe:
     *    void SetPixel(int x, int y) setze ein Pixel in der Grafik
     *         (wird in dieser oder aehnlicher Form vorausgesetzt)
     *---------------------------------------------------------------
     */
    {
        int x, y, t, dx, dy, incx, incy, pdx, pdy, ddx, ddy, es, el, err;
     int rampe=deframp;
     int shortramp=0;
     
    /* Entfernung in beiden Dimensionen berechnen */
       dx = xend - xstart;
       dy = yend - ystart;
     
    /* Vorzeichen des Inkrements bestimmen */
       incx = sgn(dx);
       incy = sgn(dy);
       if(dx<0) dx = -dx;
       if(dy<0) dy = -dy;
     
    /* feststellen, welche Entfernung größer ist */
       if (dx>dy)
       {
          /* x ist schnelle Richtung */
          pdx=incx; pdy=0;    /* pd. ist Parallelschritt */
          ddx=incx; ddy=incy; /* dd. ist Diagonalschritt */
          es =dy;   el =dx;   /* Fehlerschritte schnell, langsam */
       } else
       {
          /* y ist schnelle Richtung */
          pdx=0;    pdy=incy; /* pd. ist Parallelschritt */
          ddx=incx; ddy=incy; /* dd. ist Diagonalschritt */
          es =dx;   el =dy;   /* Fehlerschritte schnell, langsam */
       }
     
    /* Initialisierungen vor Schleifenbeginn */
       x = xstart;
       y = ystart;
       err = el/2;
        if (el<(rampe*2))
     {
      shortramp=rampe-(el/2);
      rampe= el/2;
     }
     else 
      shortramp=0;
    
     PORTA |= ((1<<0)&(1<<1));  //Motortreiber aktivieren
       //SetPixel(x,y);
     
    /* Pixel berechnen */
     
     for(t=0; t<el; ++t) /* t zaehlt die Pixel, el ist auch Anzahl */
        {
         /* Aktualisierung Fehlerterm */
           err -= es; 
           if(err<0)
           {
            /* Fehlerterm wieder positiv (>=0) machen */
               err += el;
               /* Schritt in langsame Richtung, Diagonalschritt */
               x += ddx;
               y += ddy;
         step_x(ddx);
         step_y(ddy);
           } else
           {
               /* Schritt in schnelle Richtung, Parallelschritt */
               x += pdx;
               y += pdy;
         step_x(pdx);
         step_y(pdy);
           }
      if (t<=rampe) //start
       {
        _vdelay_us((rampe-t+shortramp)*rf);
       }
      
       if (t>(el-rampe)) //stop
       {
        _vdelay_us((t-(el-rampe-shortramp))*rf);
       }
        //SetPixel(x,y);
        }
         PORTA &= ~((1<<0)&(1<<1));
    } /* gbham() */
    void moveto(int x,int y)
    {
     line(xpos,ypos,x,y);
     xpos=x;
     ypos=y;
    }
    
    unsigned char serialin(void)
    {
     unsigned int c;
     c = uart_getc();
        while ( c & UART_NO_DATA )
      c = uart_getc();
     return c;
    }
    void remote_move()
    {
     int16_t x,y;
     x=serialin()+(serialin()<<8);
     y=serialin()+(serialin()<<8);
     uart_putc(1);
     moveto(x,y);
     xpos = x;
     ypos = y;
     uart_putc(0);
    }
    void remote(void)
    { 
     unsigned int c;
        c = uart_getc();
        if ( c & UART_NO_DATA )
        {
            /* 
             * no data available from UART 
             */
        }
        else
        {
            /*
             * new data available from UART
             * check for Frame or Overrun error
             */
            if ( c & UART_FRAME_ERROR )
            {
                /* Framing Error detected, i.e no stop bit detected */
                //uart_puts_P("UART Frame Error: ");
            }
            if ( c & UART_OVERRUN_ERROR )
            {
                /* 
                 * Overrun, a character already present in the UART UDR register was 
                 * not read by the interrupt handler before the next character arrived,
                 * one or more received characters have been dropped
                 */
                //uart_puts_P("UART Overrun Error: ");
            }
            if ( c & UART_BUFFER_OVERFLOW )
            {
                /* 
                 * We are not reading the receive buffer fast enough,
                 * one or more received character have been dropped 
                 */
                //uart_puts_P("Buffer overflow error: ");
            }
           //doing commands
      switch(c)
      {
       case 0: //status
        uart_putc(0);
       break;
       case 1: //moveto(x,y)
        remote_move(); 
       break;
       case 2: //power motors on hold
        PORTA = 0b00000011;
        uart_putc(0);
       break;
       case 3: //unpower motors on hold
        PORTA = 0b00000000;
        uart_putc(0);
       break;
       case 4: //shoot
        PORTA = 0b00000000;
        uart_putc(0);
       break;
      } 
        }
    }
    
    int main(void)
    {
     init();
     while (1)
     {
      remote();
     }
    }
    Der Compiler sagt :
    Code:
     Program: 1552 bytes (75.8% Full)
    (.text + .data + .bootloader)
    Data: 85 bytes (66.4% Full)
    (.data + .bss + .noinit)
    Nehme ich diesen Teil, also die Stoprampe, heraus, geht es, mit Stoprampe, macht die Schaltung unmotiviert Resets, ich bekomme Teile der BT-Strings zu sehen. Vermutlich ist das hier wirklich ein Speicher oder Stackproblem, ich durchschaue nur nicht so ganz, wie ich das mit dem AVRStudio Debugger herausbekomme....
    Code:
    if (t>(el-rampe)) //stop
       {
        _vdelay_us((t-(el-rampe-shortramp))*rf);
       }
    Die Rampe ist ja 1zu1 aus dem anderen Programm übernommen, nur der Bresenham benötigt mehr Variablen als die Funktion im ersten Programm. ich überlege schon die ganze Zeit, wo ich noch ein paar Bytes sparen könnte... evtl. nehme ich die volatile Dinger raus und speichere das Ganze im EEProm, hat der 2313 überhaupt eins? Muß ich mal das Datenblatt wälzen, außerdem fressen die Funktionen zum ROM ansprechen ja auch wieder Programmspeicher.... Wenns gar nicht geht, muß ich eine neue Platine machen und einen anderen Kontroller nehmen, aber irgendwie wäre es schön, wenn ich das softwareseitig gelöst bekäme.
    Meine kleine Seite
    http://home.arcor.de/volker.klaffehn
    http://vklaffehn.funpic.de/cms
    neuer Avatar, meine geheime Identität

  9. #9
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    22.11.2005
    Ort
    Braunschweig
    Alter
    41
    Beiträge
    685
    So, habe im Bresenham mal folgendes geändert :

    Code:
      int x, y, t, dx, dy, es, el, err;
     unsigned char pdx, pdy, ddx, ddy,incx, incy;
     uint8_t rampe=deframp;
     uint8_t shortramp=0;
    Der Compiler behauptet immer noch, es werden 85 Bytes belegt, aber jetzt funktioniert es mit Start- und Stoprampe

    MfG
    Volker
    Meine kleine Seite
    http://home.arcor.de/volker.klaffehn
    http://vklaffehn.funpic.de/cms
    neuer Avatar, meine geheime Identität

  10. #10
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Wenn es mit den kürzeren Variablen geht, spricht das dafür dass es wirklich ein Problem mit zu wenig RAM ist. Die lokalen variablen werden erst zur Laufzeit belegt, sind also noch nicht in den vom Compiler angezeigten 85 Bytes enthalten.

    Etwas Hilfe dazu könnte es hier geben:
    http://www.rn-wissen.de/index.php/Sp...en_mit_avr-gcc

    Als kleineren Schritt vor einer neuen Platine gäbe es noch den Tiny4313 - ein sonst fast gleicher µC mit den doppelten Speicher.

Seite 1 von 2 12 LetzteLetzte

Ähnliche Themen

  1. LCD funktioniert nicht mehr
    Von tomy321 im Forum Schaltungen und Boards der Projektseite Mikrocontroller-Elektronik.de
    Antworten: 0
    Letzter Beitrag: 09.07.2011, 16:09
  2. RNBFRA funktioniert nicht mehr
    Von bart im Forum Schaltungen und Boards der Projektseite Mikrocontroller-Elektronik.de
    Antworten: 7
    Letzter Beitrag: 23.04.2007, 19:40
  3. programm funktioniert nicht mehr?
    Von manu_f im Forum C - Programmierung (GCC u.a.)
    Antworten: 10
    Letzter Beitrag: 05.11.2006, 10:05
  4. Flashen funktioniert nicht mehr!
    Von schnipro01 im Forum Asuro
    Antworten: 0
    Letzter Beitrag: 24.09.2006, 17:53
  5. ISP Adapter funktioniert nicht mehr
    Von Razer im Forum AVR Hardwarethemen
    Antworten: 19
    Letzter Beitrag: 26.03.2006, 13:00

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •