Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
| Beide Seiten der vorigen Revision Vorhergehende Überarbeitung Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
| microcontrollertechnik:6._wuerfel_und_zufall [2020/10/13 04:22] – tfischer | microcontrollertechnik:6_wuerfel_und_zufall [2024/11/13 01:04] (aktuell) – mexleadmin | ||
|---|---|---|---|
| Zeile 1: | Zeile 1: | ||
| - | ====== 6. Würfel und Zufall ====== | + | ====== 6 Würfel und Zufall ====== |
| ==== Ziele ==== | ==== Ziele ==== | ||
| Zeile 11: | Zeile 11: | ||
| --> I. Vorarbeiten # | --> I. Vorarbeiten # | ||
| - Laden Sie folgende Datei herunter: | - Laden Sie folgende Datei herunter: | ||
| - | - {{microcontrollertechnik: | + | - {{microcontrollertechnik: |
| - | - {{microcontrollertechnik: | + | - {{microcontrollertechnik: |
| - {{microcontrollertechnik: | - {{microcontrollertechnik: | ||
| Zeile 18: | Zeile 18: | ||
| --> II. Analyse des fertigen Programms # | --> II. Analyse des fertigen Programms # | ||
| - Initialisieren des Programms | - Initialisieren des Programms | ||
| - | - Öffnen Sie SimulIDE und öffnen Sie dort mittels {{microcontrollertechnik: | + | - Öffnen Sie SimulIDE und öffnen Sie dort mittels {{microcontrollertechnik: |
| - | - Laden Sie '' | + | - Laden Sie '' |
| - Zunächst wird eine Startanzeige mit dem Namen des Programms dargestellt. | - Zunächst wird eine Startanzeige mit dem Namen des Programms dargestellt. | ||
| - | - Als nächstes ist im Display ein Menu zu sehen. Durch Tastendruck ein Würfel gestartet (Druch auf Taste '' | + | - Als nächstes ist im Display ein Menu zu sehen. Durch Tastendruck |
| - Das Programm zu diesem Hexfile soll nun erstellt werden | - Das Programm zu diesem Hexfile soll nun erstellt werden | ||
| <-- | <-- | ||
| - | --> III. Eingabe in Atmel Studio # | + | --> III. Eingabe in Microchip |
| <WRAP group>< | <WRAP group>< | ||
| / | / | ||
| - | + | ||
| - | Experiment 6: | + | Experiment 6: |
| - | ============= ============================================== | + | ============= |
| - | + | ||
| - | Dateiname: MEXLEcast_de.c | + | Dateiname: |
| - | + | ||
| - | Autoren: Peter Blinzinger | + | Autoren: |
| - | Prof. G. Gruhler (Hochschule Heilbronn) | + | Prof. G. Gruhler (Hochschule Heilbronn) |
| - | D. Chilachava (Georgische Technische Universitaet) | + | D. Chilachava |
| - | + | ||
| - | Version: 1.2 vom 30.04.2020 | + | Version: |
| - | + | ||
| - | Hardware: MEXLE2020 Ver. 1.0 oder höher | + | Hardware: |
| - | AVR-USB-PROGI Ver. 2.0 | + | AVR-USB-PROGI Ver. 2.0 |
| - | + | ||
| - | Software: Entwicklungsumgebung: | + | Software: |
| - | C-Compiler: AVR/GNU C Compiler 5.4.0 | + | C-Compiler: AVR/GNU C Compiler 5.4.0 |
| - | + | ||
| - | Funktion: Es wird ein elektronischer Wuerfel mit Anzeige auf dem Display | + | Funktion: |
| - | realisiert. Mit zwei Tasten S1 = Start und S4 = Stop wird der | + | realisiert. Mit zwei Tasten S1 = Start und S4 = Stop wird der |
| - | Wuerfel gesteuert. Der Wuerfel wird mit 10ms-Takt gezaehlt. Die | + | Wuerfel gesteuert. Der Wuerfel wird mit 10ms-Takt gezaehlt. Die |
| - | Anzeige erfolgt als Ziffer im 100ms-Takt. | + | Anzeige erfolgt als Ziffer im 100ms-Takt. |
| - | + | ||
| - | Displayanzeige: | + | Displayanzeige: |
| - | +----------------+ +----------------+ | + | +----------------+ |
| - | |- Experiment 6 -| |Electronic Cast | | + | |- Experiment 6 -| |Electronic Cast | |
| - | |Electronic Cast | |Start | + | |Electronic Cast | |Start |
| - | +----------------+ +----------------+ | + | +----------------+ |
| - | + | ||
| - | Tastenfunktion: | + | Tastenfunktion: |
| - | S4: Stop (Reset-Funktion Flip-Flop) | + | S4: Stop (Reset-Funktion Flip-Flop) |
| - | + | ||
| - | Jumperstellung: | + | Jumperstellung: |
| - | + | ||
| - | Fuses im uC: CKDIV8: Aus (keine generelle Vorteilung des Takts) | + | Fuses im uC: CKDIV8: Aus (keine generelle Vorteilung des Takts) |
| - | + | ||
| - | Header-Files: | + | Header-Files: |
| + | |||
| =============================================================================*/ | =============================================================================*/ | ||
| + | |||
| // Deklarationen ============================================================== | // Deklarationen ============================================================== | ||
| + | |||
| // Festlegung der Quarzfrequenz | // Festlegung der Quarzfrequenz | ||
| - | #ifndef F_CPU // optional definieren | + | #ifndef F_CPU |
| - | #define F_CPU 12288000UL // MiniMEXLE | + | #define F_CPU 18432000UL |
| - | #endif | + | # |
| + | |||
| // Include von Header-Dateien | // Include von Header-Dateien | ||
| - | #include < | + | #include < |
| - | #include < | + | #include < |
| - | #include < | + | #include < |
| - | #include " | + | #include " |
| + | |||
| // Makros | // Makros | ||
| - | # | + | #define SET_BIT(BYTE, BIT) ((BYTE) |= (1 << (BIT))) // Bit Zustand in Byte setzen |
| - | #define CLR_BIT(PORT, BIT) ((PORT) &= ~(1 << (BIT))) // Port-Bit Loeschen | + | #define CLR_BIT(BYTE, BIT) ((BYTE) &= ~(1 << (BIT))) // Bit Zustand in Byte loeschen |
| - | #define TGL_BIT(PORT, BIT) ((PORT) ^= (1 << (BIT))) // Port-Bit Toggeln | + | #define TGL_BIT(BYTE, BIT) ((BYTE) ^= (1 << (BIT))) // Bit Zustand in Byte wechseln (toggle) |
| + | |||
| // Konstanten | // Konstanten | ||
| - | # | + | # |
| - | # | + | # |
| + | |||
| + | #define INPUT_PIN_MASK 0b00001111 | ||
| + | #define ASC_NULL 0x30 | ||
| // Variable | // Variable | ||
| - | unsigned char vorteiler = VORTEILER_WERT; // Zaehlvariable Vorteiler | + | unsigned char softwarePrescaler |
| - | unsigned char hundertstel = HUNDERTSTEL_WERT; // Zaehlvariable Hunderstel | + | unsigned char cycle10msCount |
| - | + | ||
| - | unsigned char castVar = 1; // Variable für Wuerfel-Zaehler | + | unsigned char castVar = 1; // Variable für Wuerfel-Zaehler |
| - | + | ||
| - | bool timertick; | + | bool cycle10msActive |
| - | bool takt10ms; // Bit-Botschaft alle 10ms | + | bool cycle100msActive = 0; // Bit-Botschaft alle 100ms |
| - | bool takt100ms; // Bit-Botschaft alle 100ms | + | |
| - | + | bool button1 | |
| - | bool sw1; // Bitspeicher fuer Taste 1 | + | bool button4 |
| - | bool sw4; // Bitspeicher fuer Taste 4 | + | bool castBit = 0; |
| - | bool castBit = 0; // Flip-Flop-Bit fuer Start/Stop | + | |
| + | uint8_t buttonState | ||
| // Funktionsprototypen | // Funktionsprototypen | ||
| - | void init_Taster(void); | + | void timerInt0(void); |
| - | void timerInt0(void); | + | void castCounting(void); |
| - | void castCounting(void); | + | void castDisplay(void); |
| - | void castDisplay(void); | + | void initDisplay(void); |
| - | void initDisplay(void); | + | |
| // Hauptprogramm ============================================================== | // Hauptprogramm ============================================================== | ||
| int main() | int main() | ||
| { | { | ||
| - | // Initialisierung | + | |
| - | init_Taster(); | + | initDisplay(); |
| - | initDisplay(); | + | |
| - | + | TCCR0A = 0; // Timer 0 auf " | |
| - | TCCR0A = 0; // Timer 0 auf " | + | TCCR0B |= (1<< |
| - | TCCR0B |= (1<< | + | TIMSK0 |= (1<< |
| - | TIMSK0 |= (1<< | + | |
| - | + | sei(); | |
| - | sei(); // generell Interrupts einschalten | + | |
| - | + | ||
| - | + | // Hauptprogrammschleife | |
| - | // Hauptprogrammschleife | + | |
| - | + | while(1) | |
| - | while(1) // unendliche Warteschleife | + | { |
| - | { | + | if (cycle10msActive) // alle 10ms: |
| - | if (takt10ms) // alle 10ms: | + | { |
| - | { | + | |
| - | takt10ms | + | castCounting(); |
| - | castCounting(); | + | } |
| - | + | if (cycle100msActive) | |
| - | } | + | { |
| - | if (takt100ms) // alle 100ms: | + | |
| - | { | + | castDisplay(); |
| - | takt100ms | + | } |
| - | castDisplay(); | + | } |
| - | } | + | return 0; |
| - | } | + | |
| - | return 0; | + | |
| } | } | ||
| + | |||
| // Interrupt-Routine ========================================================== | // Interrupt-Routine ========================================================== | ||
| ISR (TIMER0_OVF_vect) | ISR (TIMER0_OVF_vect) | ||
| /* In der Interrupt-Routine sind die Softwareteiler für die Taktbotschaften | /* In der Interrupt-Routine sind die Softwareteiler für die Taktbotschaften | ||
| - | | + | |
| - | + | ||
| - | | + | |
| - | hunderstel | + | hunderstel |
| - | + | ||
| - | | + | |
| - | takt100ms | + | takt100ms |
| */ | */ | ||
| { | { | ||
| - | timertick = 1; // Botschaft 0,111ms senden | + | --softwarePrescaler; // Vorteiler dekrementieren |
| - | --vorteiler; // Vorteiler dekrementieren | + | if (softwarePrescaler==0) // wenn 0 erreicht: 10ms abgelaufen |
| - | if (vorteiler==0) // wenn 0 erreicht: 10ms abgelaufen | + | |
| { | { | ||
| - | vorteiler | + | softwarePrescaler |
| - | takt10ms | + | cycle10msActive |
| - | --hundertstel; // | + | --cycle10msCount; // |
| - | + | ||
| - | if (hundertstel==0) // wenn 0 erreicht: 100ms abgelaufen | + | if (cycle10msCount==0) // wenn 0 erreicht: 100ms abgelaufen |
| { | { | ||
| - | hundertstel | + | cycle10msCount |
| - | takt100ms | + | cycle100msActive |
| } | } | ||
| } | } | ||
| } | } | ||
| - | // Taster initialisieren ======================================================= | + | |
| - | void init_Taster(void) | + | |
| - | { | + | |
| - | DDRB = DDRB & 0xE1; // Port B auf Eingabe schalten | + | |
| - | PORTB |= 0x1E; | + | |
| - | _delay_us(10); | + | |
| - | } | + | |
| // Wuerfelfunktion ============================================================ | // Wuerfelfunktion ============================================================ | ||
| void castCounting(void) | void castCounting(void) | ||
| { | { | ||
| - | // Einlesen der Tastensignale | + | DDRC = DDRC & |
| - | sw1 = (PINB & (1 << PB1)); | + | PORTC |= INPUT_PIN_MASK; |
| - | sw4 = (PINB & (1 << PB4)); | + | _delay_us(1); // Wartezeit Umstellung Hardware-Signal |
| - | + | buttonState | |
| - | // Auswertung der Tasten | + | DDRC |= INPUT_PIN_MASK; |
| - | if (sw1==0) // solange Taste 1 gedrueckt: | + | // Einlesen der Tastensignale |
| - | castBit = 1; // | + | button1 = (buttonState & (1 << PC0)); |
| - | + | button4 = (buttonState & (1 << PC3)); | |
| - | if (sw4==0) // solange Taste 4 gedrueckt: | + | |
| - | castBit = 0; // | + | // Auswertung der Tasten |
| - | + | ||
| - | if (castBit) // Solange Flip-Flop " | + | |
| - | { | + | castBit = 1; // Flip-Flop " |
| - | castVar++; // | + | |
| - | if (castVar> | + | if (button4==0) |
| - | castVar=1; // => auf 1 setzen | + | castBit = 0; // Flip-Flop " |
| - | } | + | |
| + | if (castBit) | ||
| + | { | ||
| + | castVar++; // Wurfelwert hochzaehlen im Takt 10ms | ||
| + | if (castVar> | ||
| + | castVar=1; // | ||
| + | } | ||
| } | } | ||
| + | |||
| // Anzeigefunktion Wuerfel ==================================================== | // Anzeigefunktion Wuerfel ==================================================== | ||
| void castDisplay(void) | void castDisplay(void) | ||
| { | { | ||
| - | lcd_gotoxy(1, | + | |
| - | lcd_putc(castVar+0x30); // ASCII-Wert des Wuerfelzaehlers ausgeben | + | lcd_putc(castVar+ASC_NULL); |
| } | } | ||
| + | |||
| // Initialisierung Display-Anzeige ============================================ | // Initialisierung Display-Anzeige ============================================ | ||
| - | void initDisplay() // Start der Funktion | + | void initDisplay() |
| { | { | ||
| - | lcd_init(); | + | |
| - | + | | |
| - | lcd_gotoxy(0, | + | lcd_gotoxy(0, |
| - | lcd_putstr(" | + | lcd_putstr(" |
| - | + | ||
| - | lcd_gotoxy(1, | + | lcd_gotoxy(1, |
| - | lcd_putstr(" | + | lcd_putstr(" |
| - | + | ||
| - | _delay_ms(2000); | + | _delay_ms(2000); |
| - | + | ||
| - | lcd_gotoxy(0, | + | lcd_gotoxy(0, |
| - | lcd_putstr(" | + | lcd_putstr(" |
| + | |||
| + | lcd_gotoxy(1, | ||
| + | lcd_putstr(" | ||
| + | } // Ende der Funktion | ||
| - | lcd_gotoxy(1, | ||
| - | lcd_putstr(" | ||
| - | } // Ende der Funktion | ||
| </ | </ | ||
| </ | </ | ||
| Zeile 244: | Zeile 244: | ||
| - Die Konstanten entsprechen denen der letzten Programme. \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ | - Die Konstanten entsprechen denen der letzten Programme. \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ | ||
| - Alle Variablen außer '' | - Alle Variablen außer '' | ||
| - | - Bei den Funktionsprototypen sind einige bekannte Unterprogramme vorhanden. Details werden weiter unten erklärt. \\ \\ \\ | + | - Bei den Funktionsprototypen sind einige bekannte Unterprogramme vorhanden. Details werden weiter unten erklärt. \\ \\ \\ \\ \\ |
| '' | '' | ||
| - | - Das Hauptprogramm ähnelt sehr stark dem [[4._up_down_counter|Up/Down Counter]]. | + | - Das Hauptprogramm ähnelt sehr stark dem [[4_up_down_counter|Up/Down Counter]]. |
| - Zunächst werden zwei Initialisierungsroutinen aufgerufen (siehe weiter unten) | - Zunächst werden zwei Initialisierungsroutinen aufgerufen (siehe weiter unten) | ||
| - Dann werden wieder die " | - Dann werden wieder die " | ||
| - Auch hier wird über die " | - Auch hier wird über die " | ||
| - Mit dem Befehl '' | - Mit dem Befehl '' | ||
| - | - In der Endlosschleife sind auf der ersten Ebene wieder nur If-Abfragen zu den Flags $10ms$ | + | - In der Endlosschleife sind auf der ersten Ebene wieder nur If-Abfragen zu den Flags '' |
| - | - Alle $10ms$ (bzw. wenn das entsprechende Flag gesetzt wird) wird das Flag zurückgesetzt und das Unterprogramm '' | + | - Alle $10~\rm ms$ (bzw. wenn das entsprechende Flag gesetzt wird) wird das Flag zurückgesetzt und das Unterprogramm '' |
| - | - Alle $100ms$ (bzw. wenn das entsprechende Flag gesetzt wird) wird das Flag zurückgesetzt und das Unterprogramm '' | + | - Alle $100~\rm ms$ (bzw. wenn das entsprechende Flag gesetzt wird) wird das Flag zurückgesetzt und das Unterprogramm '' |
| '' | '' | ||
| - | - Mit dem Befehl '' | + | - Mit dem Befehl '' |
| - | - Der Überlauf-Interrupt durch den Timer2 | + | - Der Überlauf-Interrupt durch den Timer0 |
| - | - Die Ermittlung von '' | + | - Die Ermittlung von '' |
| - | - Eine große Änderung ist, dass bereits im Interrupt alle 10ms die Unterfunktion '' | + | - Eine große Änderung ist, dass bereits im Interrupt alle 10ms die Unterfunktion '' |
| - | '' | + | |
| - | - Das Einstellen des Data Direction Registers und der Pullups wurde bereits in vorherigen Programmen erklärt. \\ \\ \\ | + | |
| - | '' | + | |
| \\ \\ \\ | \\ \\ \\ | ||
| - | | + | '' |
| - | - Neu hier ist, dass über '' | + | \\ \\ \\ \\ \\ |
| + | | ||
| + | - Neu hier ist, dass die Bedienung der Schalter nur das Flag '' | ||
| '' | '' | ||
| - | \\ \\ \\ \\ | + | - Hierüber wird die Augenzahl in der zweiten Zeile an Position 7 ausgegeben. |
| + | \\ \\ | ||
| '' | '' | ||
| Zeile 293: | Zeile 293: | ||
| - Darstellung des Augenwerts ändern | - Darstellung des Augenwerts ändern | ||
| - | - Laden Sie folgende Dateien herunter: {{microcontrollertechnik: | + | - Laden Sie folgende Dateien herunter: {{microcontrollertechnik: |
| - Simulieren Sie die Schaltung mit der beigefügten hex-Datei | - Simulieren Sie die Schaltung mit der beigefügten hex-Datei | ||
| - | - Ändern Sie das bisherige Programm so, dass Sie das gleiche Ergebnis erhalten. | + | - Ändern Sie das bisherige Programm so, dass Sie das gleiche Ergebnis erhalten, bzw. zumindest die Ansteuerung der LEDs. |
| <-- | <-- | ||
| - | |||