- 12V Akku mit 280 Ah bauen         
Seite 2 von 2 ErsteErste 12
Ergebnis 11 bis 20 von 20

Thema: IF Else SCHLEIFEN

  1. #11
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    Anzeige

    E-Bike
    Ein Haup-Batzen dürfte die Verwendung von float sein.

    Nimm zB folgendes Progrämmchen:

    Code:
    float a, b, c, d;
    
    void foo ()
    {
            a = b*d - a/c;
    }
    
    int main()
    {
    	while (1);
    }
    Und übersetz es wie gewohnt mit "avr-gcc -mmcu=atmega8 -Os -o float.elf float.c"

    Dann schauen wir auf die Größe mit "avr-size float.elf"
    Code:
       text    data     bss     dec     hex filename
       2730       8      16    2754     ac2 float.elf
    Der ATmega8 ist also schon zu 1/3 voll. Wo die draufgehen sieht man mit "avr-nm -S --size-sort float.elf"
    Code:
    00800074 00000004 B a
    00800068 00000004 B b
    0080006c 00000004 B c
    00800070 00000004 B d
    00800060 00000008 D __thenan_sf
    000000f8 0000000a T main
    00000346 00000056 T __addsf3
    0000039c 0000005e T __subsf3
    0000005c 0000009c T foo
    00000948 000000f4 T __unpack_f
    00000626 00000156 T __divsf3
    0000077c 000001cc T __pack_f
    000003fa 0000022c T __mulsf3
    00000102 00000244 t _fpadd_parts
    In die zweiten Spalte stehen die Größen der Objekte (Bytes in hex). Das __*-Zeug kommt von der float-Software die dazugelinkt werden muss, weil AVR keine float/double Hardware-Unterstützung hat.

    Wenn du die Größen deiner Funktionen so auflistet, erkennt man wo am meisten Platz verbraucht wird und wo eine Optimierung am meisten bringt.

    Die Optimierungsstufe von avr-gcc sollte -Os sein. -O0 oder -O3 sind keinesfalls ratsam.

    Ansonsten hilft, mehrfach verwendete Sachen in eigene Funktionen zu packen. Damit kann der Code wiederverwendet werden und muss nicht jedesmal mit leicht anderen Parametern erzeugt werden.

    Code:
    //-----------------------------------------------------------------------------------------------------------------     
    // Titel : LCD 4x16 zeigt die Uhrzeit an für Testschaltung MYAVR
    //-----------------------------------------------------------------------------------------------------------------     
    // Prozessor    : ATmega8
    // Takt                 : 3686400 Hz
    // Sprache              : C
    // Datum                : 10.04.2008
    // Version              : 1.0
    // Autor                : 
    //-----------------------------------------------------------------------------------------------------------------     
    #include <avr/io.h>
    #ifndef  F_CPU
    #define  F_CPU 3686400UL                                                                                // Quarz mit 3.6864 Mhz
    #endif
    #include <util/delay.h>                                                                                 // definiert _delay_ms() Warteschleife 
    #include "i2cmaster.h"
    #include <stdlib.h>
    #include <string.h>
    #define DS13   0xd0                                                                                              // device address of Realtime Clock DS1307, see datasheet
    char i; 
    
    
    /////////////////////////////////////////////////////////////////////////////
    // Uhr
    /////////////////////////////////////////////////////////////////////////////
    
    // Schreibt 'num' gefolgt von 'c' an position line:pos (zeile:spalte)
    void lcd_write_num (unsigned char line, unsigned char pos, unsigned char num, char c)
    {
            unsigned char digit;
            static char buf[4];
            
            buf[2] = c;
            buf[3] = 0;
            new_line (line, pos);           // legt die Zeile, und dann die Spalte fest 
            
            digit = num >> 4;
            buf[0] = digit + '0';
            
            digit = num & 0xf;
            buf[1] = digit + '0';
    }        
    
    static const char * day_of_week[] = 
    { 
            "Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"
    };
    
    void Uhr2()
    {
            i2c_init();                                                             // initialize I2C library
            unsigned char sek, min, std, day, date, month, year;                                           // Typ char gibt Sekunde,Minute,Stunde,Wochentag,Tag den,Monat,Jahr.
            unsigned char i;
            
            for (i=1; i<30; i=i+1)
            {
                            _delay_ms(250);
            
    //-----------------------------------------------------------------------------------------------------------------
    //                      Daten Auslesen des Realtime Clock DS 1307
    //-----------------------------------------------------------------------------------------------------------------                     
                            i2c_start_wait(DS13+I2C_WRITE);                         // setzt die Adresse vom DS13 und den schreiben mode
                            i2c_write(0x00);                                // schreibe Address = 0 liegt Wert Zeitdaten
                            i2c_rep_start(DS13+I2C_READ);                           // setzt die Adresse vom DS13 und den lese mode
                            sek = i2c_readAck();                                    // lese den Inhalt von Adresse 0 Sekunden               
                            min = i2c_readAck();                                    // lese den Inhalt von Adresse 1 Minuten
                            std = i2c_readAck();                                    // lese den Inhalt von Adresse 2 Stunden
                            day = i2c_readAck();                                    // lese den Inhalt von Adresse 3 WochenTag
                            date = i2c_readAck();                                   // lese den Inhalt von Adresse 4 Tag den
                            month = i2c_readAck();                                  // lese den Inhalt von Adresse 5 Monate
                            year = i2c_readNak();                                   // lese den Inhalt von Adresse 6 Jahre                                  
                            i2c_stop();                                                                     // Ende des einlesens
    //-----------------------------------------------------------------------------------------------------------------
    //                      LCD Hintergundbeleuchtung einschalten.
    //                      Ausgabe der Stunden auf das LCD Display.
                            lcd_write_num (2, 5, std, ':');
    //-----------------------------------------------------------------------------------------------------------------
    //                      Ausgabe der Minuten auf das LCD Display.
                            lcd_write_num (2, 8, min, ':');
    //-----------------------------------------------------------------------------------------------------------------
    //                      Ausgabe der Sekunden auf das LCD Display.
                            lcd_write_num (2, 11, sek, 0);
    //-----------------------------------------------------------------------------------------------------------------
    //                      Ausgabe der Wochentage auf das LCD Display.
                            if (day >= 1 && day <= 7)
                            {
                                    new_line(1,2);                                                          // legt die Zeile, und dann die Spalte fest                                             
                                    lcd_write (day_of_week[day-1]);
                            }        
    //-----------------------------------------------------------------------------------------------------------------
    //                      Ausgabe der Tages auf das LCD Display.
                            lcd_write_num (1, 7, date, '.');
    //-----------------------------------------------------------------------------------------------------------------
    //                      Ausgabe die Monate auf das LCD Display.
                            lcd_write_num (1, 10, month, '.');
    //-----------------------------------------------------------------------------------------------------------------
    //                      Ausgabe der Jahre auf das LCD Display.
                            lcd_write_num (1, 13, year, 0);
            }
    }
    
    //-----------------------------------------------------------------------------------------------------------------
    Code:
    deep-thought> avr-nm -S --size-sort uhr.o
    00000001 00000001 C i
    00000000 00000004 b buf.0
    00000015 0000000e d day_of_week
    0000033e 0000002e T lcd_write_num
    0000036c 000000c0 T Uhr2
    00000000 0000033e T Uhr
    Das ist nicht nur übersichtlicher, sondern auch etwas kleiner (256 Bytes anstatt 830, und itoa ist noch net mitgerechnet).

  2. #12
    Neuer Benutzer Öfters hier
    Registriert seit
    23.05.2007
    Alter
    45
    Beiträge
    14
    Tach !

    Wow, da geht was, bin überrascht !
    Also in der UHr bin ich grad noch am Suchen, muss noch en Bug drin sein.

    Zu dem float....
    ...denke auch dass es hauptsächlich von dem kommt.
    Könntest du mir es mal bitte in die temp.h so reinkopieren wie du meinst ?

    Komm sooo net ganz klar

    Danke Danke Danke

  3. #13
    Neuer Benutzer Öfters hier
    Registriert seit
    23.05.2007
    Alter
    45
    Beiträge
    14

    Temperaturmessung

    Hallo Freunde !
    Also, wie ihr im Anhang erkennen könnt, hat mir jemand geholden das Programm zu schrumpfen ! Um einiges
    Es wird davon ausgegeangen, dass bei 0°C 2,5 Volt anstehen.
    Was ich auch gemessen hab und auch richtig ist. Angezeigt wird mir nur leider 39 °C. Soweit sogut. Dann hab ich einen - Offset ins Programm geschrieben, dass mir die Temperatur richtig ausgegeben wird.
    Wenn ich allerdings jetzt den Fühler in cirka 26 °C warmes Wasser eintauche werden mir nur 9°C angezeigt.

    Hmmm, könnte mir nochmal jemand über die Funktion drüberschauen.
    Blick da selber net sooo ganz durch. Anfängersyndrom

    Wäre um jede Hilfe dankbar !!!

    Gruss Andy
    Angehängte Dateien Angehängte Dateien

  4. #14
    Erfahrener Benutzer Roboter Experte Avatar von Neutro
    Registriert seit
    28.10.2007
    Ort
    Ostfriesland
    Alter
    45
    Beiträge
    642
    Wenn es sich bei deinem Temperaturfühler um einen NTC/PTC handeln sollte ist das normal. Die Dinger haben keine lineare Kennlinie!
    D.H wenn die Temperatur bei 0°C Kalbriert hast und du 20°C messen willst
    wird der Wert durch die Nichtlinearität des Temperaturfühlers verfälscht, Die angezeigte Temperatur ist also falsch.
    Für solche Zwecke braucht man Temperaturfühler die Linear sind und über
    I2C Ausgelesen werden.
    Jemand mit einer neuen Idee ist ein Spinner, bis er Erfolg hat.
    (Mark Twain)

  5. #15
    Neuer Benutzer Öfters hier
    Registriert seit
    23.05.2007
    Alter
    45
    Beiträge
    14
    Ich habe einen PT100 ! In dem Temperaturbereich wo ich messen will, also zwischen 22 und 29 Grad ist er "nahezu" linear. Mit meinem "alten" Quellcode hat es ja soweit funktioniert. Nur dass das Programm wegen dem float zu gross wurde. Da hatte ich es geschafft bei 0°C auch die 0°C angezeigt zu bekommen und bei 26 °C hatte ich eine minimale Abweichung von cirka 1/2 Grad !

  6. #16
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    äh. kann es sein daß man zum Auspacken von dem rar-Zeug ne Lizenz erwerben muss?

    Hannst das net verpacken als .zip, .7z, .gz oder .bz2 ?
    Disclaimer: none. Sue me.

  7. #17
    Neuer Benutzer Öfters hier
    Registriert seit
    23.05.2007
    Alter
    45
    Beiträge
    14
    Eigentlich net, aber kein Problem. Hier als .zip
    Angehängte Dateien Angehängte Dateien

  8. #18
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    ok, hab das 7-zip besorgt

    Knackus ist

    Code:
    ADCSRA |= (1<<ADSC);
    tmph = ADCH;		
    Temperatur1(tmph);
    ADCSRA |= (1<<ADSC);
    tmpl = ADCL;
    Temperatur2(tmpl);
    1) Du musst warten, bis der ADC fertig ist
    2) Die Werte vom ADC sind doch positiv, wieso machst du in Tem1 mit dem Vorzeichen rum...?
    3) Du hast 16-Bit-Werte --> also liest man auch 16 Bit vom ADC

    Code:
    ADCSRA |= (1<<ADSC);
    while (...);
    uint16_t tmp = ADC;		
    Temperatur (tmp);
    Wie ist den die Abbildung von ADC --> Temperatur?
    Disclaimer: none. Sue me.

  9. #19
    Neuer Benutzer Öfters hier
    Registriert seit
    23.05.2007
    Alter
    45
    Beiträge
    14
    Ich hab mal versucht, ob es klappt, also PLUS und MISUNS mit auszugeben ! GEht auch soweit. Okay, du sagst warten bis der ADC fertig ist. Meinst du dass deswegen das Wandlungsergebnis nicht stimmt ?

  10. #20
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    ...es sei denn, dein ACD hat ne Kristallkugel drinne und kann in die Zukunft schauen. Schau einfach mal ins Handbuch.

    Zitat Zitat von ATmega8-Handbuch
    ADC Conversion Result

    After the conversion is complete (ADIF is high), the conversion result can be found in the ADC Result Registers.
    Disclaimer: none. Sue me.

Seite 2 von 2 ErsteErste 12

Berechtigungen

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

Solar Speicher und Akkus Tests