Spickzettel (A4, 2 Seiten)

Maximal verdichtet - das Wichtigste für die Klausur, gedacht als Vorlage für dein handbeschriebenes DIN-A4-Blatt (beidseitig). Reihenfolge nach Punktegewicht der Musterklausur. Klapp die Extra-Notizen auf für Fallen, Mini-Beispiele und Merkhilfen (die kommen nicht mit aufs Blatt, sind aber gut zum Verstehen).


Seite 1 - Grundlagen · Timer · PIO · Signalverarbeitung

Grundlagen / C (Kap. 1)

  • MC = MP + Speicher + Peripherie on-chip (= SoC). MP = universell, MC = für Anwendung zugeschnitten. Sensoren/Aktoren sind extern.
  • volatile: verhindert Wegoptimieren - Wert kann sich durch HW/ISR ändern. Pflicht bei Registern/ISR-Variablen.
  • Register = memory-mapped → als struct abbilden; Zeiger-Cast nötig (Adresse → Registerzeiger), nicht vermeiden.
  • DMA ≠ Memory-Mapped I/O (Klausurfalle!). MMIO = CPU greift auf Peripherie wie auf Speicher zu. DMA = Controller überträgt ohne CPU, nur in leistungsstärkeren MC.
  • AD = analog→digital, DA = digital→analog. Max. Quantisierungsfehler = ½ LSB. Wägeverfahren (SAR, ~n Schritte) schneller als Zählverfahren (bis 2ⁿ Schritte).
  • Bitops: setzen x |= 1<<n; löschen x &= ~(1<<n); toggeln x ^= 1<<n; testen x & (1<<n). -O0 zum Debuggen.
Extra-Notizen
  • Warum volatile: ohne es darf der Compiler while(!flag); zu einer Endlosschleife machen (er liest flag nur einmal). Mit volatile wird bei jedem Zugriff der echte HW-Wert gelesen.
  • const volatile ist sinnvoll: ein nur-lesbares Statusregister, das sich aber von außen ändert.
  • MMIO-Muster: #define REG (*(volatile uint32_t*)0x400E0E00) - genau hier braucht man den Zeiger-Cast.
  • DMA-Kern: die CPU macht nur noch die Ablaufkontrolle (Interrupt "Transfer fertig"), nicht mehr jedes Byte. Deshalb schnell (Gigabit-Ethernet, USB).
  • Speicher: RAM = flüchtig, Flash/ROM = nicht-flüchtig. Beim Reset startet die CPU bei Adresse 0 (dort Flash/ROM).
  • Merksatz zur Falle: "auf Peripherie wie auf Speicher zugreifen" = MMIO, nicht DMA. Das ist eine wiederkehrende Klausurfrage.

Timer / Counter (Kap. 5) - klausurkritisch

  • fA=fCLKPrescRCf_A = \dfrac{f_{CLK}}{\text{Presc}\cdot RC} · RC=fCLKPrescfARC = \dfrac{f_{CLK}}{\text{Presc}\cdot f_A} · TSchritt=PrescfCLKT_{Schritt} = \dfrac{\text{Presc}}{f_{CLK}}
  • 16-Bit: RC65535RC \le 65535. Prescaler-Werte 2, 8, 32, 128, 1024. Optimal = kleinster Prescaler, bei dem RC noch passt (feinste Auflösung).
  • Tastverhältnis =thigh/T= t_{high}/T. RA = Duty·RC (TIOA), RB = 0,5·RC (TIOB, 50 %).
  • Überlauf: T=2BitsPrescfCLKT = \dfrac{2^{Bits}\cdot\text{Presc}}{f_{CLK}}. Genau-n-Schritte: RC = n−1 (Off-by-one).
  • Output (ACPA/ACPC/…): 00=none, 01=set, 10=clear, 11=toggle. PWM: set bei RC, clear bei RA.
  • Capture-Modus: RA/RB werden von HW an Flanken geladen (gemessen); RC = Messdauer/Timeout (vorher konfigurieren). Gemessene Zeit = (RB−RA)·Presc/f_CLK.
