Forum: Mikrocontroller und Digitale Elektronik Wie heißt der ADC Interrupt?


von Fabian S. (jacky2k)


Lesenswert?

Hallo,
Im ADCSRA-Register kann man ja den Interrupt für den ADC einschalten. 
Schön und gut, aber wie heißt der Interruptvektor, den ich bei 
ISR/SIGNAL reinschreiben muss?

von codehamster (Gast)


Lesenswert?

Wie oft muss ich das noch schreiben???

Wenn ihr fragen zu einem uC habt dann schreibt doch bitte auch mit 
welchem das ihr arbeitet! Ohne diese Information kann dir niemand 
weiterhelfen!

von Fabian S. (jacky2k)


Lesenswert?

Ups, sorry, total vergessen, mach ich aber normalerweise... :(
Atmega32 16PU

von Jojo (Gast)


Lesenswert?

davon mal abgesehen steht das aber auch in jedem datenblatt oder in den 
tutorials...

von Jean P. (fubu1000)


Lesenswert?

WINAVR + Atmega = ADC_vect

von Jean P. (fubu1000)


Lesenswert?

AVR-Assembler + Atmega = .org 0x00e  rjmp sonstwohin

von Johannes M. (johnny-m)


Lesenswert?

Fabian Ostner wrote:
> AVR-Assembler + Atmega = .org 0x00e  rjmp sonstwohin
Nö. Beim Mega32 ist es 0x020. Die Vektortabellen sind alles andere als 
gleich (nicht zuletzt aufgrund der Tatsache, dass AVRs mit bis zu 8 KiB 
Flash nur 16 Bit breite Interrupt-Vektoren haben und alle anderen 32 Bit 
breite). Die Vektoradressen kann man nicht für alle AVRs pauschal 
angeben. Da hilft nur der Blick ins Datenblatt.

von Fabian S. (jacky2k)


Lesenswert?

Jo, danke!
Da ich in C programmiere reicht das schon :)
Nur funktionieren tuts trotzdem nicht :(

void ADC_init()
{
  ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1);
}

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

  ADMUX = channel; // channel
  ADMUX |= (1<<REFS0);  // vcc as ref
  ADCSRA |= (1<<ADSC);  // dummyread
  return result;
}

ISR(ADC_vect)
{
  uart_putcc("ADC...");
}

Ich rufe erst ADC_init() auf, dann sei() und als letztes ADC_read(0).
Ich bekomme aber nichts über den uart, gehen tut er aber, da die 
Initialisierungsnachichten kommen.

Edit: lol Dummheit tut weh... wo ist denn zur Hölle das ADIE 
abgeblieben? Hatte es vorhin reingeschrieben :(
Mit ADIE gehts ;)

von gast (Gast)


Lesenswert?

du aktivierst den adc und wählst dann erst aus von wo er messen soll?
und wie sieht das mit sei(); aus?

von Fabian S. (jacky2k)


Lesenswert?

Ohh.. hast recht... aber ist das schlimm?
Ich schalte ihn ja nur ein, die erste Konvertierung mache ich ja erst am 
Ende...
sei() habe ich in der Main Funktion nachdem alles initalisiert wurde.

von Johannes M. (johnny-m)


Lesenswert?

@Fabian Ostner:
Sehe grad, Du hast explizit den AVR-Assembler erwähnt. Der arbeitet mit 
Wortadressen (richtet sich nach dem Program Counter, und der zählt 
Worte). Da wären es dann 0x10. Der GNU-Assembler z.B. arbeitet afair 
auch im Code-Bereich mit Byte-Adressen.

Wenn man in AVR-Assembler programmiert, macht es meist Sinn, die 
Vektortabelle komplett hinzuschreiben (ohne .org) und nicht benötigte 
Vektoren entweder mit reti (bzw. bei > 8 KiB Flash mit nop reti ) 
oder rjmp bzw. jmp zu einer Fehlerbehandlungsroutine zu füllen.

von gast (Gast)


Lesenswert?

wozu ist return result; da steht soch immer eine 0 drin, kannst komplett 
löschen

von Johannes M. (johnny-m)


Lesenswert?

Fabian S. wrote:
>   ADCSRA |= (1<<ADSC);  // dummyread
>   return result;
Was willst Du denn da returnen? In result steht da immer ne 0 drin. 
result wird nichts zugewiesen und außerdem sollte man auch warten, bis 
der ADC fertig ist mit seiner Wandlung.

Das Programm macht so, wie es da steht nicht viel Sinn. Bitte schick mal 
was vollständiges. Bei Dir wird z.B. nirgends das ADC-Datenregister 
ausgelesen. Das "return result" macht da auch keinen Sinn, weil result 
gar kein Wert zugewiesen wird.

von gast (Gast)


Lesenswert?

funktioniert die uart_putcc("..."); überhaupt, hast schon mal ohne 
interrupt probiert?
ist alles richtig angeschlossen?
bausdrate etc. richtig eingestellt?
ist uart auch richtig initialisiert und bereit bevor du mit adc 
anfängst?

von gast (Gast)


Lesenswert?

>>Bei Dir wird z.B. nirgends das ADC-Datenregister
>>ausgelesen.
das ist ja auch erst mal egal, er müsste ja trotzdem in die isr springen 
und auf uart was ausgeben, er spring aber anscheinend nicht in die isr

von Johannes M. (johnny-m)


Lesenswert?

