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?
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!
Ups, sorry, total vergessen, mach ich aber normalerweise... :( Atmega32 16PU
davon mal abgesehen steht das aber auch in jedem datenblatt oder in den tutorials...
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.
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 ;)
du aktivierst den adc und wählst dann erst aus von wo er messen soll? und wie sieht das mit sei(); aus?
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.
@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.
wozu ist return result; da steht soch immer eine 0 drin, kannst komplett löschen
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.
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?
>>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
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().
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)
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?
also wenn ich recht sehe hast du NICHT vorher gesagt das alles funktioniert, an was lags denn?
ach so, wenns langsamer sein soll, dann takte doch deinen µC runter oder nimm nur jeden 10-ten wert
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 ;)
na lol, du hast dein alten post geändert, das sieht natürlich keiner wenn wir selber amschreiben sind
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
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...
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
"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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.