Extra-Notizen
  • Rechenbeispiel: fCLK=5MHzf_{CLK}=5\,\text{MHz}, f=100Hzf=100\,\text{Hz}RC=5e6/(2100)=25000RC = 5\text{e}6/(2\cdot100)=25000 (≤ 65535 ✓). Presc 2 gewählt, weil größtes RC = feinste Auflösung.
  • Warum kleinster Prescaler: großes RC → kleinere relative Rundung von RA/RB → genaueres Tastverhältnis. Zu großer Prescaler → RC klein → grobe Stufen.
  • Zwei Betriebsarten: Waveform (Signal erzeugen, RA/RC steuern TIOA) vs Capture (Zeit messen, RA/RB rasten den Zählerstand an Flanken ein).
  • TIOA & TIOB: zwei Ausgänge desselben Zählers → gleiche Frequenz (RC), nur unterschiedliches Tastverhältnis (RA bzw. RB).
  • RC-Compare setzt den Zähler zurück (CPCTRG) → legt die Periode fest.
  • Off-by-one: Zähler startet bei 0, also RC = (Anzahl − 1) für genau n Schritte (in der Klausur oft vernachlässigt, außer es steht "genau").

Parallele I/O + 7-Segment (Kap. 3)

  • SODR = set (Ausgang High), CODR = clear (Low), OSDR = read. High-aktiv: Segment an bei 1.
  • Ziffern (Segmente a,b,c,d,e,f,g): 0=abcdef 1=bc 2=abdeg 3=abcdg 4=bcfg 5=acdfg 6=acdefg 7=abc 8=abcdefg 9=abcdfg.
  • Low-aktiv häufiger: MC kann mehr Strom sinken (nach Masse ziehen) als sourcen.
  • C-Falle Rangfolge: + bindet stärker als <<x<<8+2 = x<<10. Klammern!
Extra-Notizen
  • Dekodier-Beispiel: 0x7D = 0111 1101 → Bits 0,2,3,4,5,6 = Segmente a,c,d,e,f,g (nur b fehlt) → 6. Genau so liest man SODR-Hexwerte.
  • High- vs low-aktiv = Kathode/Anode: high-aktiv → gemeinsame Kathode (Segment leuchtet bei High am Pin); low-aktiv → gemeinsame Anode (leuchtet bei Low).
  • Warum low-aktiv üblich: die Ausgangsstufe kann nach Masse mehr Strom sinken als sie sourcen kann → LED-Strom zieht der MC nicht selbst auf.
  • Rangfolge-Eselsbrücke: Shift <</>> liegt unter +/-. Bei jeder Registerrechnung mit Shift klammern: (x << 8) + 2.
  • ~ (Invertierung): setzt alle Bits um; bei SODR = ~maske leuchten also genau die im maske gelöschten Segmente.

Signalverarbeitung (Kap. 7) - klausurkritisch

  • sin(kπt)\sin(k\pi t) hat f=k/2f = k/2 Hz (da ω=2πf\omega = 2\pi f). Amplitude aus Spektrum ablesen (fehlt → 0).
  • Abtasttheorem (Nyquist): fs>2fmaxf_s > 2\,f_{max} (strikt) für artefaktfreie Abtastung.
  • Alias: falias=fnfsf_{alias} = |f - n\cdot f_s| (nächstes Vielfaches), in [0,fs/2][0, f_s/2] falten.
  • Tiefpass durch Abtastwahl (höchste weglassen): 2f2.ho¨chste<fs2fho¨chste2\,f_{2.\text{höchste}} < f_s \le 2\,f_{höchste}.
  • ADC-Auflösung: ΔU=Uref/2n\Delta U = U_{ref}/2^{n} (n Bit). Max. Fehler = ΔU/2\Delta U/2.
  • Datenmenge: D=fsBit8tD = f_s \cdot \dfrac{\text{Bit}}{8} \cdot t [Byte].
  • Gleitender Mittelwert m=1nxim=\frac1n\sum x_i: Tiefpass, Ordnung n−1, glättet, erzeugt Verzögerung. Oversampling → höhere eff. Auflösung, einfacherer AA-Filter.
