AVR Ein/Ausgabe

Inhaltsverzeichnis

1 Pinout Arduino Board 4

2 AVR PORT - I N P U T → PINB 6

3 AVR PORT Architektur Bausteine 8

4 AVR Port – O U T P U T → PORTB 10

5 AVR PORT Architektur: Fragen 2 12

5.1 Schreibweise in C, C++, C# 13

6 Starkes/ Schwaches Digitalsignal 14

6.1 Fragen: 14

7 AVR Port – INPUT MIT PULLUP → PINB/PORTB 16

8 MASKIEREN: Setzen eines einzelnen Bits 17

9 Maske für Setzen 18

9.1 Schiebeoperation 18

9.2 Mehrere Bits 18

9.3 _BV (Byte Value) Makro 19

10 MASKIEREN: Löschen eines einzelnen Bits 20

11 Maske für Löschen: Einerkomplement 21

12 MASKIEREN: Abfragen eines einzelnen Bits 23

12.1 Ist das Bit gesetzt? 23

12.2 Ist das Bit gelöscht? 24

13 Komfort-Funktionen zur Bitmanipulation stdlib.c 25





1 Pinout Arduino Board



Was ist/ Wozu dient



2 AVR PORT - I N P U T → PINB





uint8_t  x = PINB; 

3 AVR PORT Architektur Bausteine



Was ist/Wozu dient





Schmitt-Trigger: verfügt über unterschiedliche Schaltschwellen für Ein/Aus und kann so Störungen auf einem Eingangssignal des Bausteins ausblenden

Gesteuerter Puffer: hat einen Enable-Eingang über den er ein/ausgeschaltet werden kann; ist im Ausgeschalteten Zustand hochohmig (Z), blockiert also die Leitungen am Ausgang nicht

D-Flipflop: ein 1-Bit-Speicher; speichert bei steigender Taktflake das Eingangssignal bis zum nächsten Takt oder bis der Strom abgeschaltet wird (statischer Speicher); Grundbaustein für Register

Register: meist 8/16/32/64/128 Flipflops werden parallelgeschaltet und können dann die Daten auf dem mehrspurigen Datenhighway (Bus) mit einem Taktschlag abspeichern

SFR: Register im IO Bereich zur Steuerung des Prozessors und/oder der Peripheriegeräte z.B: PORTB, PINB, DDRB, SREG

Pullup: schwacher Widerstand; erzeugt eine 1 auf der Leitung; kann aber leicht überschrieben werden; verhindert, dass eine Leitung in den hochohmigen Zustand Z geht

PMOS-Transistor: Source hängt auf VDD; bei einer Null am Gate wird der Transistor eingeschaltet, es bildet sich ein Kanal zwischen Source und Drain aus; je nach Dotierung ist dieser Kanal ein Kurzschluss oder ein Widerstand; der PMOS Transistor kann also als gesteuerter Pullup verwendet werden

NAND: nur wenn beide Eingänge true sind ist der Ausgang false

INVERTER: bildet das Komplement des Eingangssignals

Bus: Datenhighway; transportiert die Digitaldaten; mehrere parallel geführte Leitungen; Busbreiten als Vielfaches von 2 (beim AVR 8 oder 16 Bit breit); darf immer nur von einem Register beschrieben werden; lange Leitungen, daher hohe parasitäre Kapazitäten, die Baugruppen brauchen starke Treiber um den Ladestrom für diese Kapazitäten liefern zu können Δ U = I * Δ t

Bustreiber: Digitalgatter mit starken Ausgangstreibern

4 AVR Port – O U T P U T → PORTB





X = 12; x = 0b1100; x = 0xC;  
PORTB = x; 



5 AVR PORT Architektur: Fragen 2



5.1 Schreibweise in C, C++, C#

x = 12; x = 0xC;

Schreibweise in GCC

X = 0b0000 1100;



6 Starkes/ Schwaches Digitalsignal



6.1 Fragen:

Pegel von Pullups: h

Pegel von Pulldown: l

Pegel von Digitalgattern: H, L

Pegel der Versorgungsleitungen: 0,1



Ein Kurzschluss zwischen h und l liefert X

Ein Kurzschluss zwischen h und L liefert L;

was liefert ein Kurzschluss zwischen 1 und L?

Taster: 0,Z oder 1,Z usw.

Umschalter: H,L oder 1,0

Taster mit Pullup: 0,h, L,h

7 AVR Port – INPUT MIT PULLUP → PINB/PORTB