gast wrote:
>>>Bei Dir wird z.B. nirgends das ADC-Datenregister
>>>ausgelesen.
> das ist ja auch erst mal egal, er müsste ja trotzdem in die isr springen
> und auf uart was ausgeben, er spring aber anscheinend nicht in die isr
Deshalb sage ich ja, dass man ohne ein vollständiges Programm gesehen 
zu haben nur spekulieren kann! In dem Schnipsel oben fehlt, wie schon 
von anderer Seite erwähnt, z.B. ein sei().

von gast (Gast)


Angehängte Dateien:

Lesenswert?

ich schickl dir mal meine adc lib, die ist zwar ohne isr, aber da wo bei 
mir die while schleifen in der adc_read sin, müsste bei dir die isr 
kommen (also ein flag in der isr signalisiert dir das die wandlung 
abgeschlossen ist oder so ähnlich)

von Fabian S. (jacky2k)


Lesenswert?

Hä?
Könnt ihr nicht lesen?
Hab doch geschrieben, das nun alles geht...oder bin ich auf ner anderen 
Seite als ihr? verwirrt

Jetzt sieht meine adc.c so aus:
#include "adc.h"

void ADC_init()
{
  ADCSRA = (1<<ADEN) | (1<<ADPS3) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADIE);
  ADMUX = 0;            // start with channel 0
  ADMUX |= (1<<REFS0);  // vcc als ref verwenden
  ADCSRA |= (1<<ADSC);  // first read to start...
}

void ADC_stop()
{
  // ADC wieder deaktivieren
  ADCSRA &= ~(1<<ADEN);
}

ISR(ADC_vect)
{
  uart_putcc("ADC...");
  ADCSRA |= (1<<ADSC);
}


Macht momentan eine Konvertierung nach der anderen, muss sie jetzt nur 
noch speichern.
Gibts ne Möglichkeit den ADC langsamer laufen zu lassen, als F_CPU/128?
Bei 16Mhz sind das 125kHz, 13 Takte braucht er für einen Wert, also 
macht er ~9600 Konvertierungen pro Sekunde... ist für meinen Geschmack 
etwas zu viel :) Oder hab ich mich irgendwie vertan?

von gast (Gast)


Lesenswert?

also wenn ich recht sehe hast du NICHT vorher gesagt das alles 
funktioniert, an was lags denn?

von gast (Gast)


Lesenswert?

ach so, wenns langsamer sein soll, dann takte doch deinen µC runter oder 
nimm nur jeden 10-ten wert

von Fabian S. (jacky2k)


Lesenswert?

Fabian S. wrote: (Datum: 01.10.2008 14:30)
> Edit: lol Dummheit tut weh... wo ist denn zur Hölle das ADIE
> abgeblieben? Hatte es vorhin reingeschrieben :(
> Mit ADIE gehts ;)

von gast (Gast)


Lesenswert?

na lol, du hast dein alten post geändert, das sieht natürlich keiner 
wenn wir selber amschreiben sind

von Fabian S. (jacky2k)


Lesenswert?

gast wrote:
> ach so, wenns langsamer sein soll, dann takte doch deinen µC runter oder
> nimm nur jeden 10-ten wert

Joa, runtertakten ist keine Option, da er eigentlich schon zu langsam 
ist ;)
Nur jeden 10. Wert, das wäre nun auch mein Ansatz, nur verschwende ich 
damit ja auch Rechenleistung, wenn in 9 von 10 Fällen der Interrupt 
ausgelöst wird um festzustellen, dass es garnicht nötig gewesen wäre :D
Aber das wird hoffentlich nicht so ins Gewicht fallen :D

von Fabian S. (jacky2k)


Lesenswert?

gast wrote:
> na lol, du hast dein alten post geändert, das sieht natürlich keiner
> wenn wir selber amschreiben sind

Das habe ich ~30 Sekunden nach dem eigentlichen Post gemacht, Ehrenwort 
:(

Edit: Wenn ich noch einen Post gemacht hätte, hätte ich einen aufn 
Deckel bekommen, mit dem netten Hinweis auf die Edit-Funktion...

von gast (Gast)


Lesenswert?

ich mach bei meinen adc routinen immer gleich eine mittelung über 
x-werte, da nimmst zwar jeden wert, würdest aber erst einmal 
zwischenspeichern und dann irgendwann (bsp nach 10-werten) den 
mittelwert ausgeben

von gast (Gast)


Lesenswert?

"Das habe ich ~30 Sekunden nach dem eigentlichen Post gemacht, Ehrenwort
:(

Edit: Wenn ich noch einen Post gemacht hätte, hätte ich einen aufn
Deckel bekommen, mit dem netten Hinweis auf die Edit-Funktion..."

naja, wir haben gelesen und gleich geschrieben und während wir 
geschrieben haben hast du deinen post geändert, deswegen haben wirs 
nicht gesehen

von Fabian S. (jacky2k)


Lesenswert?

gast wrote:
> ich mach bei meinen adc routinen immer gleich eine mittelung über
> x-werte, da nimmst zwar jeden wert, würdest aber erst einmal
> zwischenspeichern und dann irgendwann (bsp nach 10-werten) den
> mittelwert ausgeben
Joa, stimmt ;)

gast wrote:
>> "Das habe ich ~30 Sekunden nach dem eigentlichen Post gemacht, Ehrenwort
>> :(
>>
>> Edit: Wenn ich noch einen Post gemacht hätte, hätte ich einen aufn
>> Deckel bekommen, mit dem netten Hinweis auf die Edit-Funktion..."
>
> naja, wir haben gelesen und gleich geschrieben und während wir
> geschrieben haben hast du deinen post geändert, deswegen haben wirs
> nicht gesehen
Aso ok...naja nun ist es bekannt: Es geht! ;)

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.