Extra-Notizen
  • Alias-Beispiel: f=800Hzf=800\,\text{Hz}, fs=1000Hzf_s=1000\,\text{Hz} → Nyquist 500 → 800>500800>500 → Alias =1000800=200Hz=|1000-800|=\mathbf{200\,Hz}.
  • Warum strikt >: bei fs=2fmaxf_s = 2f_{max} exakt trifft man evtl. nur die Nulldurchgänge (2 Samples/Periode) → Komponente kann verschwinden. Deshalb echt größer.
  • Falten (Rezept): solange f>fs/2f > f_s/2: ffsff \leftarrow |f_s - f| wiederholen, bis ff im Basisband liegt.
  • ADC-Beispiel: 12 Bit, Uref=3,3VU_{ref}=3{,}3\,\text{V}ΔU=3,3/40960,806mV\Delta U = 3{,}3/4096 \approx 0{,}806\,\text{mV}, max. Fehler ≈ 0,4 mV.
  • Moving Average = FIR-Tiefpass: größeres n → glatter, aber träger (mehr Verzögerung/Gruppenlaufzeit). Erst nach n Werten gültig.
  • Oversampling-Regel: je Überabtastung + Mittelung ≈ +1 Bit effektive Auflösung.
  • AA-Filter: analoger Tiefpass vor dem ADC nötig, damit hohe Frequenzen gar nicht erst falten - Grenze fsfNutzband\ge f_s - f_{Nutzband}, nicht erst bei Nyquist.

Seite 2 - CRC · Leitungscodes · Seriell · Interrupts · Rest

CRC & Fehlererkennung (Kap. 10)

  • g(x)g(x) → binär: je Exponent ein Bit (x⁴+x+1 = 10011). Grad = Anzahl Prüfbits.
  • FCS: Nachricht + (Grad) Nullen, Modulo-2-Division (XOR bei führender 1), Rest = Prüfbits.
  • Senden = Daten + FCS. Empfänger dividiert Codewort → Rest 0 = gültig.
  • HW: rückgekoppeltes Schieberegister + EXOR-Gatter (LFSR). Iterationen = Anzahl Nachrichtenbits.
  • CRC erkennt Bündelfehler; Parität (VRC) nur ungerade Fehleranzahl.
  • Hamming-Distanz d: erkennbar = d1d-1, korrigierbar = (d1)/2\lfloor (d-1)/2 \rfloor.
Extra-Notizen
  • Mini-Division: Daten 1011, g=x4+x3+1=g=x^4+x^3+1= 1100110110000 : 11001 → Rest 4 Bit = FCS. XOR nur, wenn das führende Bit 1 ist; sonst 0 "herunterziehen".
  • Warum Nullen anhängen: sie schaffen den Platz für die FCS (Grad-viele Bits), die dann den Rest ersetzen.
  • Erkennungsstärke: ein CRC vom Grad r erkennt alle Bündelfehler ≤ r Bit, alle 1-Bit-Fehler und (bei gutem g) alle 2-Bit-Fehler. Stärke hängt vom Generatorpolynom ab.
  • Rangordnung: Paritätsbit < Prüfsumme (Addition) < CRC (Polynomdivision).
  • Empfänger-Trick: statt neu zu rechnen, das ganze Codewort (Daten+FCS) dividieren → Rest 0 ⇒ fehlerfrei.

