Hallo zusammen, wir (Studenten der HS Heilbronn) müssen für unsere Informatik Klausur ein Projekt auf dem MiniMexle der HS Heilbronn gestalten. Aufgabenstellung ist: Thermometer mit Balkenanzeige: Programmieren Sie ein Thermometer mit Säulenanzeige das die aktuelle Temperatur mit dem NTC on-board misst und auf dem Display als Quecksilbersäule anzeigt. Weiterhin sollen die MIN/MAX-Werte mit zwei Markierungen angezeigt werden. Auf dem MiniMexle ist ein ATMega88 MC verbaut. Hier das Datenblatt: http://www.atmel.com/dyn/resources/prod_documents/doc2545.pdf Schaltplan des MiniMexles: http://www.mexle.hs-heilbronn.de/ Leider ist uns die Gabe fürs C Programmieren nicht wirklich gegeben, und bisher sind wir mit müh und not bis zu diesem Quelltext gekommen. /*---------------------------------------------------------------------- ----------------- Datum: 03.06.2009 Beschreibung: Thermometer mit Balkenanzeige: Programmieren Sie ein Thermometer mit Säulenanzeige das die aktuelle Temperatur mit dem NTC on-board misst und auf dem Display als Quecksilbersäule anzeigt. Weiterhin sollen die MIN/MAX-Werte mit zwei Markierungen angezeigt werden. ------------------------------------------------------------------------ ---------------*/ #ifndef F_CPU //Abfrage, ob Systemtakt definiert ist #define F_CPU 18432000UL //Quarz-Frequenz definieren #endif //Quarz-Frequenz Definition aktivieren //---------------------------------------------------------------------- ---------------- // Header-Dateien //---------------------------------------------------------------------- ---------------- #include <avr/io.h> // Header Datei für I/O Konfiguration (intern werden weitere Dateien eingefügt #include <avr/interrupt.h> // Header Datei für globale Interrupt Aktivierung #include <stdint.h> // Header Datei zur Definition der Zahlentypen (int, char, unsigned char usw.) #include <stdbool.h> // Header Datei zur Defintion der 1-Bit-Variablen bool //#include <util\delay.h> // Header Datei zur Defintion von Wartezeiten #include <math.h> // Header Datei zur Defintion komplexer math. //Operationen #include "lcd_lib.h" // Header Datei zur Ansteuerung des Displays //---------------------------------------------------------------------- ---------------- //Variablen-Defintion //---------------------------------------------------------------------- ---------------- volatile float tempwert_alt = 0 ; // alter Temperaturwert volatile float tempwert_neu = 0 ; // neuer Temperaturwert volatile unsigned int verzoegerung ; // Abfragezeit volatile char LCD_Balken ; // Stand LCD-Balken volatile char LCD_min ; // Stand MIN-Markierung volatile char LCD_max ; // Stand MAX-Markierung volatile float temp_digital ; // digitalisierter Temperaturwert volatile char timer_count ; // Timer0 1 Sekunde volatile char sekunden_tick ; // von Timer0 volatile bool minuszeichen ; // Variable //---------------------------------------------------------------------- ---------------- // Funktionsprototypenaufruf //---------------------------------------------------------------------- ---------------- void Timer0Init (void) ; void ADWandlerInit (void) ; void ADWandlung (void) ; void Linearisierung (void) ; void Temperaturberechnung (void) ; void Anzeigetreiber (void) ; //---------------------------------------------------------------------- ---------------- // Main-Schleife //---------------------------------------------------------------------- ---------------- int main (void) { sei(); // Interrupt ermöglichen Timer0Init(); // Initialisierung von Timer0 ADWandlerInit(); // Initialisierung des A/D-Wandlers //DisplayInit() DDRC = 0x0F ; // Port C als Output konfigurieren DDRD = 0xFF ; // Port D als Output konfigurieren PORTC = 0x0F ; // Output-Pins von Port C auf 1 setzen lcd_init(); // LCD-Initialisierung der Header Datei lcd_lib.c //+++++++++++++++++++++++++ while(1) //Endlosschleife { if(sekunden_tick==1) { sekunden_tick = 0 ; ADWandlung() ; Linearisierung() ; } } return(1); } //---------------------------------------------------------------------- ---------------- // Funktionen //---------------------------------------------------------------------- ---------------- //Timer-Initialisierung: //Initialisierung des Timer0 zur Erzeugung eines getakteten Interrupts(jede Sekunde), //welcher dazu dient, die benötigten Takte zu realisieren (einmaliger Aufruf). void Timer0Init (void) { TCCR0A |= (1<<WGM01) ; // Clear Timer in Compare (CTC) TCCR0B |= ((1<<CS02) | (1<<CS00)) ; // Prescaler auf Teilung durch 1024 setzen OCR0A = 249; // Output Compare Register A belegen TIMSK0 |= (1<<OCIE0A) ; // Interrupt Timer/C0 Output Compare Match A sei() ; } ISR (TIMER0_COMPA_vect) { timer_count ++ ; if (timer_count == 72) { timer_count = 0 ; sekunden_tick = 1 ; } } //---------------------------------------------------------------------- ---------------------------- //A/D-Wandler-Initialisierung: //Initialisierung des A/D-Wandlers, welcher die am NTC abfallende //Spannung in ein digitales Signal umwandelt (einmaliger Aufruf). void ADWandlerInit (void) { ADCSRA |= (1<<ADPS0) | (1<<ADPS1) | (1<<ADPS2); //Frequenzvorteiler auf 128 stellen ADMUX |= (1<<REFS0) | (0<<REFS1); //AVCC als Referenzspannung wählen ADMUX |= (0<<MUX0) | (0<<MUX1) | (1<<MUX2) | (0<<MUX3); //ADC4 als Eingangskanal wählen } //---------------------------------------------------------------------- ----------------------------- //Modul ADWandlung: //---------------- //Durchführung einer Einzelwandlung der am NTC abfallenden //Spannung in einen digitalen 10-bit-Wert (wird einmal pro //Sekunde aufgerufen). void ADWandlung (void) { unsigned int wandlung = 0; unsigned int wandlungh = 0; unsigned int wandlungl = 0; ADCSRA |= (1<<ADEN); //ADC aktivieren ADCSRA |= (1<<ADSC); //Dummy-Wandlung durchführen while (ADCSRA & (1<<ADSC)); //Auf Abschluss der Dummy-Wandlung warten wandlungl = ADCL; //Auslesen der Bits 0 bis 7 der Dummy-Wandlung wandlungh = ADCH; //Auslesen der Bits 8 und 9 der Dummy-Wandlung ADCSRA |= (1<<ADSC); //Wandlung durchführen while (ADCSRA & (1<<ADSC)); //Auf Abschluss der Wandlung warten wandlungl = ADCL; //Auslesen der Bits 0 bis 7 der Wandlung wandlungh = ADCH; //Auslesen der Bits 8 und 9 der Wandlung ADCSRA |= !(1<<ADEN); //ADC deaktivieren wandlung = wandlungh<<8; //Ausgelesene Bits 8 und 9 in Variable wandlung schreiben wandlung = wandlung + wandlungl; //Ausgelesene Bits 0 bis 7 in Variable wandlung schreiben temp_digital = wandlung; //Das Ergebnis der Wandlung in Variable temp_digital schreiben } //---------------------------------------------------------------------- ------------------------------ //Modul Linearisierung: //-------------------- //Linearisierung des digitalen Temperaturwerts, welcher aufgrund //der nicht linearen NTC-Kurve noch verzerrt ist (wird einmal pro //Sekunde aufgerufen). void Linearisierung (void) { tempwert_neu = ((3977.00000000 / (log(-temp_digital/(temp_digital - 1024.00000000)) + 13.34563758))); //Linearisierung und Berechnung des Temperaturwertes aus dem digitalen Wert vom A/D-Wandler durch math. Funktion if(tempwert_neu < 273) //Abfrage, ob Temperatur kleiner Null ist { minuszeichen = true; //Bool'sche Variable zum Schreiben des Minuszeichens setzen tempwert_neu -= 273.00000000; //Letzte Rechenoperation der Linearisierungsformel durchführen tempwert_neu *= -1; //tempwert_neu ins positive kehren } else //Abfrage, ob Temperatur größer oder gleich Null ist { minuszeichen = false; //Bool'sche Variable zum Schreiben des Minuszeichens zurücksetzen tempwert_neu -= 273.00000000; //Letzte Rechenoperation der Linearisierungsformel durchführen } } //---------------------------------------------------------------------- ------------------------------------------- /* ************************************************************************ ******************************************* ENDE ************************************************************************ ******************************************* */ Wie bekommen wir die Temperatur als Balken auf unserem LCD angezeigt? Stimmt der Quelltext bisher? Würde mich freuen auf Antworten! Thomas
Eine Idee zur Darstellung könnte euch dieses Projekt geben: http://www.avrprojects.net/index.php?option=com_content&view=article&id=68:lcd-thermometer-lm35&catid=37:avr-projects&Itemid=57
Thomasjochenjohannes Vogtwilligbraun schrieb: > Wie bekommen wir die Temperatur als Balken auf unserem LCD angezeigt? > Stimmt der Quelltext bisher? Vorschlag: Schreibt doch euere Temperatur einfach mal als Zahlenwert aufs LCD. Es hat keinen Sinn Unmengen an Code zu schreiben ohne den auch nur ein einziges mal zu testen! Ihr steht dann am Ende mit haufenweise Code da, der nicht funktioniert und bei dem ihr keine Ahnung habt, wo ihr zu suchen anfangen sollt. Und gebt euch nicht der Illusion hin, dass das Programm auf Anhieb funktionieren wird. Das wird es nämlich ziemlich sicher nicht. Sobald es in einem Projekt etwas gibt, was getestet werden kann: testet es! Das bischen Code, das ihr dabei umsonst schreibt, ist gut investiert und die vermeintlich vergeudete Zeit kommt hundertfach bei der Fehlersuche zurück. > Würde mich freuen auf Antworten! Ihr könntet euch zb. ein paar Sonderzeichen definieren, aus denen der Balken zusammengesetzt wird. Da eine Character Position am LCD aus einer 5*8 Matrix besteht, benötigt man 5 Sonderzeichen (+1 Leerzeichen) um dammit an einer Characterposition jeden beliebigen Balken mit einer Breite von 0 bis 5 Balkenstrichen zu erhalten. Wenn man 20 Character Positionen für einen Balken zur Verfügung hat, dann muss man eigentlich nur noch eine gewisse Anzahl an völlig ausgefüllten Balkenelementen und eines der 5 Sonderzeichen ausgeben um damit jede beliebige Balkenlänge von 0 bis 100 (20*5) sekrechten Strichen erreichen zu können.
Hallo, danke für die Antworten. Könnte mir jemand beantworten was diese Fehlermeldung bedeutet? c:/winavr-20090313/bin/../lib/gcc/avr/4.3.2/../../../../avr/bin/ld.exe: Thermometer.elf section .text will not fit in region text c:/winavr-20090313/bin/../lib/gcc/avr/4.3.2/../../../../avr/bin/ld.exe: region text overflowed by 460 bytes Thomas
Thomasjochenjohannes Vogtwilligbraun schrieb: > Hallo, > > danke für die Antworten. > > Könnte mir jemand beantworten was diese Fehlermeldung bedeutet? > > c:/winavr-20090313/bin/../lib/gcc/avr/4.3.2/../../../../avr/bin/ld.exe: > Thermometer.elf section .text will not fit in region text > c:/winavr-20090313/bin/../lib/gcc/avr/4.3.2/../../../../avr/bin/ld.exe: > region text overflowed by 460 bytes "will not fit" -> "wird nicht passen" "overflowed by xx bytes" -> "um xx Bytes zu überlaufen (zu gross)" Die Rede ist von der .text Sektion. Also wird euch wohl der Compiler darauf aufmerksam machen, dass irgendetwas zu gross ist Edit: Die Sektion .text ist der normale Programmcode (und nicht etwa Texte) Habt ihr den Optimizer schon an?
> RAM/Flash ist zu voll...
Das liegt an der Math-Bibliothek und an den ganzen Float-Werten, für die
die Gleitkomma-Bibliothek eingebunden wird. Das frisst ordentlich
Speicher.
Tobias schrieb: >> RAM/Flash ist zu voll... > > Das liegt an der Math-Bibliothek und an den ganzen Float-Werten, für die > die Gleitkomma-Bibliothek eingebunden wird. Das frisst ordentlich > Speicher. Aber nicht so viel, dass ein Mega88 bei diesem Code "überläuft". Vermutlich nicht die richtige Bibliothek mit dazu gelinkt.
Hallo zusammen, hab mal mit Optimization Os gemacht, und siehe da, keine Fehler mehr. Könnt mir vllt. jemand die unterschiede der Optimierungen erklären? Thomas
Thomasjochenjohannes Vogtwilligbraun schrieb: > Hallo zusammen, > > hab mal mit Optimization Os gemacht, und siehe da, keine Fehler mehr. > > Könnt mir vllt. jemand die unterschiede der Optimierungen erklären? Wenn du nicht optimierst, lässt der Compiler alles so wie du es geschrieben hast. Jeder Variablenzugriff, selbst Code der offensichtlich nie erreicht werden kann
1 | if( 1 == 2 ) |
2 | printf( "autsch" ); |
landet im Prozessor. Erlaubst du dem Compiler zu optimieren, dann darf er Code umstellen, Variablenzugriffe abkürzen (weil der Wert ohnehin schon in einem CPU Register vorliegt) etc... Welches Potential in einer Optimierung steckt, hast du ja jetzt gesehen. Zusätzlich laufen optimierte Programme meist auch schneller. Einziger Nachteil: Es ist nicht mehr so einfach den Programmablauf in einem Debugger zu verfolgen, da der angezeigte Source Code im Debugger nur mehr sher rudimentär mit dem übereinstimmt, was der Prozessor wirklich ausführt.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.