Forum: Mikrocontroller und Digitale Elektronik Dringend Hilfe gesucht AD-Wandler


von Clemens H. (Firma: Stahl AG) (clemensh)


Lesenswert?

Hallo Zusammen,
ich muss die Woche unbedingt noch ein Projekt zum Abschluss bringen.
Es ist zum Haare ausreißen, es will einfach nicht.
Ich wäre echt für jeden Tipp dankbar! xD


Benutzen tue ich das AVR Studio 4 mit Tiny 48 als µC.
Das Programm ist rudimentär vereinfacht, enthält aber die dringend 
nötige ADC und Interrupt Funktionen.

Die Probleme:
1. Der interrupt löst nicht aus.
2. Der ADC hat zuerst völlig seltsame werte, selbst ohne Spannung 
ausgegeben, nach der Vereinfachung bleibt der Compiler bereits beim 
Abwarten auf die AD-Wandlung hängen ADSC von 1 auf 0.


Hier der Programm Code:
_______________________________________

#define F_CPU 8000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>
#include <stdint.h>


int main(void)
{
//Datenrichtung
DDRA=0;
DDRB=0;
DDRC=0b11000000;//ADC  PC0-5// PCI bei PC7
DDRD=0b00011111;// Leuchtmelder/LED

//Interrupt
PCICR =0b00000001;// PORT C
PCMSK0=0b10000000;// PCINT 7
sei();//algemeine Interrupt freigabe

//AD-Wandler
ADMUX |=0b00100000;//ADLAR //left adjust result
ADMUX |=0b00000111;// kanalauswahl ADC7
ADCSRA |=0b10000000;//ADEN ADC einschalten
ADCSRA |=0b0000111;// Vorteiler 128


//ADC Read // Das erste Auslesen als Dummyread
ADCSRA |=0b01000000;//ADSC startet AD wandlung
while (ADCSRA & (1<<ADSC) ); // auf Abschluss der Konvertierung warten
uint8_t ADCwert= ADCH;

ADCSRA |=0b01000000;//ADSC startet AD wandlung
while (ADCSRA & (1<<ADSC) ); // auf Abschluss der Konvertierung warten
ADCwert= ADCH;


PORTD=0b00010000; // Leuchtmelder an

//Interrupt auslösen
PORTC=0b00000000;
PORTC=0b11111111;
do
{
if(ADCwert>=100)
{PORTD=0b00000110;}
}
while(1);

}

ISR(PCINT0_vect)
{
PORTD=0b00001111;//Leuchtmelder aus
}

von Marco F. (m8_killer)


Lesenswert?

Hallo,

schau mal hier 
"http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#ADC_.28Analog_Digital_Converter.29"; 
das dürfte dir weiterhelfen, ich benutze die beispiel routine selber mit 
nem atmega8.

das "flattern" des des adc wertes ist normal, kannst du mit nem elko 
stabilisieren.

von Justus S. (jussa)


Lesenswert?

PCINT 7 ist an PortB...

und gewöhn dir gleich eine vernünftige Schreibweise von Zuweisungen an, 
sowas
> DDRC=0b11000000;
ist Mist

von Marco F. (m8_killer)


Lesenswert?

Dus olltest ausserdem mit sei(); den interupt global einschalten, sonst 
gehts nicht. mein vorredner hat recht, in 2 wochen weisst du selber 
nicht mehr welche bits du geschaltet hast
schreibe besser

DDRB |= (1<<PB0) | (1<<PB2) ...usw

von Floh (Gast)


Lesenswert?

Clemens Huhn schrieb:
> do
> {
> if(ADCwert>=100)
> {PORTD=0b00000110;}
> }
> while(1);

erwartest du hier irgendwelche Änderungen an PORTD?
ADCwert änderst sich ja nicht mehr, da du ihn nur >vor< der Schleife 
beschreibst.
:-)

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> sowas
>> DDRC=0b11000000;
> ist Mist
Richtig, da schreibt man besser
DDRC=0xC0;
das ist wenigstens protabel... ;-)

> DDRB |= (1<<PB0) | (1<<PB2) ...usw
Das ist bei einem Port Register jetzt aber irgendwie witzlos, oder?
>> DDRC=0b11000000;
>> DDRC=0xC0;
Ich zumindest sehe hier auf einen kurzen Blick, dass die obersten beiden 
Bits Ausgänge sind.
Bei Steuer Registern lasse ich da gern nochmal mit mir reden... ;-)

> erwartest du hier irgendwelche Änderungen an PORTD?
Da war dann noch die Zeile
>>  PORTD=0b00001111;//Leuchtmelder aus

von Clemens H. (Firma: Stahl AG) (clemensh)


Lesenswert?

Danke erstmal für eure Mühe.
Das mit der schreibweise werde ich mir zu Herzen nehmen. xD

Der ADC Wert soll nur einmal eingelesen werden, die do-while Schleife 
ist nur zur überprüfung der Interrupt Funktion da drin.
Später werden die Eingänge des ADC ständig ausgelesen und mit den 
kritischen Werten verglichen.
Am PORTD hängen LEDs dran, die zeigen Momentan nur ob der ADC Wert den 
entsprechenden Wert ließt und ob der Interrupt ausgelöst hat.

Ich werd das jetzt mal testen und poste später ob nun alles 
funktioniert.

von Clemens H. (Firma: Stahl AG) (clemensh)


Lesenswert?

Danke erstmal für eure Mühe.
Das mit der schreibweise werde ich mir zu Herzen nehmen. xD

Der ADC Wert soll nur einmal eingelesen werden, die do-while Schleife 
ist nur zur überprüfung der Interrupt Funktion da drin.
Später werden die Eingänge des ADC ständig ausgelesen und mit den 
kritischen Werten verglichen.
Am PORTD hängen LEDs dran, die zeigen Momentan nur ob der ADC Wert den 
entsprechenden Wert ließt und ob der Interrupt ausgelöst hat.

Funktioniert soweit jetzt alles prima. Besten Dank

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.