Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
Beide Seiten der vorigen Revision Vorhergehende Überarbeitung Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
microcontrollertechnik:skript [2024/10/07 00:00] – angelegt mexleadmin | microcontrollertechnik:skript [2024/10/28 05:04] (aktuell) – mexleadmin | ||
---|---|---|---|
Zeile 6: | Zeile 6: | ||
- Wdh. Hello Blinking World: | - Wdh. Hello Blinking World: | ||
- | - DDRx, PORTx, _Delay_ms() --> R steht fast immer für Register | + | - '' |
- --> einmal kompilieren und in Simulide aufbauen | - --> einmal kompilieren und in Simulide aufbauen | ||
- Welche " | - Welche " | ||
Zeile 12: | Zeile 12: | ||
- " | - " | ||
- Frage an Studis "Wer weiß nicht was PWM ist?" | - Frage an Studis "Wer weiß nicht was PWM ist?" | ||
- | |||
In MC Studio | In MC Studio | ||
- | - neues Projekt | + | - neues Projekt |
- jetzt neu: mit Display! | - jetzt neu: mit Display! | ||
- --> Bibliothek aus wiki herunterladen! | - --> Bibliothek aus wiki herunterladen! | ||
- Project --> Add --> existing Item (NICHT drag & drop) | - Project --> Add --> existing Item (NICHT drag & drop) | ||
- | - bei mir --> F2 Namen ändern auf "lcd_lib_de.h" | + | - bei mir --> F2 Namen ändern auf '' |
- Split Screen | - Split Screen | ||
- Was tun, um Lib in main einzufügen? | - Was tun, um Lib in main einzufügen? | ||
- | - #include! | + | - '' |
- | - #inc + < | + | - '' |
- | - --> Unterschied < | + | - --> Unterschied |
- | - Durchsicht der lcd_lib_de.h | + | - Durchsicht der '' |
- | - F_CPU | + | - '' |
- --> CPU Frequenz, wichting für genaues Timing der delays | - --> CPU Frequenz, wichting für genaues Timing der delays | ||
- | - hier 18,432 MHz --> Minimexle Frequenz | + | - hier '' |
- | - Warum 18,432? | + | - Warum '' |
- ILIAS --> Elektronik Labor --> MiniMEXLE Schaltbild | - ILIAS --> Elektronik Labor --> MiniMEXLE Schaltbild | ||
- " | - " | ||
Zeile 36: | Zeile 35: | ||
- Funktionsprotoypen --> bitte immer am anfan angeben --> gut für eine Übersicht | - Funktionsprotoypen --> bitte immer am anfan angeben --> gut für eine Übersicht | ||
- als erstes immer Initialisierung (anlegen der Variablen, verschiedene Konfigurationen etc.) | - als erstes immer Initialisierung (anlegen der Variablen, verschiedene Konfigurationen etc.) | ||
- | - lcd_i + < | + | - '' |
- schon mal kompilieren (immer mal kompilieren zum test, ob noch alles klappt) | - schon mal kompilieren (immer mal kompilieren zum test, ob noch alles klappt) | ||
- noch nicht lauffähig, da nichts angezeigt ! | - noch nicht lauffähig, da nichts angezeigt ! | ||
Zeile 42: | Zeile 41: | ||
- welche Unterfunktion wohl geeignet? | - welche Unterfunktion wohl geeignet? | ||
- Hinweis auf Inkonsistenz bei Namensgebung | - Hinweis auf Inkonsistenz bei Namensgebung | ||
- | - Eingabe lcd_displayMessage(" | + | - Eingabe |
- Flashen auf Minimexle | - Flashen auf Minimexle | ||
- Add Target --> STK500 --> ersten COM Port auswählen (und - falls es nicht passt - den nächsten) | - Add Target --> STK500 --> ersten COM Port auswählen (und - falls es nicht passt - den nächsten) | ||
Zeile 48: | Zeile 47: | ||
- Apply --> Device Signature sichtbar? | - Apply --> Device Signature sichtbar? | ||
- --> Memories --> Program | - --> Memories --> Program | ||
- | - Ausgabe von "Hallo! Zähler: | + | - Ausgabe von '' |
- | - kann "ä" | + | - kann '' |
- --> Datasheet lesen! | - --> Datasheet lesen! | ||
- Am besten in der Schaltung den Namen suchen | - Am besten in der Schaltung den Namen suchen | ||
Zeile 55: | Zeile 54: | ||
- Googeln nach ST7066U Datasheet | - Googeln nach ST7066U Datasheet | ||
- Kurzes darüberscrollen über das Datasheet | - Kurzes darüberscrollen über das Datasheet | ||
- | - --> Character code Table! --> ist da "ä" | + | - --> Character code Table! --> ist da '' |
- | - Also: was tun? entweder | + | - Also: was tun? entweder |
- Vergleich in Simulide: | - Vergleich in Simulide: | ||
- Aufbau der Schaltung: mega88 + Hd44780 (ist kompatibel zu ST7066U) | - Aufbau der Schaltung: mega88 + Hd44780 (ist kompatibel zu ST7066U) | ||
- Wie verbinden? Siehe lib (wenn gut beschrieben) oder MEXLE Schaltung | - Wie verbinden? Siehe lib (wenn gut beschrieben) oder MEXLE Schaltung | ||
- | - In lib: Port-Bits. PIN_EN, PIN_RS --> wo in Simulide? | + | - In lib: Port-Bits. |
- | - Für was steht EN? --> Enable. RS --> Register Select | + | - Für was steht '' |
- | - PORT_DATA: von PORTC nur die ersten 4 bits (0...3) | + | - '' |
- | - 18,432 MHz eingeben! | + | - in Simulide '' |
- hex file Flashen | - hex file Flashen | ||
- --> animation einschalten (High/Low wird angezeigt) | - --> animation einschalten (High/Low wird angezeigt) | ||
- es wird noch nichts ausgegeben?? | - es wird noch nichts ausgegeben?? | ||
- | - PC0 auf D4, PC1 auf D5, PC2 auf D6, PC3 auf D7 | + | - '' |
- | - jetzt klappts , aber ä an falscher Position | + | - jetzt klappts, aber '' |
- | - lcd_gotoxy einfügen | + | - '' |
- In Simulide autoload einschalten! | - In Simulide autoload einschalten! | ||
Jetzt: aufsteigende Zahlen ausgeben | Jetzt: aufsteigende Zahlen ausgeben | ||
Was tun? | Was tun? | ||
- | - Laufvariable anlegen und nutzen: uint8_t i=0; und i++ in der Schleife | + | - Laufvariable anlegen und nutzen: |
- | - wie gibt man Zahlen aus? sprintf? (kann in String einen Zahlenwert ausgeben) | + | - wie gibt man Zahlen aus? '' |
- | - sprintf(output_str, | + | - '' |
- | - output_str deklarieren | + | - '' |
- | - kompilieren --> #include < | + | - '' |
+ | - kompilieren --> | ||
- Simulation herunterdrehen | - Simulation herunterdrehen | ||
Zeile 84: | Zeile 84: | ||
Die CPU kann aber schneller! | Die CPU kann aber schneller! | ||
- Blick ins Datenblatt des atmega88 | - Blick ins Datenblatt des atmega88 | ||
- | - Blockbild | + | - Blockbild |
- | - T/C im Inhaltsverzeichnis --> 16 bit Timer/ | + | - Vergleich mit Zahnarztpraxis |
+ | - " | ||
+ | - viele Helfer (Servants) die der CPU zuarbeiten | ||
+ | - PORT's unten kennen wir schon. Sind die Türsteher (doorman) für die Anschlüsse | ||
+ | - Aber auch Analog Digital Wandler, nicht flüchtiger Speicher EEPROM (non-volatile memory) und mehr | ||
+ | - Wir werden Timer und Counter nutzen | ||
+ | - T/C im Inhaltsverzeichnis | ||
+ | | ||
+ | | ||
+ | - **16 bit Timer/ | ||
+ | - wieder Blockbild, diesmal vom Timer / Counter | ||
+ | - wieder echt kompliziert auf den ersten Blick | ||
- wichtig sind immer die Register | - wichtig sind immer die Register | ||
- | - TCNTn --> timer Counter ; für was steht n? in Mathe? | + | - '' |
- | - OCRnA --> Output Compare | + | - --> timer Counter ; für was steht '' |
- | - TCCRnA | + | - das ist der eigentliche aufsteigende Zählwert |
- | - sprintf(output_str, | + | - kann auch beschrieben werden |
- | - kommt noch nix heraus! | + | - '' |
- | - Control logic --> steht im folgenden in der Register Description | + | - '' |
- | - Blick in die Tabellen, was bei initialisierung | + | - Zeilen mit '' |
- | - --> CS auf 000 hat keine Clock! | + | - bei Ausgabe Position ändern: '' |
- | - also CS10 setzen | + | - diesmal: '' |
- | - TCCR1B |= 1<< | + | - kompilieren und in Simulide starten |
+ | - TC zählt | ||
+ | - siehe Blockdiagramm: | ||
+ | - Blick in die Tabellen, was bei Initialisierung des uC mit 0 passiert | ||
+ | - bei vielen ergibt '' | ||
+ | | ||
+ | - mit CS kann der Vorteiler (prescaler) gesetzt werden, welcher für die CPU Clk zum zählen herunterteilt | ||
+ | - gut wäre '' | ||
+ | - Wo ist '' | ||
+ | - Eingabe von '' | ||
+ | - jetzt zählt der Zähle echt schnell. Schneller als die Anzeige! | ||
+ | - Neue Challenge: Blinken ohne '' | ||
+ | - Mit Zähler möglich! Wie? mal selbst überlegen! | ||
+ | - z.B. '' | ||
+ | - geht auch besser! Denn der Knecht kann noch mehr: | ||
+ | - Blick ins Datenblatt --> viele Seiten! | ||
+ | - Blick auf Block Diagramm des TC: | ||
+ | - '' | ||
+ | - wo geht das Vergleichsergebnis hin? | ||
+ | - zu " | ||
+ | - leider etwas irreführend, | ||
+ | - jetzt erstmal Datenblatt nach '' | ||
+ | - Oh! Kommt als Pin am Chip vor. | ||
+ | - Warum wohl? | ||
+ | - was könnte das " | ||
+ | - suchen im Datenblatt nach **__Waveform generat__** (ohne **__ion__**!) | ||
+ | - (zunächst im 8-Bit Timer gefunden) Output compare unit, block diagram | ||
+ | - hier als " | ||
+ | - Der Generator wird über die Register bits WGM und COM geändert | ||
+ | - (besser im 16-bit TC1 das Block diagramm nachsehen) | ||
+ | - wieder Register description ansehen | ||
+ | - erste Bits im TCCR1A sind COM.. | ||
+ | - Blick in die Tabelle: was muss eingestellt werden, um eine Ausgabe für die blinkende LED zu bekommen? | ||
+ | - '' | ||
+ | - wir brauchen '' | ||
+ | - '' | ||
+ | - UND: '' | ||
+ | - Output-Pin togglt! Yeah :-) | ||
+ | - Problem: wir können die Geschwnindigkeit nich richtig einstellen :-( | ||
+ | - Also Challenge: zeitlich einstellbares toggeln | ||
+ | - Bisher: timer zählt stur von 0 ... 65535, also er verwendet OCR1A gar nicht! | ||
+ | - Wäre gut den MaxWert einstellen zu können, also nach erreichen von OCR1A wieder zurück auf 0. | ||
+ | - Lösung über "Clear Timer on Compare": | ||
+ | - timing diagramm erklären | ||
+ | - Mal alle Wave Generation Modes ansehen: | ||
+ | - Normal: 0 ... 65535, und dann wieder Sprung auf 0 --> OC1A ändert sich nur bei max Wert | ||
+ | - Fast PWM: | ||
+ | - 0 ... max Wert, und dann wieder Sprung auf 0 --> OC1A bei TCNT>= OCR1A gleich 0, sonst 1 | ||
+ | - Fast PWM kann verschiedene max Werte haben: 255, 511, 1023, ICR1 und sogar OCR1A selbst | ||
+ | - Ansteigende Flanke immer bei 0 --> links bündig! | ||
+ | - PWM, phase correct | ||
+ | - 0 ... max Wert, und dann: max Wert ... 0 --> OC1A bei TCNT>= OCR1A gleich 0, sonst 1 | ||
+ | - halb so schnell weil doppelte Rampe | ||
+ | - mitten zentriert | ||
+ | - Für uns wichtig Mode 4: da denn OCR1A der Maxwert, also die Dauer für Ein (und Dauer für Aus) beim PWM | ||
+ | - Wir müssen '' | ||
+ | - '' | ||
+ | - Und OCR1A setzen: '' | ||
+ | - Wichtig immer LED an Port bei Simulide! nicht nur auf die Animation vertrauen! | ||
+ | - Mit CS Clock select: kann es auch langsamer ausgegeben werden | ||
+ | - Ggf. auch Sound Code ansehen. | ||
+ | |||
+ | |||
+ | --> Ergebnisse: | ||
+ | - bitte immer eindeutige und konistente Namen in Ihrer Doku nutzen! | ||
+ | - Sonst werden nachfolgende Leser Probleme beim verstehen bekommen.. | ||
+ | |||
+ | |||
+ | ===== Einschub - Debugging ===== | ||
+ | |||
+ | Debugging Beispiel: DisplayAndTimer_v02 in ILIAS | ||
+ | |||
+ | kleine Änderungen: | ||
+ | * Variable '' | ||
+ | * Umbenennen der Variablen über '' | ||
+ | * Beispielhaft: | ||
+ | * Kompilieren und am Bildschirm den Output ansehen | ||
+ | * Problem: Zähler scheint nur zwischen 48 und 57 zu zählen! | ||
+ | |||
+ | Tipps | ||
+ | - **Tipp 1**: Verwenden von nicht genutzten Registern | ||
+ | - nach erstem '' | ||
+ | - nach zweiten'' | ||
+ | - In Simulide: MCU Monitor >> Blick auf die beiden Register | ||
+ | - Komisch: OutputStr verändert sich zwischen beiden! | ||
+ | - **Tipp 2**: Nur absolut notwendigen Code betrachten | ||
+ | - Code soweit auskommentieren wie es nur geht. | ||
+ | - **Tipp 3**: Im Fall von Deklarationen: | ||
+ | - Nach '' | ||
+ | - RAM Table über '' | ||
+ | - auf Byte PC umschalten | ||
+ | - Suchen der Speicherzelle | ||
+ | - Geschwindigkeit reduzieren | ||
+ | - **Tipp 4**: Logic Analyzer | ||
+ | - '' | ||
+ | - '' | ||
+ | - Logic analyzer beschreiben: | ||
+ | - Trigger in Logic Analyzer | ||
+ | - **Tipp 5**: Hyper-V | ||
+ | - Windows Eingabe: '' | ||
+ | - siehe: https:// | ||
+ | - Installation dauert einige Minuten | ||
+ | - Simulide in VM ist stabiler | ||
+ | - **Tipp 6**: Scope | ||
+ | - Tracks: Aufteilen des Bildschirms | ||
+ | - Trigger | ||
+ | - Auto | ||
+ | - **Tipp 7**: Scripted Modules | ||
+ | - Beispiel DAC | ||
+ | - im Komponentenexplorer: | ||
+ | - im Dateiexplorer: | ||
+ | - Alle Dateien anklicken --> nix passiert | ||
+ | - rechten Editorbereich in Simulide öffnen (" | ||
+ | - | ||
+ | - Known Problems | ||
+ | - Ampmeter only for DC! (about 10 Hz) | ||
+ | - FETs | ||
+ | - use Relays instead \\ Change | ||
+ | - Inductance: 1 nH | ||
+ | - Resistance to 1 mOhm | ||
+ | - IOn 100 mA | ||
+ | - IOff 50 mA | ||
+ | - Beispiel: Halbbrücke (auch als FET Variante ok) | ||
+ | - Alternative mit Relays | ||
+ | - Hier besser als Umschalter umzusetzen, da Kurzschluss im Zwischenstadium {{drawio> | ||
+ | |||
+ | ===== Interrupts und Zeitslots ===== | ||
+ | |||
+ | Wdh: | ||
+ | - Bisher: | ||
+ | - Ausgabe auf dem Display in while-Schleife "so schnell wie's geht" | ||
+ | - Counter TC1 läuft autonom und unabhängig vom Programmcode (nach Config) | ||
+ | - Counter kann unterschiedlich schnell laufen (prescaler) | ||
+ | - Counter kann auch Ausgabe antriggern | ||
+ | - Nun: | ||
+ | - welche Modi gibts? Was kann man noch mit dem Timer/ | ||
+ | - Anschauen der verschiedenen Modi: | ||
+ | - Normal: 0 ... 65535, und dann wieder Sprung auf 0 --> OC1A ändert sich nur bei max Wert | ||
+ | - Fast PWM: | ||
+ | - 0 ... max Wert, und dann wieder Sprung auf 0 --> OC1A bei TCNT>= OCR1A gleich 0, sonst 1 | ||
+ | - Fast PWM kann verschiedene max Werte haben: 255, 511, 1023, ICR1 und sogar OCR1A selbst | ||
+ | - Ansteigende Flanke immer bei 0 --> links bündig! | ||
+ | - PWM, phase correct | ||
+ | - 0 ... max Wert, und dann: max Wert ... 0 --> OC1A bei TCNT>= OCR1A gleich 0, sonst 1 | ||
+ | - halb so schnell weil doppelte Rampe | ||
+ | - mitten zentriert | ||
+ | - weitere Register des TC anschauen | ||
+ | - TCNT1H/ | ||
+ | - OCR1AH/ | ||
+ | - OCR1BH/ | ||
+ | - ICR1H/ | ||
+ | - erst TIFR1: | ||
+ | - zeigt Ereignisse an (über Flags): z.B. Vergleichswert ist erreicht, oder Maximalwert ist erreicht | ||
+ | - wenn ein Ereignis eintritt, dann kann ein Interrupt ausgelöst werden | ||
+ | - TIMSK1 : Ist eine Maske, die angibt, welcher Interrupt aktiv ist | ||
+ | - Mal Overflow Interrupt testen: | ||
+ | - bei Initialisierung: | ||
+ | - außerhalb von main: | ||
+ | - '' | ||
+ | - wir brauchen zumindest einen " | ||
+ | - woher bekommen? | ||
+ | - am besten da nachschauen, | ||
+ | - suchen nach vector | ||
+ | - '' | ||
+ | - Eingeben von '' | ||
+ | - '' | ||
+ | - was machen wir da drin? am besten z.B. Port B3 toggeln | ||
+ | - '' | ||
+ | - testen --> toggelt! | ||
+ | - Wie könnte man nun die Ausgabe nur alle paar Zentelsekunden ausführen lassen? | ||
+ | - Alle Zeilen in den Interrupt? --> bloß nicht! | ||
+ | - SW_Flag in ISR setzen und in main auswerten | ||
+ | - '' | ||
+ | - '' | ||
+ | - '' | ||
+ | - Geschwindigkeit zu langsam? | ||
+ | - statt '' | ||
+ | - Aber wie kommt man z.b. genau auf eine Millisekunde? | ||
+ | - Man nehme: | ||
+ | - Takt: 18.432 MHz | ||
+ | - 8-Bit Counter: zählt bis 256 (16 Bit geht nicht genau auf...) | ||
+ | - --> zählt 72' | ||
+ | - Prescaler von 8: zählt 8x so langsam, also nur 9'000 pro Sekunde und löst interrupt aus | ||
+ | - Im Interrupt von 9 herunterzählen: | ||
+ | - up-Down-Counter ansehen |