DDRB = 0; //alle Pins auf Input
PORTB = 0xff; //alle Pullups aktivieren uint8_t x = PINB; // Pins einlesen



8 MASKIEREN: Setzen eines einzelnen Bits

ohne die anderen Bits in einem Register zu verändern



PORTB = 0b0000010;     //ACHTUNG! Es werden alle Bits gesetzt!



  1. MASKE = 0b0000010;

  2. BITWEISES ODER



Beispiel: Setzen des Bits 1

uint8_t mask = 0b0000 0010;
PORTB = PORTB | mask; 



oder



PORTB |= 0b0000 0010; 





9 Maske für Setzen

Für jedes Bit das in einem SFR (special function register) gesetzt oder gelöscht werden soll muss in der Maske das zugehörige Bit auf 1 gesetzt werden.

9.1 Schiebeoperation

uint8_t maske = 1 << 1;                          

0000 0001 „1“
0000 0010 „1<<1“

9.2 Mehrere Bits

uint8_t maske = (1 << 1) | (1 << 3); 

0000 0010
0000 1000 „1<<3“

0000 1010 „(1 << 1) | (1 << 3)“



Zur besseren Lesbarkeit: Bits in den SFR (special function register) mit Namen und Werten

#define PB1 1
#define PB3 3
uint8_t maske = (1 << PB1)|(1 << PB3); 





9.3 _BV (Byte Value) Makro

In der Stdlib.c ist in io.h ein Makro zur Bildung von Masken definiert:

#define _BV(bit)	(1 << (bit))

Beispiel:

#include <avr/io.h>
uint8_t maske = _BV(PB1) | _BV(PB3)

Aufgabe: Erzeugen Sie folgende Masken: 0000 0001, 1000 0000, 1000 1000



10 MASKIEREN: Löschen eines einzelnen Bits

ohne die anderen Bits in einem Register zu verändern



PORTB = 0b1111 1101;     //ACHTUNG! Es werden alle Bits gesetzt!



  1. MASKE = 0b1111 1101;

  2. BITWEISES UND



Beispiel: Löschen des Bits 1

uint8_t mask = 0b1111 1101;
PORTB = PORTB & mask; 



oder



PORTB &= 0b1111 1101; 



11 Maske für Löschen: Einerkomplement



0b1111 1101 kann gebildet werden durch das Einerkomplement von 0b0000 0010

Vorgangsweise:

  1. Maske bilden wie beim Setzen eines Bits

  2. Einerkomplement ( Operator „~“ in C, C++, C#)





Frage: Maske für Setzen von Bit 1 und Bit 3?

Beispiel:

uint8_t maske = ~ 0b0000 0010; 

uint8_t maske1 = ~ _BV(PB1);
uint8_t maske2 = ~( _BV(PB3) | _BV(PB1) ); //1111 0101

12 MASKIEREN: Abfragen eines einzelnen Bits


12.1 Ist das Bit gesetzt?

if (PINB & _BV(PB3)) …


z.B. PINB 0b0000 1011

_BV(PB3) = 1 << PB3 = 1 << 3 0b0000 1000

Ergebnis 0b0000 1000 TRUE


z.B. PINB 0b0000 0011

_BV(PB3) = 1 << PB3 = 1 << 3 0b0000 1000

Ergebnis 0b0000 0000 FALSE


12.2 Ist das Bit gelöscht?

Abfragen wie vorher, ob das Bit gesetzt ist und das Ergebnis der Abfrage negieren

If ( !(PINB & _BV(bit))) …



z.B. PINB 0b0000 1011
_BV(PB3) = 1 << PB3 = 1 << 3 0b0000 1000

Ergebnis 0b0000 1000 gesetzt → FALSE


z.B. PINB 0b0000 0011

_BV(PB3) = 1 << PB3 = 1 << 3 0b0000 1000

Ergebnis 0b0000 0000 nicht gesetzt → TRUE




13 Komfort-Funktionen zur Bitmanipulation stdlib.c

#include <avr/io.h> //Stdlib.c einbinden

#define bit_is_set(sfr, bit) (_SFR_BYTE(sfr) & _BV(bit))

#define bit_is_clear(sfr, bit) (!(_SFR_BYTE(sfr) & _BV(bit)))

#define loop_until_bit_is_set(sfr, bit) do { } while (bit_is_clear(sfr, bit))

#define loop_until_bit_is_clear(sfr, bit) do { } while (bit_is_set(sfr, bit))





z.B.

#include <avr/io.h>
...
 loop_until_bit_is_clear(PINB, PB3);  
…
 if (bit_is_set(PINB, PB1)) ...