Difference between revisions of "AVR Embedded Tutorial - Analog Read/de"
m (Fixed template loop; added language category) |
|||
(7 intermediate revisions by one other user not shown) | |||
Line 1: | Line 1: | ||
− | {{ | + | {{LanguageBar}} |
− | |||
=Analog Read= | =Analog Read= | ||
==Vorwort== | ==Vorwort== | ||
+ | |||
Dieser Code ist für einen Atmega328/Arduino mit 16MHz. | Dieser Code ist für einen Atmega328/Arduino mit 16MHz. | ||
+ | |||
Wie man die UART ansteuert, steht hier: | Wie man die UART ansteuert, steht hier: | ||
+ | |||
* [[AVR Embedded Tutorial - UART/de|UART]] ''UARTInit'' und ''UARTSendString(...'' | * [[AVR Embedded Tutorial - UART/de|UART]] ''UARTInit'' und ''UARTSendString(...'' | ||
+ | |||
+ | Der ATmega328 kann mit 10Bit Genauigkeit messen, somit wird ein Wert zwischen 0..1023 ausgegeben. | ||
==Polling-verfahren == | ==Polling-verfahren == | ||
===ADC Initialisieren=== | ===ADC Initialisieren=== | ||
+ | |||
Analoges Einlesen konfigurieren. | Analoges Einlesen konfigurieren. | ||
Als Referenzspannung wird AVcc genommen, dies ist der einfachste Weg. Dies mus an '''ADMUX''' übergeben werden. | Als Referenzspannung wird AVcc genommen, dies ist der einfachste Weg. Dies mus an '''ADMUX''' übergeben werden. | ||
Folgende Referenzspannungen kann man mit ADMUX konfigurieren: | Folgende Referenzspannungen kann man mit ADMUX konfigurieren: | ||
+ | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
Line 33: | Line 39: | ||
procedure ADC_Init; | procedure ADC_Init; | ||
begin | begin | ||
− | ADMUX := (1 shl REFS); // AVcc als Referenz. | + | ADMUX := (1 shl REFS); // AVcc als Referenz. |
− | ADCSRA :=(1 shl ADEN) or // Wandler einschalten. | + | ADCSRA := (1 shl ADEN) or // Wandler einschalten. |
− | %111; | + | %111; // Teiler 128. |
end; | end; | ||
</syntaxhighlight> | </syntaxhighlight> | ||
===Auslesen=== | ===Auslesen=== | ||
+ | |||
Der Ablauf bei Messen ist folgendermassen. | Der Ablauf bei Messen ist folgendermassen. | ||
+ | |||
* Port angeben. | * Port angeben. | ||
* Warten bis Messung ferig. | * Warten bis Messung ferig. | ||
* Messwert auslesen. | * 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. | 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. | ||
Line 57: | Line 66: | ||
end; | end; | ||
</syntaxhighlight> | </syntaxhighlight> | ||
+ | |||
Wen man immer vom gleiche Port einliest, muss man die '''ADMUX'''-Zeile nur einmal aufrufen. | 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. | Auch kann man dann das Messen einleiten direkt nach der '''while''-Schleife machen. Die spart ein paar Takte. | ||
===Über UART ausgeben=== | ===Über UART ausgeben=== | ||
+ | |||
Variablen für Zwischenspeicher für die Messdaten. | Variablen für Zwischenspeicher für die Messdaten. | ||
+ | |||
<syntaxhighlight lang="pascal"> | <syntaxhighlight lang="pascal"> | ||
var | var | ||
Line 67: | Line 79: | ||
s: string[10]; | s: string[10]; | ||
</syntaxhighlight> | </syntaxhighlight> | ||
+ | |||
In einer Endlosschelife werden dann die Messdaten ausgegeben. | In einer Endlosschelife werden dann die Messdaten ausgegeben. | ||
+ | |||
<syntaxhighlight lang="pascal"> | <syntaxhighlight lang="pascal"> | ||
begin | begin | ||
Line 91: | Line 105: | ||
==Interrupt gesteuert== | ==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. | ||
+ | |||
+ | <syntaxhighlight lang="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; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ===Messwert im Interrupt ausgeben=== | ||
+ | |||
+ | <syntaxhighlight lang="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; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ===Hauptprogramm=== | ||
+ | |||
+ | Da das Messen Interruptgesteuert ist, bleibt die Hauptschleife leer. | ||
+ | Wichtig, das man mit '''sei''' die Interrupts einschaltet. | ||
+ | |||
+ | <syntaxhighlight lang="pascal"> | ||
+ | begin | ||
+ | |||
+ | // UART inizialisieren | ||
+ | UARTInit; | ||
+ | |||
+ | // ADC | ||
+ | ADC_Init; | ||
+ | |||
+ | // Interrupt erlauben | ||
+ | asm Sei end; | ||
+ | |||
+ | // Hauptschleife | ||
+ | repeat | ||
+ | // Mache Irgendwas | ||
+ | until 1 = 2; | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | == Siehe auch == | ||
+ | |||
+ | * Übersichtseite [[AVR Embedded Tutorial/de|AVR Embedded Tutorial]] | ||
+ | Autor: [[User:Mathias|Mathias]] | ||
− | [[Category:AVR]] {{AutoCategory}} | + | [[Category:Embedded]] |
+ | [[Category:AVR]] | ||
+ | [[Category:Arduino]] | ||
+ | {{AutoCategory}} |
Latest revision as of 11:43, 22 January 2020
│ 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