Sign in Join
Wiki copytemporary

AVR Embedded Tutorial - UART/de: what changed

Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
1+## Contents
2+
3+ * 1 UART Polling
4+ * 1.1 ATmega328p (Arduino uno/nano)
5+ * 1.1.1 Konstanten für Inizialisierung
6+ * 1.1.2 Inizialisieren
7+ * 1.1.3 Zeichen empfangen
8+ * 1.1.4 Zeichen senden
9+ * 1.1.5 String senden
10+ * 1.1.6 Hauptschleife
11+ * 1.2 ATtiny2313
12+ * 2 Interrupt
13+ * 2.1 Empfangspuffer
14+ * 2.1.1 Deklaration
15+ * 2.1.2 Inzialisieren
16+ * 2.1.3 Interrupt
17+ * 2.1.4 Hauptschleife
18+ * 2.2 Sendepuffer
19+ * 2.2.1 Deklaration
20+ * 2.2.2 Inzialisieren
21+ * 2.2.3 Interrupt
22+ * 2.2.4 String senden
23+ * 2.2.5 Hauptschleife
24+ * 3 Software - UART / UART - Emulation
25+ * 3.1 Konstanten
26+ * 3.2 Zeichen senden
27+ * 3.3 Zeichen empfangen
28+ * 4 Siehe auch
29+
130# UART Polling
231
332## ATmega328p (Arduino uno/nano)
433
5-Für die serielle Ausgabe wird ein Terminal mit folgenden Einstellungen gebraucht:
6-
7-| | |
8-|-----------|------|
9-| Baud Rate | 9600 |
10-| Bits | 8 |
11-| Stopbits | 1 |
12-| Parity | none |
34+Für die serielle Ausgabe wird ein Terminal mit folgenden Einstellungen gebraucht:
1335
14-Beim Betätigen von <span class="kbd">Space</span> im Terminal-Programm, sollte ein "Hello World !" zurück kommen.
36+Baud Rate | 9600
37+---|---
38+Bits | 8
39+Stopbits | 1
40+Parity | none
41+
42+Beim Betätigen von `Space` im Terminal-Programm, sollte ein "Hello World !" zurück kommen.
1543
1644### Konstanten für Inizialisierung
17-
18-``` pascal
45+```
1946const
20- CPU_Clock = 16000000; // Taktfrequenz Arduino, default 16MHz.
21- Baud = 9600; // Baudrate
22- Teiler = CPU_Clock div (16 * Baud) - 1;
47+ CPU_Clock = 16000000; // Taktfrequenz Arduino, default 16MHz.
48+ Baud = 9600; // Baudrate
49+ Teiler = CPU_Clock div (16 * Baud) - 1;
2350```
2451
25-**Hinweis:** Wen den der CPU-Clock zu klein ist in die Baudrate zu hoch, gibt es Übertragungsfehler. Beispiel: Clock **1MHz**, Baud **9600** geht nicht. Aber **1MHz** und Baud **1200** gehen.
52+**Hinweis:** Wen den der CPU-Clock zu klein ist in die Baudrate zu hoch, gibt es Übertragungsfehler. Beispiel: Clock **1MHz** , Baud **9600** geht nicht. Aber **1MHz** und Baud **1200** gehen.
2653
2754### Inizialisieren
2855
29-Die UART-Schnittstelle konfigurierieren.
30-
31-``` pascal
32- procedure UARTInit;
33- begin
34- UBRR0 := Teiler; // Baud
35-
36- UCSR0A := 0 // Normale Geschwindigkeit
37- UCSR0B := (1 shl TXEN0) or (1 shl RXEN0); // Empfangen und Senden
38- UCSR0C := (%011 shl UCSZ0); // 8-Bit Übertragung, 1 Stop-Bits.
39- end;
56+Die UART-Schnittstelle konfigurierieren.
4057```
58+procedure UARTInit;
59+ begin
60+ UBRR0 := Teiler; // Baud
61+
62+ UCSR0A := 0 // Normale Geschwindigkeit
63+ UCSR0B := (1 shl TXEN0) or (1 shl RXEN0); // Empfangen und Senden
64+ UCSR0C := (%011 shl UCSZ0); // 8-Bit Übertragung, 1 Stop-Bits.
65+ end;
66+```
4167
4268### Zeichen empfangen
43-
44-``` pascal
45- function UARTReadChar: char;
46- begin
47- while UCSR0A and (1 shl RXC0) = 0 do; // Warten, bis Zeichen ankommt.
48- Result := char(UDR0); // Zeichen einlesen.
49- end;
5069```
70+function UARTReadChar: char;
71+ begin
72+ while UCSR0A and (1 shl RXC0) = 0 do; // Warten, bis Zeichen ankommt.
73+ Result := char(UDR0); // Zeichen einlesen.
74+ end;
75+```
5176
5277### Zeichen senden
53-
54-``` pascal
55- procedure UARTSendChar(c: char);
56- begin
57- while UCSR0A and (1 shl UDRE0) = 0 do; // Warten, bis letztes Zeichen gesendet.
58- UDR0 := byte(c); // Zeichen senden.
59- end;
6078```
79+procedure UARTSendChar(c: char);
80+ begin
81+ while UCSR0A and (1 shl UDRE0) = 0 do; // Warten, bis letztes Zeichen gesendet.
82+ UDR0 := byte(c); // Zeichen senden.
83+ end;
84+```
6185
6286### String senden
63-
64-``` pascal
65- procedure UARTSendString(s: ShortString);
66- var
67- i: integer;
68- begin
69- for i := 1 to length(s) do begin
70- UARTSendChar(s[i]); // Zeichen einzeln senden.
71- end;
72- end;
7387```
88+procedure UARTSendString(s: ShortString);
89+ var
90+ i: integer;
91+ begin
92+ for i := 1 to length(s) do begin
93+ UARTSendChar(s[i]); // Zeichen einzeln senden.
94+ end;
95+ end;
96+```
7497
7598### Hauptschleife
7699
77-Hier wird gewartet, bis <span class="kbd">Space</span> ankommt, anschliessend wir "Hello World !" gesendet.
78-
79-``` pascal
100+Hier wird gewartet, bis `Space` ankommt, anschliessend wir "Hello World !" gesendet.
101+```
80102program Project1;
81-begin
82- UARTInit;
83- repeat
84- if UARTReadChar = #32 then begin // #32 = space
85- UARTSendString('Hello World !'#13#10);
86- end;
87- until 1 = 2;
88-end.
103+ begin
104+ UARTInit;
105+ repeat
106+ if UARTReadChar = #32 then begin // #32 = space
107+ UARTSendString('Hello World !'#13#10);
108+ end;
109+ until 1 = 2;
110+ end.
89111```
90112
91113## ATtiny2313
92114
93-Beim ATtiny2313 haben die Register eine andere Bezeichnung als beim ATmega328p.
94-
95-- Die **0** entfällt in der Bezeichnung.
96-- **UBRR0** muss man in **UBRRH** und **UBRRL** zerlegen.
115+Beim ATtiny2313 haben die Register eine andere Bezeichnung als beim ATmega328p.
97116
98-Das sieht dann so aus:
117+ * Die **0** entfällt in der Bezeichnung.
118+ * **UBRR0** muss man in **UBRRH** und **UBRRL** zerlegen.
99119
100-``` pascal
120+Das sieht dann so aus:
121+```
101122UBRRH := Teiler shr 8;
102-UBRRL := Byte(Teiler);
103-
104-UCSRB := (1 shl TXEN) or (1 shl RXEN);
105-UCSRC := (%011 shl UCSZ);
123+ UBRRL := Byte(Teiler);
124+
125+ UCSRB := (1 shl TXEN) or (1 shl RXEN);
126+ UCSRC := (%011 shl UCSZ);
106127```
107128
108-(Der Code wurde nicht getestet)
129+(Der Code wurde nicht getestet)
109130
110131# Interrupt
111132
112-Beim Polling kann es passieren, das Zeichen verschluckt werden, dies passiert, wen ein Zeichen ankommt und man dieses nicht abholt. Aus diesem Grund empfiehlt es sich, den Zeichenempfang Interrupt gesteuert zum machen.
133+Beim Polling kann es passieren, das Zeichen verschluckt werden, dies passiert, wen ein Zeichen ankommt und man dieses nicht abholt. Aus diesem Grund empfiehlt es sich, den Zeichenempfang Interrupt gesteuert zum machen.
113134
114-Bei höheren Baudraten, ist dies zwingend.
135+Bei höheren Baudraten, ist dies zwingend.
115136
116-Es wir ein einfacher Ringpuffer mit 16 Zeichen verwendet.
137+Es wir ein einfacher Ringpuffer mit 16 Zeichen verwendet.
117138
118-Die Beispiele zeigen dies anhand eines ATmega328p (Arduino uno/nano).
139+Die Beispiele zeigen dies anhand eines ATmega328p (Arduino uno/nano).
119140
120141## Empfangspuffer
121142
122143### Deklaration
123144
124-Zeichenbuffer deklarieren, hier wir ein Puffer von 16 Zeichen angelegt.
125-
126-``` pascal
145+Zeichenbuffer deklarieren, hier wir ein Puffer von 16 Zeichen angelegt.
146+```
127147const
128- Crxlen = 16; // Puffergrösse
129-var
130- RXBuf: array[0..Crxlen - 1] of byte;
131- RXread: byte = 0;
132- RXwrite: byte = 0;
148+ Crxlen = 16; // Puffergrösse
149+ var
150+ RXBuf: array[0..Crxlen - 1] of byte;
151+ RXread: byte = 0;
152+ RXwrite: byte = 0;
133153```
134154
135155### Inzialisieren
136156
137-Dies ist ähnlich des Polling verfahren, der Unterschied, man teilt mit **RXCIE0** mit, das beim Zeichenempfang ein Interrupt ausgelöst wird.
138-
139-``` pascal
140- procedure UARTInit;
141- begin
142- UBRR0 := teiler;
143-
144- UCSR0A := (0 shl U2X0);
145- UCSR0B := (1 shl TXEN0) or (1 shl RXEN0) or (1 shl RXCIE0);
146- UCSR0C := %011 shl UCSZ0;
147- end;
157+Dies ist ähnlich des Polling verfahren, der Unterschied, man teilt mit **RXCIE0** mit, das beim Zeichenempfang ein Interrupt ausgelöst wird.
148158```
159+procedure UARTInit;
160+ begin
161+ UBRR0 := teiler;
162+
163+ UCSR0A := (0 shl U2X0);
164+ UCSR0B := (1 shl TXEN0) or (1 shl RXEN0) or (1 shl RXCIE0);
165+ UCSR0C := %011 shl UCSZ0;
166+ end;
167+```
149168
150169### Interrupt
151170
152-Bei auslösen des Interrupts, wird das Zeichen vom UART in Zeichenbuffer kopiert.
153-
154-``` pascal
155- procedure UART_RX_Empfang; public Name 'USART__RX_ISR'; interrupt;
156- var
157- b: byte;
158- begin
159-
160- // Zeichen einlesen
161- b := UDR0;
162-
163- // Zeichen in Puffer schreiben.
164- if b <> 0 then begin
165- RxBuf[rxwrite] := b;
166- Inc(RXwrite);
167- if RXwrite >= Crxlen then begin
168- RXwrite := 0;
171+Bei auslösen des Interrupts, wird das Zeichen vom UART in Zeichenbuffer kopiert.
172+```
173+procedure UART_RX_Empfang; public Name 'USART__RX_ISR'; interrupt;
174+ var
175+ b: byte;
176+ begin
177+
178+ // Zeichen einlesen
179+ b := UDR0;
180+
181+ // Zeichen in Puffer schreiben.
182+ if b <> 0 then begin
183+ RxBuf[rxwrite] := b;
184+ Inc(RXwrite);
185+ if RXwrite >= Crxlen then begin
186+ RXwrite := 0;
187+ end;
188+ end;
169189 end;
170- end;
171- end;
172190```
173191
174192### Hauptschleife
175193
176-In der Hauptschleife wird geprüft, ob sich etwas im Empfangspuffer, wen ja, wird ein Zeichen davon ausgelesen. In diesem Beispiel werden, die empfangenen Zeichen in Grossbuchstaben umgewandelt und anschiessend wieder ausgegeben.
177-
178-``` pascal
194+In der Hauptschleife wird geprüft, ob sich etwas im Empfangspuffer, wen ja, wird ein Zeichen davon ausgelesen. In diesem Beispiel werden, die empfangenen Zeichen in Grossbuchstaben umgewandelt und anschiessend wieder ausgegeben.
195+```
179196begin
180- // UART inizialisieren, die Interrupt gesteuert ist.
181- UARTInit;
182-
183- // Interrupt aktivieren.
184- asm sei end;
185-
186- // Hauptschleife.
187- repeat
188-
189- // Ist ein Zeichen im Puffer ?
190- while RXwrite <> rxread do begin
191-
192- // Interrupt sperren.
193- asm cli end;
194-
195- // Zeichen aus Puffer lesen
196- ch := RXBuf[rxread];
197- Inc(RXread);
198- if RXread >= Crxlen then begin
199- RXread := 0;
200- end;
201-
202- // Interrupt aktivieren.
197+ // UART inizialisieren, die Interrupt gesteuert ist.
198+ UARTInit;
199+
200+ // Interrupt aktivieren.
203201 asm sei end;
204-
205- // Wen kleiner Buchstaben, diesen in einen grossen umwandeln.
206- if ch in [$61..$7A] then begin
207- Dec(ch, 32);
208- end;
209-
210- // Zeichen ausgeben.
211- UARTSendChar(char(ch));
212- end;
213- until 1 = 2;
214-end.
202+
203+ // Hauptschleife.
204+ repeat
205+
206+ // Ist ein Zeichen im Puffer ?
207+ while RXwrite <> rxread do begin
208+
209+ // Interrupt sperren.
210+ asm cli end;
211+
212+ // Zeichen aus Puffer lesen
213+ ch := RXBuf[rxread];
214+ Inc(RXread);
215+ if RXread >= Crxlen then begin
216+ RXread := 0;
217+ end;
218+
219+ // Interrupt aktivieren.
220+ asm sei end;
221+
222+ // Wen kleiner Buchstaben, diesen in einen grossen umwandeln.
223+ if ch in [$61..$7A] then begin
224+ Dec(ch, 32);
225+ end;
226+
227+ // Zeichen ausgeben.
228+ UARTSendChar(char(ch));
229+ end;
230+ until 1 = 2;
231+ end.
215232```
216233
217234## Sendepuffer
218235
219236### Deklaration
220237
221-Sendepuffer deklarieren, hier wir ein Puffer von 16 Zeichen angelegt.
222-
223-``` pascal
238+Sendepuffer deklarieren, hier wir ein Puffer von 16 Zeichen angelegt.
239+```
224240const
225- CTXlen = 16; // Puffergrösse
226-var
227- TXBuf: array[0..CTXlen - 1] of byte;
228- TXread: byte = 0;
229- TXwrite: byte = 0;
241+ CTXlen = 16; // Puffergrösse
242+ var
243+ TXBuf: array[0..CTXlen - 1] of byte;
244+ TXread: byte = 0;
245+ TXwrite: byte = 0;
230246```
231247
232248### Inzialisieren
233249
234-Dies ist ähnlich des Empfangsbuffer verfahren, wichtig dabei, die Interrupt-Funktion darf noch **nicht** aktiviert werden, da es am Anfang noch nichts zu senden gibt.
235-
236-``` pascal
237- procedure UARTInit;
238- begin
239- UBRR0 := teiler;
240-
241- UCSR0A := (0 shl U2X0);
242- UCSR0B := (1 shl TXEN0) or (1 shl RXEN0);
243- UCSR0C := %011 shl UCSZ0;
244- end;
250+Dies ist ähnlich des Empfangsbuffer verfahren, wichtig dabei, die Interrupt-Funktion darf noch **nicht** aktiviert werden, da es am Anfang noch nichts zu senden gibt.
245251```
252+procedure UARTInit;
253+ begin
254+ UBRR0 := teiler;
255+
256+ UCSR0A := (0 shl U2X0);
257+ UCSR0B := (1 shl TXEN0) or (1 shl RXEN0);
258+ UCSR0C := %011 shl UCSZ0;
259+ end;
260+```
246261
247262### Interrupt
248263
249-Der Interrupts, wird ausgelöst, sobald das Zeichen im UART gesendet wurde.
250-
251-Sobald der Ringpuffer leer ist, wird die Interrupt-Funktion wider deaktiviert.
264+Der Interrupts, wird ausgelöst, sobald das Zeichen im UART gesendet wurde.
252265
253-Die Abfrage von **UDRE0** wird hier nicht gebraucht, da der Interrupt nur ausgelöst wird, wen der Puffer leer ist.
266+Sobald der Ringpuffer leer ist, wird die Interrupt-Funktion wider deaktiviert.
254267
255-``` pascal
256- procedure UART_UDRE_Senden; public Name 'USART__UDRE_ISR'; interrupt;
257- begin
258- // Zeichen Senden.
259- UDR0 := TXBuf[TXread];
268+Die Abfrage von **UDRE0** wird hier nicht gebraucht, da der Interrupt nur ausgelöst wird, wen der Puffer leer ist.
269+```
270+procedure UART_UDRE_Senden; public Name 'USART__UDRE_ISR'; interrupt;
271+ begin
272+ // Zeichen Senden.
273+ UDR0 := TXBuf[TXread];
274+
275+ // Ringpuffer verschieben.
276+ Inc(TXread);
260277
261- // Ringpuffer verschieben.
262- Inc(TXread);
263-
264- // Wen Zeiger am Ende, wieder von vorn beginnen.
265- if TXread >= CTXlen then begin
266- TXread := 0;
267- end;
268-
269- // Ist Ringpuffer leer, kein Interrupt mehr nötig-
270- if TXread = TXwrite then begin
271- UCSR0B := UCSR0B and not (1 shl UDRIE0);
272- end;
273- end;
278+ // Wen Zeiger am Ende, wieder von vorn beginnen.
279+ if TXread >= CTXlen then begin
280+ TXread := 0;
281+ end;
282+
283+ // Ist Ringpuffer leer, kein Interrupt mehr nötig-
284+ if TXread = TXwrite then begin
285+ UCSR0B := UCSR0B and not (1 shl UDRIE0);
286+ end;
287+ end;
274288```
275289
276290### String senden
277291
278-Sobald sich etwas im Rindpuffer befindet, wird der Interrupt weder aktiviert.
279-
280-``` pascal
281- procedure UARTSendString(s: ShortString);
282- var
283- i: byte;
284- begin
285-
286- // Ringpuffer mit Daten befüllen,
287- for i := 1 to Length(s) do begin
288- TXBuf[TXwrite] := byte(s[i]);
289- Inc(TXwrite);
290- if TXwrite >= CTXlen then begin
291- TXwrite := 0;
292+Sobald sich etwas im Rindpuffer befindet, wird der Interrupt weder aktiviert.
293+```
294+procedure UARTSendString(s: ShortString);
295+ var
296+ i: byte;
297+ begin
298+
299+ // Ringpuffer mit Daten befüllen,
300+ for i := 1 to Length(s) do begin
301+ TXBuf[TXwrite] := byte(s[i]);
302+ Inc(TXwrite);
303+ if TXwrite >= CTXlen then begin
304+ TXwrite := 0;
305+ end;
306+ end;
307+
308+ // Sende Interrupt aktivieren.
309+ UCSR0B := UCSR0B or (1 shl UDRIE0);
292310 end;
293- end;
294-
295- // Sende Interrupt aktivieren.
296- UCSR0B := UCSR0B or (1 shl UDRIE0);
297- end;
298311```
299312
300313### Hauptschleife
301314
302-Der String wird extra ein wenig koatisch ausgegeben, dies sollte zeigen, das die Ausgabe im Hintergrund abläuft. Im Beispiel, blinkt sogar eine LED während der Ausgabe.
303-
304-``` pascal
315+Der String wird extra ein wenig koatisch ausgegeben, dies sollte zeigen, das die Ausgabe im Hintergrund abläuft. Im Beispiel, blinkt sogar eine LED während der Ausgabe.
316+```
305317var
306- z: byte;
307- s: ShortString;
308-begin
309- DDRB := DDRB or (1 shl 5);
310- // UART inizialisieren, die Interrupt gesteuert.
311- UARTInit;
312-
313- // Interrupt aktivieren.
314- asm Sei end;
315-
316- // Hauptschleife.
317- repeat
318- UARTSendString('Hello World');
319- UARTSendString(' !'#13#10);
320-
321- PORTB := PORTB or (1 shl 5);
322- mysleep(sl);
323-
324- Str(z: 3, s);
325- UARTSendString(s + '. ');
326- Inc(z);
327-
328- PORTB := PORTB and not (1 shl 5);
329- mysleep(sl);
330-
331- until 1 = 2;
332-end.
318+ z: byte;
319+ s: ShortString;
320+ begin
321+ DDRB := DDRB or (1 shl 5);
322+ // UART inizialisieren, die Interrupt gesteuert.
323+ UARTInit;
324+
325+ // Interrupt aktivieren.
326+ asm Sei end;
327+
328+ // Hauptschleife.
329+ repeat
330+ UARTSendString('Hello World');
331+ UARTSendString(' !'#13#10);
332+
333+ PORTB := PORTB or (1 shl 5);
334+ mysleep(sl);
335+
336+ Str(z: 3, s);
337+ UARTSendString(s + '. ');
338+ Inc(z);
339+
340+ PORTB := PORTB and not (1 shl 5);
341+ mysleep(sl);
342+
343+ until 1 = 2;
344+ end.
333345```
334346
335347# Software - UART / UART - Emulation
336348
337-Es ist auch möglich eine UART-Schnittstelle per Software zu emulieren.
349+Es ist auch möglich eine UART-Schnittstelle per Software zu emulieren.
338350
339-Dies ist praktisch, wen man einen AVR hat, welcher keinen/zuwenig Hardware-UART hat.
351+Dies ist praktisch, wen man einen AVR hat, welcher keinen/zuwenig Hardware-UART hat.
340352
341-**Hinweis:** Dieser Code funktioniert nur mit **16MHz** CPU-Takt und **9600Baud**. Einfach **Baud** und **CPU_Clock** anzupassen reicht nicht, weil die Formel noch einen Fehler hat.
353+**Hinweis:** Dieser Code funktioniert nur mit **16MHz** CPU-Takt und **9600Baud**. Einfach **Baud** und **CPU_Clock** anzupassen reicht nicht, weil die Formel noch einen Fehler hat.
342354
343-**Wichtig:** Während der Übertragung, müssen Interrupts gesperrt werden.
355+**Wichtig:** Während der Übertragung, müssen Interrupts gesperrt werden.
344356
345-Gleichzeigtes lesen und schreiben funktioniert nicht, da kein Puffer vorhanden ist.
357+Gleichzeigtes lesen und schreiben funktioniert nicht, da kein Puffer vorhanden ist.
346358
347-Im Idealfall ist dies gut verwendbar, um Fehler auf ein UART-Terminal auszugeben.
359+Im Idealfall ist dies gut verwendbar, um Fehler auf ein UART-Terminal auszugeben.
348360
349361## Konstanten
350362
351-In diesem Beispiele werden die Pin 2 & 3 von PortD verwendet.
352-
353-``` pascal
363+In diesem Beispiele werden die Pin 2 & 3 von PortD verwendet.
364+```
354365const
355- CPU_Clock = 16000000; // Taktfrequenz Arduino, default 16MHz.
356- Baud = 9600; // Baudrate
357-
358- TXpin = (1 shl 3); // Pin 3 ( Empfangen )
359- RXpin = (1 shl 2); // Pin 2 ( Senden )
360-
361- SoftTeiler = CPU_Clock div (Baud * 22); // Bitzeitzähler
366+ CPU_Clock = 16000000; // Taktfrequenz Arduino, default 16MHz.
367+ Baud = 9600; // Baudrate
368+
369+ TXpin = (1 shl 3); // Pin 3 ( Empfangen )
370+ RXpin = (1 shl 2); // Pin 2 ( Senden )
371+
372+ SoftTeiler = CPU_Clock div (Baud * 22); // Bitzeitzähler
362373```
363374
364-Den Empfangs-Pin auf Input stellen.
365-
366-``` pascal
375+Den Empfangs-Pin auf Input stellen.
376+```
367377begin
368- DDRD := DDRD or TXpin;
369- ...
370- // Loop
371- ...
372-end.
378+ DDRD := DDRD or TXpin;
379+ ...
380+ // Loop
381+ ...
382+ end.
373383```
374384
375-**Hinweis:** Will man die gleichen Pins wie bei der Hardware-UART verwenden, muss beim Arduino der Pin **0**& **1** frei gegeben werden.
376-
377-``` pascal
385+**Hinweis:** Will man die gleichen Pins wie bei der Hardware-UART verwenden, muss beim Arduino der Pin **0** & **1** frei gegeben werden.
386+```
378387begin
379- UCSR0B := 0; // Blockierter Pin 0 & 1 frei geben
380- ...
381- // Loop
382- ...
383-end.
388+ UCSR0B := 0; // Blockierter Pin 0 & 1 frei geben
389+ ...
390+ // Loop
391+ ...
392+ end.
384393```
385394
386395## Zeichen senden
387-
388-``` pascal
389- procedure UARTSoftSendByte(c: byte);
390- var
391- i, Data: int16;
392- j: Int8;
393- begin
394- asm Cli end; // Interrupt sperren
395- Data := (c shl 1) or $FE00;
396- for j := 0 to 9 do begin // Bit ausgeben, inklusiv Stop-Bits.
397- if (Data and 1) = 1 then
398- PORTD := PORTD or TXpin // HIGH
399- else
400- PORTD := PORTD and not TXpin; // LOW
401- Data := Data shr 1;
402- for i := 0 to SoftTeiler do; // Ein Takt Pause
403- end;
404- asm Sei end; // Interrupt erlauben
405- end;
406396```
397+procedure UARTSoftSendByte(c: byte);
398+ var
399+ i, Data: int16;
400+ j: Int8;
401+ begin
402+ asm Cli end; // Interrupt sperren
403+ Data := (c shl 1) or $FE00;
404+ for j := 0 to 9 do begin // Bit ausgeben, inklusiv Stop-Bits.
405+ if (Data and 1) = 1 then
406+ PORTD := PORTD or TXpin // HIGH
407+ else
408+ PORTD := PORTD and not TXpin; // LOW
409+ Data := Data shr 1;
410+ for i := 0 to SoftTeiler do; // Ein Takt Pause
411+ end;
412+ asm Sei end; // Interrupt erlauben
413+ end;
414+```
407415
408416## Zeichen empfangen
409417
410-**Hinweis:** Wen kein Zeichen im Empfang kommt, hängt die Schleife im Endlosen.
411-
412-``` pascal
413- function UARTSoftReadByte: byte;
414- var
415- i: Int16;
416- j: Int8;
417- begin
418- asm Cli end; // Interrupt sperren
419- Result := 0;
420- while PIND and RXpin > 0 do; // Warten bis erste fallende Flanke
421- for i := 0 to SoftTeiler div 2 do; // Ein halber Takt Pause
422- for j := 0 to 7 do begin
423- for i := 0 to SoftTeiler do; // Ein Takt Pause
424- Result := Result shr 1;
425- if PIND and RXpin <> 0 then
426- Inc(Result, $80);
427- end;
428- for i := 0 to SoftTeiler; // Ein Takt Pause
429- asm Sei end; // Interrupt erlauben
430- end;
418+**Hinweis:** Wen kein Zeichen im Empfang kommt, hängt die Schleife im Endlosen.
431419```
420+function UARTSoftReadByte: byte;
421+ var
422+ i: Int16;
423+ j: Int8;
424+ begin
425+ asm Cli end; // Interrupt sperren
426+ Result := 0;
427+ while PIND and RXpin > 0 do; // Warten bis erste fallende Flanke
428+ for i := 0 to SoftTeiler div 2 do; // Ein halber Takt Pause
429+ for j := 0 to 7 do begin
430+ for i := 0 to SoftTeiler do; // Ein Takt Pause
431+ Result := Result shr 1;
432+ if PIND and RXpin <> 0 then
433+ Inc(Result, $80);
434+ end;
435+ for i := 0 to SoftTeiler; // Ein Takt Pause
436+ asm Sei end; // Interrupt erlauben
437+ end;
438+```
432439
440+
441+
433442# Siehe auch
434443
435-- Übersichtseite [[AVR Embedded Tutorial/de|AVR Embedded Tutorial]]
444+ * Übersichtseite [[AVR Embedded Tutorial/de|AVR Embedded Tutorial]]
436445
437-Autor: Mathias
446+Autor: [Mathias](</User:Mathias> "User:Mathias")
438447
439448---
440-*From the Free Pascal wiki, page "AVR Embedded Tutorial - UART/de", as it stood on 2022-01-06 after a change by VamLykTan, 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](/wiki-contact).*
441-Category: AVR/de
442-Category: Arduino/de
443-Category: Deutsch
444-Category: Embedded/de
445-Category: Tutorials/de
449+*From the Free Pascal wiki, page "AVR Embedded Tutorial - UART/de", as the Internet Archive kept it on 2023-03-20. 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](/wiki-contact).*

Back to history