PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Anfängerproblem



OML221
23.05.2009, 01:58
Hallo zusammen,

wir haben gerade im Studium den ATMega88
Für diesen Controller wollte ich nun ein ganz einfaches Programm schreiben nur leider hab ich nen kleinen Fehler drin und ich finde ihn nicht.
Bestimmt kennt sich der eine oder andere gut aus und kann mir nen Tipp geben.

Also das Ziel ist das die LED leuchtet sobald ein Spannungswert unterschritten wird. (Interne Spannung als Referenz) Das Funktioniert auch, allerdings nur ein einziges mal.
Danach muss ich RESET drücken damit der Controller den neuen Wert auslesen kann und entsprechend reagiert.
Das soll natürlich nicht so sein, es soll ständig überprüft werden und wärend das Programm läuft auf Änderungen reagieren.


Hier mal das kurze Programm:


//----------------------------------------------------------------------
// Titel : Spannungstest mit LED
//----------------------------------------------------------------------
// Funktion : Schaltet Bit 2 an Port B (LED) an wenn Spannung
an ADC 0 einen Wert unterschreitet
// Schaltung : ...
//----------------------------------------------------------------------
// Prozessor : ...
// Takt : 3.6864 MHz
// Sprache : C
// Datum : ...
// Version : ...
// Autor : ...
//----------------------------------------------------------------------
#define F_CPU 3686400 // Taktferquenz des myAVR-Boards
#include <avr\io.h> // AVR Register und Konstantendefinitionen
#include <avr\interrupt.h>
#include <inttypes.h>

void Init_Ports(void);
uint16_t readADC(uint8_t channel);

int main(void)
{

Init_Ports();
uint16_t result = readADC(0);

while(1) // Hauptschleife der main-Funktion
{
//Auslesen der analogen Spannungen an Pin 0,
// also ADC0. In result steht das Ergebnis.
if (result < 53)
{
PORTB = 0x04; // LED toggeln
}
else
PORTB = 0x00;

}

return(1);
}

void Init_Ports(void)
{

DDRB |= (1 << DDB2); // PORTB PB2 als Ausgabe (LED)
PORTB |= (1 << PB2);
}

uint16_t readADC(uint8_t channel)
{
uint8_t i;
uint16_t result = 0;

// Den ADC aktivieren und Teilungsfaktor auf 64 stellen
ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1);

// Kanal des Multiplexers waehlen
ADMUX = channel;
// Interne Referenzspannung verwenden (also 2,56 V)
ADMUX |= (1<<REFS1) | (1<<REFS0);

// Den ADC initialisieren und einen sog. Dummyreadout machen
ADCSRA |= (1<<ADSC);
while(ADCSRA & (1<<ADSC));

// Jetzt 3x die analoge Spannung and Kanal channel auslesen
// und dann Durchschnittswert ausrechnen.
for(i=0; i<3; i++) {
// Eine Wandlung
ADCSRA |= (1<<ADSC);
// Auf Ergebnis warten...
while(ADCSRA & (1<<ADSC));

result += ADCW;
}

// ADC wieder deaktivieren
// ADCSRA &= ~(1<<ADEN);

result /= 3;

return result;
}



Vielen Dank
Gruß
Oli

sternst
23.05.2009, 02:54
Dann schau dir deine main nochmal genau an.
Du liest einmal den ADC aus, und danach wertest du in einer Endlosschleife immer wieder das Ergebnis dieses einmaligen Auslesens aus.

PS: Und nächstes mal bitte die Code-Tags verwenden.

SprinterSB
23.05.2009, 09:56
result = blah() muss also in die Schleife.

Zudem wird ei Port getoggelt, indem man das entsprechende Bit in PIND auf 1 setzt. Aber was du willst ist wohl garkein Toggle...

..und es heisst avr/io.h und nichts mit Backslash oder so'n Zeug. Auch nicht unter Windoofs.

OML221
23.05.2009, 11:56
Klar, wie doof, habs jetzt aber hinbekommen, danke für Eure Antworten!

@SprinterSB
es ist egal ab man avr/io.h oder avr\io.h schreibt, beides hat den selben Effekt

schöne WE!

sternst
23.05.2009, 16:35
es ist egal ab man avr/io.h oder avr\io.h schreibt, beides hat den selben Effekt
Funktioniert != Richtig

Der Compiler (oder genauer: Präprozessor) ist so freundlich, deinen Backslash zu schlucken und das zu machen, was du erwartest. Das macht diesen Backslash aber nicht "richtig". Der nächste Compiler ist vielleicht nicht so freundlich, also gewöhnt man sich das besser gar nicht erst an.