Leitungscodes (Kap. 10)

  • Baudrate = Symbole/s. NRZ/NRZI: Baud = Bitrate. Manchester/RZ: Baud = 2·Bitrate (halbe Nutzrate).
  • Manchester IEEE 802.3: Mitten-Flanke steigend = 1, fallend = 0. G. E. Thomas = invertiert (steigend=0, fallend=1). Selbsttaktend, Preis: doppelte Bandbreite.
  • NRZI: 1 = Pegelwechsel, 0 = kein Wechsel. Lange 0-Folge → Sync-Verlust → Bit-Stuffing.
Extra-Notizen
  • Manchester-Beispiel (IEEE): Mittenflanken steigend, fallend, steigend, steigend, fallend → 1 0 1 1 0. Nach G. E. Thomas dieselbe Figur = 0 1 0 0 1 (invertiert).
  • Selbsttaktend heißt: in jeder Bitmitte liegt eine Flanke → der Empfänger gewinnt den Takt aus dem Signal, keine separate Taktleitung nötig.
  • Preis: 2 Symbole pro Bit → doppelte Bandbreite; außerdem kein DC-Anteil (gut für Übertrager/Trafokopplung).
  • NRZI-Problem: viele 0 = keine Flanke = Taktverlust. Bit-Stuffing: nach k gleichen Bits künstlich einen Wechsel einfügen (empfängerseitig wieder entfernt).
  • Merkhilfe: "IEEE = In Mitte steigt die 1".

Serielle Schnittstelle / USART (Kap. 4)

  • 8N1 = 1 Start + 8 Daten + 0 Parität + 1 Stopp = 10 Bit/Zeichen. Zeichen/s = Baud / Rahmenbits.
  • Baud = MCK16CD\dfrac{MCK}{16\cdot CD} (BRGR), Empfänger tastet 16× ab (Bitmitte). Startbit synchronisiert.
  • THR → TSR (serialisiert, sendet TxD); RSR → RHR (deserialisiert, empfängt RxD). Handshake CTS/RTS/DCD optional.
  • I²C (TWI): SDA + SCL, Master/Slave, 7-Bit-Adresse, halbduplex, open-drain. SPI: MOSI/MISO/SCK/CS, vollduplex, Adressierung per Chip-Select, schneller, mehr Leitungen.
  • DMA/PDC: Pointer + Counter (US_TPR/US_TCR); HW dekrementiert, bei 0 Interrupt ENDTX/ENDRX.
Extra-Notizen
  • Zeichenrate-Beispiel: 9600 8N1 → 9600 / 10 = 960 Zeichen/s.
  • Baudraten-Fehler: BRGR/CD ist ganzzahlig → reale Baud weicht ab. Für garantierten Durchsatz den Teiler abrunden (Baud rauf), nicht kaufmännisch runden.
  • Parität: even/odd - erkennt nur eine ungerade Fehleranzahl; N = keine.
  • I²C-Arbitrierung: wired-AND auf SDA - wer eine 0 treibt, "gewinnt"; Verlierer zieht sich zurück. Start = SDA fällt, während SCL high.
  • SPI-Modi: CPOL (Takt-Ruhepegel) + CPHA (Abtastflanke) → 4 Modi; Sender/Empfänger müssen denselben Modus nutzen.
  • Warum 16× Oversampling: der Empfänger findet die Bitmitte sicher und ist robust gegen Taktabweichung.

Interrupts (Kap. 6) + SWI (Kap. 9)

  • Ablauf: IRQ (Peripherie) → Controller → CPU signalisieren → laufenden Befehl unterbrechen → Vektorregister lesen → ISR-Adresse in CPU-Register laden → ISR → Rücksprung (reentrant).
  • Priorität 0-7 (AIC) ordnet parallele IRQs; Vektortabelle hält ISR-Adressen. ISR = Funktion mit Attribut (autom. Kontextsicherung).
  • Polling (CPU fragt ab) vs Interrupt (HW meldet) vs DMA (Transfer ohne CPU).
  • Shared-Data-Problem: gemeinsame Variablen volatile + kritischer Abschnitt (Interrupts kurz sperren). Interrupt-Latenz = Zeit bis ISR-Start.
  • NVIC (Cortex-M3): Auto-Stacking, Tail-Chaining, Late-Arriving. SWI/SVC: synchroner SW-Interrupt, User → Supervisor-Mode.
