- LiTime Speicher und Akkus         
Seite 3 von 3 ErsteErste 123
Ergebnis 21 bis 25 von 25

Thema: Einstieg in C (WinAVR)

  1. #21
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    31
    Beiträge
    1.578
    Anzeige

    Praxistest und DIY Projekte
    Hi,

    also ich bin momentan fleißig am programmieren und habe was ausprobiert, was ich kaum glauben kann:
    Ein Programm (berechnen von ein paar Variablen) in Bascom braucht 5x so lange wie das gleiche Programm in C. KANN DAS SEIN? Das wäre ja gigantisch
    Hier mal die Codes, damit ihr mitreden könnt:
    Bascom:
    Code:
    Dim Newrcdata As Byte
    Dim Empf(8) As Byte
    
    Dim Empfold1(8) As Word
    Dim Empfold2(8) As Word
    Dim Empfold3(8) As Word
    Dim Empfold4(8) As Word
    
    Dim Lpempf(8) As Word
    
    
    Dim I As Byte
    
    Do
    
    
       Newrcdata = 1
       Call Rc_signal()
       Portd.0 = Not Portd.0
    
    
    Loop
    
    End
    
    
    Sub Rc_signal()
    
    
       If Newrcdata = 1 Then
          Newrcdata = 0
    
          For I = 1 To 8
             Empfold1(i) = Empfold2(i)
             Empfold2(i) = Empfold3(i)
             Empfold3(i) = Empfold4(i)
             Empfold4(i) = Empf(i)
    
             Lpempf(i) = Empfold1(i) + Empfold2(i)
             Lpempf(i) = Lpempf(i) + Empfold3(i)
             Lpempf(i) = Lpempf(i) + Empfold4(i)
             Shift Lpempf(i) , Right , 2 , Signed
          Next I
    
       End If
    
    
    End Sub
    AVR-Studio:
    Code:
    uint8_t newrcdata = 0;
    
    uint8_t empf[8];
    
    uint16_t empfold1[8];
    uint16_t empfold2[8];
    uint16_t empfold3[8];
    uint16_t empfold4[8];
    
    uint16_t lpempf[8];
    
    int main(void)
    {
        
        Clock_init();
        PORTC.DIR = 0x80;
        uart_init(&USARTC1);
        init_i2c(&TWIE);
        
        PORTD.DIR = 0xff;                              //set PortD Output
        PORTD.OUTSET = 0x01;                           //set PortD.0 High
        
        empf[1] = 120;
        empf[2] = 210;
        empf[3] = 210;
        empf[4] = 210;
        empf[5] = 210;
        empf[6] = 210;
        empf[7] = 210;
        empf[8] = 210;
        
        while(1)
        {
            newrcdata = 1;
            rc_signal();
            PORTD.OUTTGL = 0x01;
        }
        
    }
    
    void rc_signal(void)
    {
        if(newrcdata==1)
        {
            newrcdata = 0;
            for(uint8_t i=1;i<9;i++)
            {
                empfold1[i]=empfold2[i];
                empfold2[i]=empfold3[i];
                empfold3[i]=empfold4[i];
                empfold4[i]=empf[i];
                
                lpempf[i]=empfold1[i]+empfold2[i]+empfold3[i]+empfold4[i];
                lpempf[i]=lpempf[i]>>2;
            }
        }
    }
    Die benötigte Zeit wurde jeweils mit dem Oszi gemessen, Bascom braucht 75µs und AVR-Studio braucht 15µs.

    Außerdem wollte ich noch fragen, wann brauche ich volatile?
    Was ich bis jetzt weiß, ist, dass wenn eine Variable volatile ist, wird der Wert immer wieder im RAM gespeichert und daraus gelesen. Wenn eine Variable nicht als volatile definiert wird, wird der Wert wohl im Stack gespeichert!?
    Was ist der Vorteil? Ist der Weg über den Stack schneller?
    Kann es passieren, dass mir bestimmte Variablen, die nicht oft benutzt werden, wegoptimiert werden? Und wenn ja, woher weiß ich, welche Variablen wegoptimiert werden?

    Sorry für die vielen Fragen, aber in den Tuts / im Inet hab ich leider keine Antworten darauf gefunden...

    Vielen Dank & Gruß
    Chris

  2. #22
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    02.11.2005
    Alter
    48
    Beiträge
    1.146
    Wow, der Vergleich ist schon beeindruckend - das da so viel Unterschied drin ist, hätte ich auch nicht gedacht.
    Mal schauen, wie viele Bascom-Jünger jetzt auf C umsteigen wollen

    Zum volatile:
    Die häufigste Verwendung für volatile ist bei Variablen, die sowohl im normalen Programmablauf als auch in einer Interrupt-Routine benutzt werden.
    Wie Du schon richtig geschrieben hast, verhindert volatile das Optimieren einer Variable. Wird eine Variable im Code benutzt, wird sie erst mal vom RAM in ein Register (nicht auf den Stack!) geladen und von dort aus für weitere Operationen verwendet. Wird eine Variable z.B. in einer Schleife dauernd lesend geprüft, ohne innerhalb der Schleife verändert zu werden, wird der Controller nur ein einziges mal den Wert aus dem RAM in ein Register lesen und danach nur noch den Registerwert verwenden.
    Nun könnte es aber sein, dass diese Variable von einem Interrupt verändert wird. Die ISR weiß nichts von der Kopie der Variablen im Register und wird den Original-Wert vom RAM einlesen, verändern und wieder im RAM ablegen. Nach der Rückkehr aus der ISR benutzt die Schleife jedoch weiter die Kopie im Register, weil sie vom Interrupt nichts weiß. Das führt dann zu einem Programmfehler.
    Mit volatile teilt man dem Compiler nun mit, dass eine Variable unvorhersehbar geändert werden kann (also z.B. von einer ISR). Der Compiler veranlasst daraufhin, dass eine Variable jedesmal, wenn sie benutzt wird, neu aus dem RAM gelesen wird. Das verlangsamt den Programmablauf ein wenig, da ein zusätzlicher Lesebefehl verwendet werden muss, ist aber nun mal in solchen Fällen unerlässlich.

    Es kann auch sein, dass Variablen nur in Registern erzeugt und verwendet werden und gar nicht erst im RAM landen. Das würde man dann als "wegoptimiert" bezeichnen. Das ist z.B. bei Laufvariablen in for-Schleifen in der Regel der Fall, da die Variable nur so lange gebraucht wird, wie die for Schleife läuft. Das ist aber eigentlich nur beim Debuggen problematisch, da man solche Variablen im Watch-Fenster nicht anzeigen lassen kann.

    Gruß,
    askazo

  3. #23
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    31
    Beiträge
    1.578
    Hi,

    ok, dann hab ich das glaub ich richtig verstanden, danke für die Erklärung
    Kann es auch sein, dass ganze Teile des Codes wegoptimiert werden (z.b. irgendwelche Variablen, die nur einmal verwendet werden)?
    In Bascom gibt es einen Signed-Shift (also shiften, nur mit Beachtung des Vorzeichens). Gibts das in C auch? Wie man shiftet weiß ich (>> <<), aber wird dabei das Vorzeichen beachtet oder kommt dann Müll raus?

    Gruß
    Chris

  4. #24
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Zitat Zitat von Che Guevara Beitrag anzeigen
    Code:
    uint8_t empf[8];
    ...
        empf[1] = 120;
        empf[2] = 210;
        empf[3] = 210;
        empf[4] = 210;
        empf[5] = 210;
        empf[6] = 210;
        empf[7] = 210;
        empf[8] = 210;
    Bei einem Array der Größe 8 sind die erlaubten Indizes 0-7. Du machst diesen Fehler bei allen Arrayzugriffen. Sollte das Programm wie erwartet laufen, dann ist das purer Zufall.


    Zitat Zitat von Che Guevara Beitrag anzeigen
    In Bascom gibt es einen Signed-Shift (also shiften, nur mit Beachtung des Vorzeichens). Gibts das in C auch? Wie man shiftet weiß ich (>> <<), aber wird dabei das Vorzeichen beachtet oder kommt dann Müll raus?
    Links-Shift ist kein Problem. Rechts-Shift von Signed-Typen ist Implementation-Defined.
    MfG
    Stefan

  5. #25
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    31
    Beiträge
    1.578
    Hi,

    ja das stimmt, mit dem Array hab ich nen kleinen Fehler eingebaut. Das war aber sowieso nur ein Laufzeit Test.
    Das Shiften hab ich ausprobiert, ist soweit alles wie erwartet
    Eine Frage hab ich aber noch: Ich Suche eine Lib, mit der ich das TWI-Modul eines ATXMega32A4 ansteuern kann. Ich bin zwar auf die Lib von Peter Fleury gestoßen, aber diese scheint nur für normale Megas zu sein... Wäre toll, wenn jemand da was hätte. Notfalls würd ich mir das auch selbst schreiben, wenn ich ne Vorlage hätte, wie der Ablauf sein soll.

    Gruß
    Chris

Seite 3 von 3 ErsteErste 123

Ähnliche Themen

  1. Fehlermeldung WinAVR
    Von hvltt15 im Forum C - Programmierung (GCC u.a.)
    Antworten: 2
    Letzter Beitrag: 10.04.2008, 21:31
  2. MFile [WinAVR]
    Von siroks im Forum C - Programmierung (GCC u.a.)
    Antworten: 4
    Letzter Beitrag: 17.01.2008, 22:22
  3. WinAVR
    Von Chattychan im Forum C - Programmierung (GCC u.a.)
    Antworten: 5
    Letzter Beitrag: 12.09.2006, 14:41
  4. WinAvr
    Von LC-HC im Forum C - Programmierung (GCC u.a.)
    Antworten: 2
    Letzter Beitrag: 30.08.2005, 15:10
  5. WinAVR Tutorial
    Von Kjion im Forum Software, Algorithmen und KI
    Antworten: 2
    Letzter Beitrag: 12.08.2004, 11:36

Berechtigungen

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

LiFePO4 Speicher Test