- Labornetzteil AliExpress         
Seite 2 von 3 ErsteErste 123 LetzteLetzte
Ergebnis 11 bis 20 von 23

Thema: AD-Wandler freilauf Fragen

  1. #11
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    11.11.2005
    Beiträge
    321
    Anzeige

    Praxistest und DIY Projekte
    beim AVR8 schaltest du einfach zwischendurch auf den mux3, den gibt es nämlich nicht beim AVR 8 (sondern nur das register) und schaltest dann auf den port mit dem mux den du brauchen tust im freilaufmodus und schon klappt es. also mux3 und dann den port zum auslesen und immer weiter so.

  2. #12
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    52
    Beiträge
    2.236
    @Sternthaler

    Ein Beispiel braucht man nicht weit suchen, bleiben wir doch beim Asuro.
    Ich erlaube mir die erweiterte Bibliothek von Weja zu zitieren,

    SIG_ADC Routine für Odometrie, in Encoder_Init() wird adc Freerunning
    eingeschaltet

    Code:
    SIGNAL (SIG_ADC)
    
    {
    
    	static unsigned char tmp[2],flag[2],toggle;
    
    	if (autoencode){
    
    	tmp[toggle]= ADCH;
    
    	if (toggle)	ADMUX = (1 <<ADLAR) | (1 <<REFS0) | WHEEL_RIGHT; 
    
    	else ADMUX = (1 <<ADLAR) | (1 <<REFS0) | WHEEL_LEFT; 
    
    
    
    	if ( (tmp[toggle] <= 160) && (flag[toggle] == TRUE)) {
    
    		encoder[toggle] ++;
    
    		flag[toggle] = FALSE;
    
    	}
    
    	if ( (tmp[toggle] > 160) && (flag[toggle] == FALSE)) {
    
    		encoder[toggle] ++;
    
    		flag[toggle] = TRUE; 
    
    	}
    
    	toggle ^= 1;
    Ich brauche Dir das wohl nicht näher zu erklären, was hier passiert, aber klar, bei jedem Interrupt wird der Kanal umgeschaltet und es klappt, das habe ich schon öfters umgesetzt und keine Problemme mit gehabt...

    @castle

    klar fühlst Du Dich pudelwohl, wahrscheinlich geht Dir immer einer ab, wenn Du jemanden niedermachen kannst...

    Gruß Sebastian

  3. #13
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    11.11.2005
    Beiträge
    321
    aber klar, bei jedem Interrupt wird der Kanal umgeschaltet und es klappt...

    nicht immer...he.....aber immer öfter.... und das ist mir zu unsicher und schalte darum den mux3 dazwischen und erst dann habe ich die 100%

  4. #14
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    29.05.2005
    Beiträge
    1.018
    Zitat Zitat von Auf Seite 197 in der ATmega8-Doku
    Changing Channel or Reference Selection
    The MUXn and REFS1:0 bits in the ADMUX Register are single buffered through a temporary
    register to which the CPU has random access. This ensures that the channels
    and reference selection only takes place at a safe point during the conversion. The
    channel and reference selection is continuously updated until a conversion is started.
    Once the conversion starts, the channel and reference selection is locked to ensure a
    sufficient sampling time for the ADC. Continuous updating resumes in the last ADC
    clock cycle before the conversion completes (ADIF in ADCSRA is set). Note that the
    conversion starts on the following rising ADC clock edge after ADSC is written. The user
    is thus advised not to write new channel or reference selection values to ADMUX until
    one ADC clock cycle after ADSC is written.
    If both ADFR and ADEN is written to one, an interrupt event can occur at any time. If the
    ADMUX Register is changed in this period, the user cannot tell if the next conversion is
    based on the old or the new settings. ADMUX can be safely updated in the following
    ways:
    1. When ADFR or ADEN is cleared.
    2. During conversion, minimum one ADC clock cycle after the trigger event.
    3. After a conversion, before the Interrupt Flag used as trigger source is cleared.
    When updating ADMUX in one of these conditions, the new settings will affect the next
    ADC conversion.
    Punkt 1 ist klar, hier soll ADFR gesetzt sein.

    Punkt 2 ist ein Timing um der S/H-Schaltung Zeit zu geben. Kein Einflus, da das Timing ja über den ADC-Interrupt kommt und wir dort ja den MUX 'umschalten' wollen. Und zwar möglichst schnell. ABER: 'Once the conversion starts, the channel and reference selection is locked' dies wird bestimmt auf das Timing achten!?!?

    Punkt 3. Hier stehe ich etwas im Regen. Ich verstehe das so: Conversion ist fertig; Interrupt noch nicht ausgelösst; Unser Programm löscht das ADIF-Flag. Das aber kann nicht im Interrupt passieren, da er ja nicht ausgelösst wurde, und somit verstehe ich es so, das 'aus versehen' ein loopendes Hauptprogramm das Flag 'so nebenbei' zurücksetzt.
    Das sollte unsere Loop also nicht unbedingt machen.


    Gut; soweit lese ich hieraus, was im internen Ablauf in der CPU, zu welchem Zeitpunkt passiert, um die in ADMUX gesetzten Bits überhaupt zu berücksichtigen.

    Nun folgendes aus der Doku:
    Zitat Zitat von Auf Seite 198 in der ATmega8-Doku
    ADC Input Channels
    When changing channel selections, the user should observe the following guidelines to
    ensure that the correct channel is selected:
    In Single Conversion mode, always select the channel before starting the conversion.
    The channel selection may be changed one ADC clock cycle after writing one to ADSC.
    However, the simplest method is to wait for the conversion to complete before changing
    the channel selection.
    In Free Running mode, always select the channel before starting the first conversion.
    The channel selection may be changed one ADC clock cycle after writing one to ADSC.
    However, the simplest method is to wait for the first conversion to complete, and then
    change the channel selection. Since the next conversion has already started automatically,
    the next result will reflect the previous channel selection.
    Subsequent conversions
    will reflect the new channel selection.
    Nicht dass ihr denkt, ich hätte das selbst geschrieben. Englisch war nicht unbedingt mein Lieblingsfach. Das lesen ist aber noch OK, so hoffe ich. Manchmal hapert es halt an der Interpretation.

    Frage:
    Warum läuft Weja's Bibliothek-Funktion? (Hier habe ich leider tatsächlich eine Vermutung. Trotz meiner Vermutung, ist sie aber in genau der vorliegenden Form funktionsfähig. Später mehr dazu bei Bedarf.)
    Aber es kann ja noch folgende Frage beantwortet werden:
    Was habe ich nicht an der Doku verstanden?
    Lieber Asuro programieren als arbeiten gehen.

  5. #15
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    19.03.2005
    Ort
    Villach
    Alter
    32
    Beiträge
    995
    Hi,
    kann mir wer schnell alle die register erklären. kurz und bündig. reicht ein kleiner satz zu jeden register, was eben dass wichtigste ist bei ihnen.

  6. #16
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    29.05.2005
    Beiträge
    1.018
    Zitat Zitat von Superhirn
    kurz und bündig.
    Ob das Geht?
    Kleiner Versuch:

    Code:
    Register:
    ADMUX
      Bit 7: REFS1
      Bit 6: REFS0
      Bit 5: ADLAR
      Bit 4: -
      Bit 3: MUX3
      Bit 2: MUX2
      Bit 1: MUX1
      Bit 0: MUX0
    
    REFS-Bit-Kombinationen wählt die Referenzspannung
    (Gut im Asuro ist AVCC)
     REFS1 REFS0
       0     0       AREF
       0     1       AVCC
       1     0       Nicht erlaubt
       1     1       Interne 2.5V Referenz
    
    ADLAR-Bedeutung
       0   ADC-Ergebniss in den Registern ADCL und ADCH steht so:
            ADCH: Bits 1 und 0: Höchste Bits der Wandlung
            ADCL: Bits 7 bis 0: Die niedriegen Bits der Wandlung
       1   In den Registern ADCL und ADCH steht das Ergebniss nun so:
            ADCH: Bits 7 bis 0: Die höchsten 8 Bit vom Ergeniss
            ADCL: Bits 7 und 6: Die beiden niedrigsten Ergebnissbits
    
    MUX-Bits
     0000  wählt ADC-Kanal 0
     0001  wählt ADC-Kanal 1
     0010  wählt ADC-Kanal 2
     0011  wählt ADC-Kanal 3
     0100  wählt ADC-Kanal 4
     0101  wählt ADC-Kanal 5
     0110  wählt ADC-Kanal 6
     0111  wählt ADC-Kanal 7
     1000  
     1001  
     1010  
     1011  
     1100  
     1101  
     1110  1.23 Volt wird gemessen
     1111  0 Volt werden gemessen
    
    
    Register:
    ADCSRA
      Bit 7: ADEN
      Bit 6: ADSC
      Bit 5: ADFR
      Bit 4: ADIF
      Bit 3: ADIE
      Bit 2: ADPS2
      Bit 1: ADPS1
      Bit 0: ADPS0
    
    ADEN: 1 schaltet den ADC-Wandler erst ein
    ADSC: Eine 1 startet die Wandlung, oder das 'freerunning'
    ADFR: 1 erlaubt das 'freerunning'
    ADIF:  Wird von der CPU auf 1 gesetzt, wenn eine Wandlung fertig ist
    ADIE: 1 erlaubt der CPU eine Interrupt-Funktion aufzurufen
    ADPS2 bis ADPS0: Wählt einen Vorteiler, der die Wandlergeschwindigkeit
              und damit allerdings wohl auch die Genauigkeit steuert.
              Großer Vorteilerwert ergibt eine langsamere Wandlung. Damit wird
              dann aber auch das laufende Programm nicht so häufig unter-
              brochen und somit läuft es 'etwas' schneller. 
    ADPS2 ADPS1 ADPS0
       0    0    0    Vorteilteiler  2
       0    0    1    Vorteilteiler  2 (Ja, nochmal 2)
       0    1    0    Vorteilteiler  4
       0    1    1    Vorteilteiler  8
       1    0    0    Vorteilteiler  16
       1    0    1    Vorteilteiler  32
       1    1    0    Vorteilteiler  64
       1    1    1    Vorteilteiler  128
    Du solltest also immer erst in das Register ADMUX schreiben.
    Dann in das ADCSRA-Register schreiben.
    z.B.:

    ADMUX = 0b01000000; /* AVCC-Referenz; Kanal 0 */
    ADCSRA = 0b11101111 /* Enable; ADC-Start; freerunning; Interrupt enable; Vorteiler 128

    Um den Interrupt überhaupt nutzen zu können benötigst du eine Funktion.
    z.B.
    Code:
    volatile   unsigned   int   adc_wert;
    
    SIGNAL (SIG_ADC)
    {
       adc_wert = ADCL + (ADCH << 8);
    }
    Damit liefert dir der 'freerunning' ADC-Wandler nun automatisch immer den gemessenen Wert vom Kanal 0 in die Variable adc_wert.
    Diesen Wert kannst du in deinem Hauptprogramm immer lesen.

    P.S.: Kürzer schaffe ich leider nicht
    Lieber Asuro programieren als arbeiten gehen.

  7. #17
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    19.03.2005
    Ort
    Villach
    Alter
    32
    Beiträge
    995
    Danke. Kürzer gehts sicher nicht. jetzt weiß ich alles was ich wissen muss. (derzeit)

  8. #18
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    1. Das ADC-Register sollte unbedingt als 16-Bit-Wert gelesen werden, damit der Zugriff in der richtigen Reihenfolge gemacht wird.
    2. ausserdem ist der Wert darin unsigned.
    3. das Lesen muss atomar erfolgen, da sonst während des Auslesens ein ADC-IRQ auftreten kann, und man dann einen korrupten Wert liest (passiert zwar selten, aber es passiert)

    Code:
    #include <avr/io.h>
    #include <avr/signal.h>
    #include <avr/interrupt.h>
    
    uint16_t volatile  adc_wert;
    
    SIGNAL (SIG_ADC)
    {
       adc_wert = ADC;
    } 
    
    // Lesen:
    ...
       uint16_t wert;
       uint8_t sreg;
       ...
       sreg = SREG;
       cli();
       wert = adc_wert;
       SREG = sreg;   
       ...
    Disclaimer: none. Sue me.

  9. #19
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    19.03.2005
    Ort
    Villach
    Alter
    32
    Beiträge
    995
    Muss das so kompliziert gemacht werden wie es Sprinter sagte? Es reicht ja dass man die register setzt, den wert evt über interrupt ausließt und sofort in eine variable schreibt und dann im normalen programm weitergeht. Oder?

  10. #20
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    Es kann natürlich auch einfacher gemacht werden, wenn er Code nicht korrekt zu sein braucht.
    Disclaimer: none. Sue me.

Seite 2 von 3 ErsteErste 123 LetzteLetzte

Berechtigungen

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

Solar Speicher und Akkus Tests