Extra-Notizen
  • Latenz-Falle: ein zu langer kritischer Abschnitt (IRQ gesperrt) kann eine hochpriore ISR über ihre Deadline blockieren - selbst bei geringer CPU-Auslastung. Auslastung ≠ Planbarkeit.
  • Reentranz: Rücksprung aus der ISR gibt Interrupts wieder frei; eine höher-priore ISR darf eine niedrigere unterbrechen (Preemption) → gemeinsame Daten schützen.
  • Spurious Interrupt: Anforderung verschwindet, bevor sie bearbeitet wird → dedizierter Spurious-Handler fängt das ab.
  • Vektortabelle: beim Start Flash → RAM kopieren und remappen, damit die ISR-Adressen zur Laufzeit änderbar sind.
  • NVIC-Vorteile: Tail-Chaining (direkt in die nächste ISR ohne Pop/Push), Late-Arriving (Wechsel auf höher-prioren IRQ während des Stackings).
  • SWI/SVC-Zweck: Anwendungscode ruft kontrolliert Systemdienste (z. B. putchar) auf und wechselt dabei in den privilegierten Modus.

Power (Kap. 2) · ARM (Ref.) · Regelung (Kap. 8)

  • PMC: Peripherietakt einzeln an/aus (PMC_PCER/PCDR). Reset: CPU-Takt an, Peripherie-Takt aus (SW aktiviert). PdynfCU2P_{dyn}\sim f\cdot C\cdot U^2 → Takt senken/abschalten spart Energie.
  • ARM: 32-Bit RISC, Load/Store, R0-R15 (R13=SP, R14=LR, R15=PC), CPSR, Modi (User/IRQ/FIQ/SVC…). Thumb = 16-Bit-Befehle, ~65 % Codegröße.
  • Regelung: Steuerung = offen, Regelung = geschlossen (Rückführung). PID: P schnell (bleibende Abweichung), I beseitigt sie (träge, Windup), D dämpft (rauschempfindlich). Zweipunktregler + Hysterese verhindert Prellen. Anti-Windup: I begrenzen.
Extra-Notizen
  • Schlafmodi: Sleep/Wait (CPU-Takt aus, schnelles Aufwachen, Zustand bleibt) vs Backup (fast alles aus, minimaler Strom, aber langsames, reset-ähnliches Aufwachen). Kompromiss Strom ↔ Aufwachzeit.
  • Clock-Tree: Quarz → PLL (× MUL+1 / ÷ DIV) → MCK → Prescaler → Peripherie. Beispiel Arduino Due: 12 MHz × 14 / 2 = 84 MHz.
  • ARM-Pipeline: 3-stufig (Fetch-Decode-Execute) beim ARM7 → PC läuft dem ausgeführten Befehl um 2 voraus. Pro Modus eigener SP/LR.
  • Thumb-Abwägung: dichter/energiesparender Code, aber eingeschränkter Befehlssatz (meist R0-R7). Thumb-2 (Cortex-M3) mischt 16/32-Bit und hebt das auf.
  • Windup-Beispiel: Stellglied in Sättigung (z. B. 100 %) → I-Anteil wächst ungebremst weiter → beim Umkehren starkes Überschwingen. Anti-Windup: I-Anteil einfrieren/begrenzen (Clamping).
  • Zweipunkt-Hysterese: ein bei unterer, aus bei oberer Schwelle → ruhiges Schalten statt Prellen um den Sollwert.

Prio-Tipp: Timer- und Signalverarbeitungs-Formeln sicher beherrschen (zusammen ~41 P), CRC-Division und Manchester-Dekodierung üben. Grundlagen-Fallen (DMA vs. MMIO, AD/DA, Wäge/Zähl) auswendig.