www.mikrocontroller.net

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


Autor: Clemens Huhn (Firma: Stahl AG) (clemensh)
Datum:

Bewertung
0 lesenswert
nicht 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
}

Autor: Marco F. (m8_killer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

schau mal hier 
"http://www.mikrocontroller.net/articles/AVR-GCC-Tu... 
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.

Autor: Justus Skorps (jussa)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
PCINT 7 ist an PortB...

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

Autor: Marco F. (m8_killer)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Floh (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.
:-)

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Clemens Huhn (Firma: Stahl AG) (clemensh)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Clemens Huhn (Firma: Stahl AG) (clemensh)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.