Hallo zusammen, ich komm nicht mehr weiter bei der ADC Schnittstelle. Ich bin gerade dabei mich in die ADC Schnittstelle des ATmega32 einzuarbeiten. Leider sind da einige Fragen noch offen. Ich kapier einfach nicht wie das vorgehen ist bei der sog. Single Conversation und dem Free Running Mode bzw. der Interrupthandhabung. Single Conversation starten kommt Messwert -> Interrupt wird ausgelöst O.K soweit verstanden aber bei Free Running Mode wird dauernd gelesen was heißt das wird da immer ein Interrupt ausgelöst. D.h Prozzessor wär nur mit ADC beschäftigt wenn z.B ein Analog Wert anliegt.?? Bei Free Running ist da ADSC Bit dann dauern auf 1 ? Oder wird zwischendrin wie bei Single Conversation nach Umwandlung des Empfangswertes dieses Bit (ADSC) auf 0 gesetzt? Wer kann mir in dieser Problematik weiterhelfen, lese schon dauern die Spec werd aber in diesen und vielen anderen Punkten nicht schlau... Vielen Dank im Voraus Peter
Weiß jemand einen Source Code in Assembler indem man die grundlegende Handhabung des ADC (evtl mit single und free Running mode , Interrupt) nachvollziehen kann . Oder in irgend einem Tutorial ? Vielen Dank
Wenn du mal guckst, was die maximale Samplezahl pro Sekunde ist (15kSps), wirst du feststellen, dass dir genug Zeit bleibt, um zwischen den einzelnen Interrupts selbst bei 1MHz noch komplexere Aufgaben zu erledigen. (Bei voller A/DC Frequenz bei 8MHz bleiben etwa 500 Taktzyklen, um den AD-Wert zu verarbeitn und anderes zu machen. Aber ich denke mal, dass du den A/D-Wandler nicht mit voller Frequenz betreiben mußt, oder?) Wie das mit dem Bit ist, weiß ich nicht, aber das steht alles im Datenblatt. (Ich weiß: "...lese schon dauern die Spec werd aber in diesen und vielen anderen Punkten nicht schlau...". Trotzdem, lesen bildet!)
Hallo, ich habe bisher nur am Mega8 mit dem ADC gearbeitet, denke aber, dass es prinzipiell gleich ist. Während beim Single-Conversion das ADSC wieder auf Null gesetzt wird, bleibt es im Free-Running mode auf Eins, d.h. es wird nur einmal am Beginn vom Programm gesetzt. Wenn der Interrupt aktiviert ist, dann wird er immer am Ende einer Wandlung ausgelöst, sei es jetzt Single-Conv. oder Free-Running. Der µC wird also in diesem Sinne nur beschäftigt, wenn ein Wert fertig ist. Es ist allerdings zu beachten, dass im Free-Running auch weiter gewandelt wird, wenn das Interrupt-Flag nicht gelöscht wird. Wenn also dein Programm nicht jeden Interrupt vom ADC auswertet (oder auswerten kann) dann würden Werte verloren gehen. Viele Grüße
Hallo Peter, Source Code kann ich dir heute abend suchen - aber wahrscheinlich hat bis dahin schon jemand anderes welchen geschickt ;-) Ansonsten würde ich empfehlen nochmal bei www.avrfreaks.net nachschauen, da gibt's einen Haufen Tutorials. Viele Grüße
Hallo Peter, und nochmal ;-) Ganz vergessen hatte ich die App. Notes direkt von www.atmel.com Dort werden viele Einzelproblematiken gut beschrieben. Kann sein, dass da was über ADC bei ist. Viele Grüße
Danke Thomas für Deine Hilfe, leider bin ich noch kein bisschen vorangekommen. Kann jemand mal über den Sourcecode schauen was faul ist ? ich will an ADC0 eine Spannung anlegen die dann gewandelt am Port A (Low Byte) auch ausgegeben werden soll (Ich weiß 1 Bit fehlt wegen des Eingangspins) Leider tut sich nichts an den LEDs ; Bei Single Step springt Programm immer auf TIM0_OVERFLOW dann auf ADR 0 -> Srung auf main ???? Vielen Dank Peter rjmp main ; Reset Handler reti ; EXT_INT0 ; IRQ0 Handler reti ;EXT_INT1 ; IRQ1 Handler reti ;EXT_INT2 ; IRQ2 Handler reti ;TIM2_COMP ; Timer2 Compare Handler reti ;TIM2_OVF ; Timer2 Overflow Handler reti ;TIM1_CAPT ; Timer1 Capture Handler reti ;TIM1_COMPA ; Timer1 CompareA Handler reti ;TIM1_COMPB ; Timer1 CompareB Handler reti ;TIM1_OVF ; Timer1 Overflow Handler reti ;TIM0_COMP ; Timer0 Compare Handler reti ;TIM0_OVF ; Timer0 Overflow Handler reti ;SPI_STC ; SPI Transfer Complete Handler reti ;USART_RXC ; USART RX Complete Handler reti ;USART_UDRE ; UDR Empty Handler reti ;USART_TXC ; USART TX Complete Handler rjmp ADC ; ADC Conversion Complete Handler reti ;EE_RDY ; EEPROM Ready Handler reti ;ANA_COMP ; Analog Comparator Handler reti ;TWI ; Two-wire Serial Interface Handler reti ;SPM_RDY ; Store Program Memory Ready Handler main: ;Initialisierung des Stack Pointers ->notwendig bei Interrupt Sprüngen ldi stack,LOW(RAMEND);Initiate Stackpointer out SPL,stack ; wegen Interrupts und Unterprogr. ldi stack,HIGH(RAMEND) out SPH,stack ;Stackpointerinitialisierung ende ldi ll,0x00 out ADMUX,ll ldi ll,0xFB out ADCSR,ll ;Reg ADCSRA beschrieben ldi port_direction, 0xfe out DDRA, port_direction ;PortB auf Ausgang schalten sei ;Set Global Interrupt Enable this means bit7 in Status Register is set to 1. loop: ;ldi kk,0xDB ;out ADCSR,kk ;Reg ADCSRA beschrieben-> Neue Konversation eingeleitet rjmp loop ADC: in mp,ADCL in tr,ADCH out PORTA,mp ;out PORTA,tr reti
Hi, warum setzt du das ADIF Bit? Im Anhang is nen kleines ADC Programm, momentan als Free runnning, der Programmteil für Single Conversion ist auch dabei Bis denn
Hallo Christoph, danke für dein Programm, aber auch mit deinem Programm rührt sich nichts, was kann ich noch alles probieren. Kann es daran liegen das ich Eingang und Ausgang den Port A benutze? Aber ich schalte doch um, bzw. hab einen Pin als Eingang definiert. Dein Programm indem ich in der ISR den PortA setze... Übrigens das Interrupt Flag hab ich nur aus sicherheitsgründen gelöscht, damit ich weiß daß auf jeden Fall kein Interrupthandling während dieses Abschnittes vorkommt. Danke Peter rjmp main ; Reset Handler reti ; EXT_INT0 ; IRQ0 Handler reti ;EXT_INT1 ; IRQ1 Handler reti ;EXT_INT2 ; IRQ2 Handler reti ;TIM2_COMP ; Timer2 Compare Handler reti ;TIM2_OVF ; Timer2 Overflow Handler reti ;TIM1_CAPT ; Timer1 Capture Handler reti ;TIM1_COMPA ; Timer1 CompareA Handler reti ;TIM1_COMPB ; Timer1 CompareB Handler reti ;TIM1_OVF ; Timer1 Overflow Handler reti ;TIM0_COMP ; Timer0 Compare Handler reti ;TIM0_OVF ; Timer0 Overflow Handler reti ;SPI_STC ; SPI Transfer Complete Handler reti ;USART_RXC ; USART RX Complete Handler reti ;USART_UDRE ; UDR Empty Handler reti ;USART_TXC ; USART TX Complete Handler rjmp ADC ; ADC Conversion Complete Handler reti ;EE_RDY ; EEPROM Ready Handler reti ;ANA_COMP ; Analog Comparator Handler reti ;TWI ; Two-wire Serial Interface Handler reti ;SPM_RDY ; Store Program Memory Ready Handler main: ;Initialisierung des Stack Pointers ->notwendig bei Interrupt Sprüngen ldi stack,LOW(RAMEND);Initiate Stackpointer out SPL,stack ; wegen Interrupts und Unterprogr. ldi stack,HIGH(RAMEND) out SPH,stack ;Stackpointerinitialisierung ende ldi ll,0xb00100000 out ADMUX,ll ldi ll,0x0b11101101 out ADCSR,ll ;Reg ADCSRA beschrieben ldi port_direction, 0xfe out DDRA, port_direction ;PortB auf Ausgang schalten sei ;Set Global Interrupt Enable this means bit7 in Status Register is set to 1. loop: ;ldi kk,0xDB ;out ADCSR,kk ;Reg ADCSRA beschrieben-> Neue Konversation eingeleitet jmp loop ADC: in mp,ADCL in tr,ADCH out PORTA,tr ;out PORTA,tr ldi port_direction, 0xfe out DDRA, port_direction ;PortB auf Ausgang schalten reti
Hallo Peter, ich hab zwar noch nicht mit dem ADC beim Mega32 gearbeitet, was mir aber Aufgefallen ist, ist das deine IRQ-Vectoren ins leere laufen. Beim Mega32 ist jeder Vector 4 und nicht 2 Byte(wie bei den "alten" AVR's) gross. Sprich du müsstes 2 reti pro Vector eintragen, oder besser mit .org-Anweisungen arbeiten. Kleines Beispiel: .org 0 rjmp start ; Reset Handle .org INT0addr rjmp Int0Interrupt .org INT1addr rjmp Int0Interrupt .org OVF1addr reti Gruß -=jens=-
Hallo Jens, danke für deinen Hinweis, Du hast recht! Ich hab noch nicht mit org gearbeitet Ist das so richtig Interrupt kommt->MC springt auf die entsprechende Adr. in der z.B .org 0x0010 steht -> was heist das dann genau bzw. der darauffolgende Befehl mit rjmp Name von ISR Label... Kannst du mir das bitte noch erklären? Danke Peter
Hallo Peter, erstmal ist es am besten (übersichtlichsten) wenn du bei den .org Anweisungen mit symbolischen Adressen arbeitest, also für deinen ADC-Interrupt nicht: .org $20, sondern .org ADCCaddr. Dies kennzeichnet die Adresse in der Vector-Sprungtabelle, die durch den ADC-Interrupt Angesprungen wird. Der dort stehende Code wird direkt ausgeführt, deshalb springt man von dort zur eigentlichen Interruptroutine. Achtung, wenn dein Programm größer wird gibt es Probleme mit dem rjmp Befehl, da der nur eine Sprungweite von +-2kB schaft. In diesem Fall musst du den jmp Befehl verwenden. Zur Addressierung der Interruptvectoren schau dir mal die m32def.inc Datei an, dort sind ganz am Ende die Zuweisungen für die Vectoradressen Gruß -=jens=-
Hallo Jens, aber was sagt genau folgendes ----------------------------- .org ADCCaddr rjmp ADC_HANDLING ADC_HANDLING: ... ------------------------------ wann wird .org ausgeführt bzw. was macht er dann, und wann wird rjmp ausgeführt...? bisher habe ich das nur mit den direkten Interrupteinsprungadressen gemacht da hab ich gewußt bei Interrupt ... springt er auf Adr. z.B 0x020 in meinem Fall und dort habe ich einen rjmpt gesetzt, die anderen Interrupteinsprungstellen habe ich mit reti belegt das ist mir klar aber das mit org .?? Sorry hab noch nicht so viel Erfahrung Danke Peter
Hallo Peter, der .org ist nur ne Compileranweisung die dafür sorgt, das der Code an eine definierte Adresse kommt. Ansonsten ist dein Vorgehen richtig. Wie gesag der Unterschied zwischen dem Mega32 und den kleineren AVRs ist, das die Sprungtabelle jeweils 4 Byte für jeden Vector groß ist (damit man per jmp den gesammten Adressraum ansprechen kann). Wenn du jetzt die Tabelle mit .org Anweisungen aufbaust liegen die Sprungbefehle automatisch auf der richtigen Adresse, unabhängig vom eingesetzten AVR. Gruß -=jens=-
AHHH, Jetzt glaub ich hab ichs, die Anweisung .org ADCCaddr rjmp ADC_HANDLING setzt den rjmp Befehl auf die Adr. $0020 richtig ? Ich glaube schon... Vielen Dank Peter PS: Weist du vielleicht ob es eine Besonderheit beim Atmega32 gibt. Ich hab nämlich ein ganz triviales Programm geschrieben das auf PORTA nur high pegel ausgeben soll -> es funktioniert > programmier ich aber das ganze auf den PortC um so leuchten nur 4 der 8 LEDs (4 High Pegel) -> Weist Du rat ?? Peter
Zu meiner letzten Fragen bzgl. Ausgabe an Port C habe ich jetzt nach Stundenlanger Suche den Fehler gefunden -> Die JTAG Schnittstelle war enabeld... damit war eine Anzeige nicht auf allen Ports möglich So gehen die Stunden ins Land... Grüße Peter
Hallo Peter, sorry zu deinem PORTC Problem fällt mir z.Zt. nichts ein. Gruß -=jens=-
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.