Forum: Compiler & IDEs Balkenanzeige der Temp auf LCD Anzeige


von Thomasjochenjohannes V. (Firma: HS HN) (vowibr)


Lesenswert?

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

von Stefan B. (stefan) Benutzerseite


Lesenswert?


von Karl H. (kbuchegg)


Lesenswert?

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.

von Thomasjochenjohannes V. (Firma: HS HN) (vowibr)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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?

von ... .. (docean) Benutzerseite


Lesenswert?

RAM/Flash ist zu voll...

von Tobias (Gast)


Lesenswert?

> 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.

von Stefan E. (sternst)


Lesenswert?

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.

von Thomasjochenjohannes V. (Firma: HS HN) (vowibr)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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
Noch kein Account? Hier anmelden.