Sign in Join
Wiki copytemporary

Revision 1 of 1, by Trev on 1-22-2020. The page as it is now.

AVR Embedded Tutorial - Analog Read/de

Analog Read

Vorwort

Dieser Code ist für einen Atmega328/Arduino mit 16MHz.

Wie man die UART ansteuert, steht hier:

Der ATmega328 kann mit 10Bit Genauigkeit messen, somit wird ein Wert zwischen 0..1023 ausgegeben.

Polling-verfahren

ADC Initialisieren

Analoges Einlesen konfigurieren. Als Referenzspannung wird AVcc genommen, dies ist der einfachste Weg. Dies mus an ADMUX übergeben werden.

Folgende Referenzspannungen kann man mit ADMUX konfigurieren:

Bit 7 Bit 6 Beschreibung
0 0 Pin AREF
0 1 von AVcc
1 0 -
1 1 2.56V

Mit ADCSRA wird der Wandler gestartet.

pascal
  procedure ADC_Init;
  begin
    ADMUX  := (1 shl REFS);   // AVcc als Referenz.
    ADCSRA := (1 shl ADEN) or // Wandler einschalten.
    %111;                     // Teiler 128.
  end;

Auslesen

Der Ablauf bei Messen ist folgendermassen.

Bei ADMUX muss man die Referenzspannung nochmals angeben, weil es das Register mit Referenz teilt, man könnte auch eine or-Verknüpfung mit ADMUX machen.

pascal
  function ADC_Read(Port: byte): integer;
  begin
    ADMUX := (1 shl REFS) or (Port and $0F);      // Port angeben.
    ADCSRA := ADCSRA or (1 shl ADSC);             // Messen einleiten.
    while (ADCSRA and (1 shl ADSC)) <> 0 do begin // Warten bis gemessen.
    end;

    Result := ADC;                                // Messwert auslesen. 
  end;

Wen man immer vom gleiche Port einliest, muss man die ADMUX-Zeile nur einmal aufrufen. Auch kann man dann das Messen einleiten direkt nach der 'while-Schleife machen. Die spart ein paar Takte.

Über UART ausgeben

Variablen für Zwischenspeicher für die Messdaten.

pascal
var
  Data: integer;
  s: string[10];

In einer Endlosschelife werden dann die Messdaten ausgegeben.

pascal
begin

  // UART inizialisieren
  UARTInit;

  // ADC inizialisieren
  ADC_Init;

  // Interrupt erlauben
  asm Sei END;

  // Messwerte ausgeben.
  repeat
    Data := ADC_Read(0);
    str(Data: 6, s);
    UARTSendString(s);
  until 1 = 2;
end.

Interrupt gesteuert

Bei dem Interruptgesteuerten Verfahren, hat man den Vorteil, das man nicht warten muss, bis die Messung fertig ist, somit hat man Zeit für Anderes.

Inizialisieren

Der Unterschied:

pascal
  procedure ADC_Init;
  const
    Port = 0;
  begin
    ADMUX := (1 shl REFS) or (Port and $0F);
    ADCSRA := %111 or (1 shl ADEN) or (1 shl ADSC) or (1 shl ADIE);
  end;

Messwert im Interrupt ausgeben

pascal
  procedure ADC_Ready public Name 'ADC_ISR'; interrupt;
  var
    Data: integer;
    s: string[10];
  begin
    Data := ADC;
    ADCSRA := ADCSRA or (1 shl ADSC);
    str(Data: 6, s);
    UARTSendString(s);
  end;

Hauptprogramm

Da das Messen Interruptgesteuert ist, bleibt die Hauptschleife leer. Wichtig, das man mit sei die Interrupts einschaltet.

pascal
begin

  // UART inizialisieren
  UARTInit;

  // ADC
  ADC_Init;

  // Interrupt erlauben
  asm Sei END;

  // Hauptschleife
  repeat
    // Mache Irgendwas
  until 1 = 2;
end.

Siehe auch

Autor: Mathias


From the Free Pascal wiki, page "AVR Embedded Tutorial - Analog Read/de", as it stood on 2020-01-22 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's Licensing page. If you have concerns about this material, message the admin.