AVR Embedded Tutorial - Analog Read/de
│ Deutsch (de) │ English (en) │
Analog Read
Vorwort
Dieser Code ist für einen Atmega328/Arduino mit 16MHz.
Wie man die UART ansteuert, steht hier:
- UART UARTInit und UARTSendString(...
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.
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.
- Port angeben.
- Warten bis Messung ferig.
- Messwert auslesen.
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.
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.
var
Data: integer;
s: string[10];
In einer Endlosschelife werden dann die Messdaten ausgegeben.
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:
- Bei ADMUX gibt man am Anfang schon den Eingangs-Port an.
- Bei ADCSRA muss man mit ADSC die erste Messung gestartet werde.
- Mit ADIE teilt man mit das die Wandlung Interrupt gesteuert ist.
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
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.
begin
// UART inizialisieren
UARTInit;
// ADC
ADC_Init;
// Interrupt erlauben
asm Sei end;
// Hauptschleife
repeat
// Mache Irgendwas
until 1 = 2;
end.
Siehe auch
- Übersichtseite AVR Embedded Tutorial
Autor: Mathias