- 3D-Druck Einstieg und Tipps         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 15

Thema: adc-wert regelmässig auslesen mit interrupt

  1. #1
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    20.06.2004
    Beiträge
    1.941

    adc-wert regelmässig auslesen mit interrupt

    Anzeige

    Praxistest und DIY Projekte
    hallo, am adc-0 (avr16) wird durch ein rad-encoder immer ein wert zwischen 60 und 240 ausgegeben. beim wert unter 100 soll die variable hochgezählt werden und bei einem wert über 200 soll die variable hochgezählt werden.
    kann keine lösung über interrupt finden.
    mfg pebisoft

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    53
    Beiträge
    2.236
    Und wo liegt das Problem?
    Mach einen freilauf ADC, und werte in der Interruptroutine die Werte aus. Bei Bedarf kann ich Dir ein Codeschnipsel schicken,
    Gruß Sebastian

  3. #3
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    20.06.2004
    Beiträge
    1.941
    was ist ein freilauf-adc . komme mit dieser adc-auswertung im interrupt nicht klar.
    mfg pebisoft

  4. #4
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    53
    Beiträge
    2.236
    Ganz einfach :

    Freilauf ADC -> der wert wird ständig ausgelesen
    Ich weiß zwar nicht in welcher Sprache Du progst, aber ich mach es so in Assembler:
    Code:
    ldi tmp,(1<< ADEN) | (1<<ADFR) | (1<<ADIE) | (1<<ADSC) | (1<<ADPS0) | (1<<ADPS1) | (1<<ADPS2)
    	out ADCSRA,tmp
    	ldi tmp,(1<<REFS0) | (1<<ADLAR) | (1<<MUX0)
    	out ADMUX,tmp
    Der ADFR bit schaltet Free Run modus ein.

    Du mußt Dir auch noch den passenden Interruptvektor einrichten

    Code:
    .org ADCCaddr
    	rjmp ADCcomplete	; ADC Interrupt Vector Address

    Jetzt Springt er nachdem er jedesmal fertig ist mit ADC nach ADCcomplete

    in ADCcomplete routine:
    Code:
    in tmp,ADCL
    	in tmp,ADCH
    Es wird zwar der LOW Byte überschrieben, das macht aber nichts weil der wert linksgerichtet ist (sehe ADLAR Bit in ADMUX) und die zwei unteren bits kann man ruhig hier weglassen.

    Jetzt prüfst Du den Wert in tmp nach Deinen >100 oder <200 und änderst den Zähler entsprechend.
    Zum schluß reti und fertig.

    Hoffe, daß es verständlich war, wenn Du C benutzt wird es wohl auch kein Problem sein die Assembler schnipsel zu verstehen.

    Gruß Sebastian

  5. #5
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    20.06.2004
    Beiträge
    1.941
    ich progge in winavr-c.
    mfg pebisoft

  6. #6
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    53
    Beiträge
    2.236
    ich progge in winavr-c.
    Dann ist das wohl kein Problem das von mir geschriebene umzusetzen.

    mach doch etwa so :
    Code:
    ADCSRA=(1<< ADEN) | (1<<ADFR) | (1<<ADIE) | (1<<ADSC) | (1<<ADPS0) | (1<<ADPS1) | (1<<ADPS2);
    ADMUX = (1<<REFS0) | (1<<MUX0);
    Der Interrupthandler
    Code:
    SIGNAL (SIG_ADC) {
    int result;
    result  = ADCL + (ADCH << 8);
    if (result < 100){
    zaehler++;
    } else if (result > 200) {
    zaehler--;
    }
    }
    Dein Zähler muß Du nur volatile Deklarieren, damit er im Interrupt auch zugänglich ist.
    Naja und sonstige headers nicht vergessen (signal.h interrupt.h)

    Ich hoffe, daß es Dir weiterhilft

    Gruß Sebastian

  7. #7
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    20.06.2004
    Beiträge
    1.941
    sag mal : 1<<ADFR kennt er nicht, gibt es für ADFR noch einen anderen ausdruck.
    "adc_lcd.c:44: error: `ADFR' undeclared (first use in this function)"
    mfg pebisoft

  8. #8
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    53
    Beiträge
    2.236
    Ein Auszug aus meiner iom16.h :
    #define ADCSRA _SFR_IO8(0x06)
    #define ADPS0 0
    #define ADPS1 1
    #define ADPS2 2
    #define ADIE 3
    #define ADIF 4
    #define ADATE 5
    #define ADSC 6
    #define ADEN 7
    Der ADFR ist dabei Bit Nr. 5 also muß es heissen (1<<ADATE) und nicht (1<<ADFR)

    Komisch, warum das so ist weiß ich nicht, ich dachte, daß wäre 1:1 von den Bits des AVR´s
    übernommen.
    Ist es ein Bug, oder warum haben sie den Namen geändert ?
    Na ja versuch es mit ADATE

    Gruß Sebastian


    EDIT:

    Ups, stimmt alles nicht so ganz, also :
    es gibt wirklich kein ADFR bei MEGA 16 sondern ADATE:
    Bit5 - ADATE: ADC Auto Trigger Enable
    When this bit is writen to one Auto Triggering of the ADC is enabled.
    also ADATE doch einschalten


    Und wann er dann Triggerd bestimmt der Register SFIOR
    Für Free Running mode sieht es dann so aus

    SFIOR &= ~(1<<ADTS0) | (1<<ADTS1) | (1<<ADTS2);

    Sehe auch Dattenblatt Seite 215.
    Damit hast Du den Free Running eingeschaltet.

    Ich habe es mit Dattenblatt von Mega 8 verglichen, wußte nicht, daß sie das bei Mega 16
    sooooo verändert haben

  9. #9
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    20.06.2004
    Beiträge
    1.941
    hallo, funktioniert klasse, vielen dank für deine schnelle hilfe.
    mfg pebisoft
    ps:
    Und wann er dann Triggerd bestimmt der Register SFIOR
    Für Free Running mode sieht es dann so aus
    SFIOR &= ~(1<<ADTS0) | (1<<ADTS1) | (1<<ADTS2);

    was ist das.
    habe es nicht eingesetzt, es läuft trotzdem automatisch mit dem interrupt.

  10. #10
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    53
    Beiträge
    2.236
    Freut mich.

    Gruß Sebastian

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Labornetzteil AliExpress