Sign in Join
Wiki copytemporary

AVR Embedded Tutorial - UART/de: what changed

Revision 2 to 3. 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-
301# UART Polling
312
323## ATmega328p (Arduino uno/nano)
334
34-Für die serielle Ausgabe wird ein Terminal mit folgenden Einstellungen gebraucht:
5+Für die serielle Ausgabe wird ein Terminal mit folgenden Einstellungen gebraucht:
356
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.
7+| | |
8+|-----------|------|
9+| Baud Rate | 9600 |
10+| Bits | 8 |
11+| Stopbits | 1 |
12+| Parity | none |
4313
14+Beim Betätigen von `Space` im Terminal-Programm, sollte ein "Hello World !" zurück kommen.
15+
4416### Konstanten für Inizialisierung
45-```
17+
18+``` pascal
4619const
47- CPU_Clock = 16000000; // Taktfrequenz Arduino, default 16MHz.
48- Baud = 9600; // Baudrate
49- Teiler = CPU_Clock div (16 * Baud) - 1;
20+ CPU_Clock = 16000000; // Taktfrequenz Arduino, default 16MHz.
21+ Baud = 9600; // Baudrate
22+ Teiler = CPU_Clock div (16 * Baud) - 1;
5023```
5124
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.
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.
5326
5427### Inizialisieren
5528
56-Die UART-Schnittstelle konfigurierieren.
57-```
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;
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;
6640```
6741
6842### Zeichen empfangen
69-```
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;
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;
7550```
7651
7752### Zeichen senden
78-```
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;
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;
8460```
8561
8662### String senden
87-```
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;
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;
9673```
9774
9875### Hauptschleife
9976
100-Hier wird gewartet, bis `Space` ankommt, anschliessend wir "Hello World !" gesendet.
101-```
77+Hier wird gewartet, bis `Space` ankommt, anschliessend wir "Hello World !" gesendet.
78+
79+``` pascal
10280program Project1;
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.
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.
11189```
11290
11391## ATtiny2313
11492
115-Beim ATtiny2313 haben die Register eine andere Bezeichnung als beim ATmega328p.
93+Beim ATtiny2313 haben die Register eine andere Bezeichnung als beim ATmega328p.
11694
117- * Die **0** entfällt in der Bezeichnung.
118- * **UBRR0** muss man in **UBRRH** und **UBRRL** zerlegen.
95+- Die **0** entfällt in der Bezeichnung.
96+- **UBRR0** muss man in **UBRRH** und **UBRRL** zerlegen.
11997
120-Das sieht dann so aus:
121-```
98+Das sieht dann so aus:
99+
100+``` pascal
122101UBRRH := Teiler shr 8;
123- UBRRL := Byte(Teiler);
124-
125- UCSRB := (1 shl TXEN) or (1 shl RXEN);
126- UCSRC := (%011 shl UCSZ);
102+UBRRL := Byte(Teiler);
103+
104+UCSRB := (1 shl TXEN) or (1 shl RXEN);
105+UCSRC := (%011 shl UCSZ);
127106```
128107
129-(Der Code wurde nicht getestet)
108+(Der Code wurde nicht getestet)
130109
131110# Interrupt
132111
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.
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.
134113
135-Bei höheren Baudraten, ist dies zwingend.
114+Bei höheren Baudraten, ist dies zwingend.
136115
137-Es wir ein einfacher Ringpuffer mit 16 Zeichen verwendet.
116+Es wir ein einfacher Ringpuffer mit 16 Zeichen verwendet.
138117
139-Die Beispiele zeigen dies anhand eines ATmega328p (Arduino uno/nano).
118+Die Beispiele zeigen dies anhand eines ATmega328p (Arduino uno/nano).
140119
141120## Empfangspuffer
142121
143122### Deklaration
144123
145-Zeichenbuffer deklarieren, hier wir ein Puffer von 16 Zeichen angelegt.
146-```
124+Zeichenbuffer deklarieren, hier wir ein Puffer von 16 Zeichen angelegt.
125+
126+``` pascal
147127const
148- Crxlen = 16; // Puffergrösse
149- var
150- RXBuf: array[0..Crxlen - 1] of byte;
151- RXread: byte = 0;
152- RXwrite: byte = 0;
128+ Crxlen = 16; // Puffergrösse
129+var
130+ RXBuf: array[0..Crxlen - 1] of byte;
131+ RXread: byte = 0;
132+ RXwrite: byte = 0;
153133```
154134
155135### Inzialisieren
156136
157-Dies ist ähnlich des Polling verfahren, der Unterschied, man teilt mit **RXCIE0** mit, das beim Zeichenempfang ein Interrupt ausgelöst wird.
158-```
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;
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;
167148```
168149
169150### Interrupt
170151
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;
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;
189169 end;
170+ end;
171+ end;
190172```
191173
192174### Hauptschleife
193175
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-```
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
196179begin
197- // UART inizialisieren, die Interrupt gesteuert ist.
198- UARTInit;
199-
200- // Interrupt aktivieren.
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.
201203 asm sei 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.
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.
232215```
233216
234217## Sendepuffer
235218
236219### Deklaration
237220
238-Sendepuffer deklarieren, hier wir ein Puffer von 16 Zeichen angelegt.
239-```
221+Sendepuffer deklarieren, hier wir ein Puffer von 16 Zeichen angelegt.
222+
223+``` pascal
240224const
241- CTXlen = 16; // Puffergrösse
242- var
243- TXBuf: array[0..CTXlen - 1] of byte;
244- TXread: byte = 0;
245- TXwrite: byte = 0;
225+ CTXlen = 16; // Puffergrösse
226+var
227+ TXBuf: array[0..CTXlen - 1] of byte;
228+ TXread: byte = 0;
229+ TXwrite: byte = 0;
246230```
247231
248232### Inzialisieren
249233
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.
251-```
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;
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;
260245```
261246
262247### Interrupt
263248
264-Der Interrupts, wird ausgelöst, sobald das Zeichen im UART gesendet wurde.
249+Der Interrupts, wird ausgelöst, sobald das Zeichen im UART gesendet wurde.
265250
266-Sobald der Ringpuffer leer ist, wird die Interrupt-Funktion wider deaktiviert.
251+Sobald der Ringpuffer leer ist, wird die Interrupt-Funktion wider deaktiviert.
267252
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);
277-
278- // Wen Zeiger am Ende, wieder von vorn beginnen.
279- if TXread >= CTXlen then begin
280- TXread := 0;
281- end;
253+Die Abfrage von **UDRE0** wird hier nicht gebraucht, da der Interrupt nur ausgelöst wird, wen der Puffer leer ist.
254+
255+``` pascal
256+ procedure UART_UDRE_Senden; public Name 'USART__UDRE_ISR'; interrupt;
257+ begin
258+ // Zeichen Senden.
259+ UDR0 := TXBuf[TXread];
282260
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;
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;
288274```
289275
290276### String senden
291277
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);
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;
310292 end;
293+ end;
294+
295+ // Sende Interrupt aktivieren.
296+ UCSR0B := UCSR0B or (1 shl UDRIE0);
297+ end;
311298```
312299
313300### Hauptschleife
314301
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-```
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
317305var
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.
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.
345333```
346334
347335# Software - UART / UART - Emulation
348336
349-Es ist auch möglich eine UART-Schnittstelle per Software zu emulieren.
337+Es ist auch möglich eine UART-Schnittstelle per Software zu emulieren.
350338
351-Dies ist praktisch, wen man einen AVR hat, welcher keinen/zuwenig Hardware-UART hat.
339+Dies ist praktisch, wen man einen AVR hat, welcher keinen/zuwenig Hardware-UART hat.
352340
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.
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.
354342
355-**Wichtig:** Während der Übertragung, müssen Interrupts gesperrt werden.
343+**Wichtig:** Während der Übertragung, müssen Interrupts gesperrt werden.
356344
357-Gleichzeigtes lesen und schreiben funktioniert nicht, da kein Puffer vorhanden ist.
345+Gleichzeigtes lesen und schreiben funktioniert nicht, da kein Puffer vorhanden ist.
358346
359-Im Idealfall ist dies gut verwendbar, um Fehler auf ein UART-Terminal auszugeben.
347+Im Idealfall ist dies gut verwendbar, um Fehler auf ein UART-Terminal auszugeben.
360348
361349## Konstanten
362350
363-In diesem Beispiele werden die Pin 2 & 3 von PortD verwendet.
364-```
351+In diesem Beispiele werden die Pin 2 & 3 von PortD verwendet.
352+
353+``` pascal
365354const
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
373-```
355+ CPU_Clock = 16000000; // Taktfrequenz Arduino, default 16MHz.
356+ Baud = 9600; // Baudrate
374357
375-Den Empfangs-Pin auf Input stellen.
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
376362```
363+
364+Den Empfangs-Pin auf Input stellen.
365+
366+``` pascal
377367begin
378- DDRD := DDRD or TXpin;
379- ...
380- // Loop
381- ...
382- end.
368+ DDRD := DDRD or TXpin;
369+ ...
370+ // Loop
371+ ...
372+end.
383373```
384374
385-**Hinweis:** Will man die gleichen Pins wie bei der Hardware-UART verwenden, muss beim Arduino der Pin **0** & **1** frei gegeben werden.
386-```
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
387378begin
388- UCSR0B := 0; // Blockierter Pin 0 & 1 frei geben
389- ...
390- // Loop
391- ...
392- end.
379+ UCSR0B := 0; // Blockierter Pin 0 & 1 frei geben
380+ ...
381+ // Loop
382+ ...
383+end.
393384```
394385
395386## Zeichen senden
396-```
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;
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;
414406```
415407
416408## Zeichen empfangen
417409
418-**Hinweis:** Wen kein Zeichen im Empfang kommt, hängt die Schleife im Endlosen.
419-```
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-```
410+**Hinweis:** Wen kein Zeichen im Empfang kommt, hängt die Schleife im Endlosen.
439411
440-
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;
431+```
441432
442433# Siehe auch
443434
444- * Übersichtseite [[AVR Embedded Tutorial/de|AVR Embedded Tutorial]]
435+- Übersichtseite [[AVR Embedded Tutorial/de|AVR Embedded Tutorial]]
445436
446-Autor: [Mathias](</User:Mathias> "User:Mathias")
437+Autor: Mathias
447438
448439---
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).*
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

Back to history