Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen Revision Vorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
microcontrollertechnik:7_uhr_und_zeitraster [2020/10/16 10:27]
tfischer
microcontrollertechnik:7_uhr_und_zeitraster [2024/01/22 13:46] (aktuell)
mexleadmin
Zeile 1: Zeile 1:
-====== 7Uhr und Zeitraster ======+====== 7 Uhr und Zeitraster ======
  
 ==== Ziele ==== ==== Ziele ====
Zeile 5: Zeile 5:
 Nach dieser Lektion sollten Sie: Nach dieser Lektion sollten Sie:
  
-  - wissen, wie man ....+  - wissen, wie man aus den auf Interupt-basierten Zeitrastern langsamere Raster umsetzt. 
 ==== Übung ==== ==== Übung ====
  
 --> I. Vorarbeiten # --> I. Vorarbeiten #
   - Laden Sie folgende Datei herunter:    - Laden Sie folgende Datei herunter: 
-    - {{microcontrollertechnik:7_mexleclock.simu}} +    - {{microcontrollertechnik:7._uhr_und_zeitraster.sim1}} 
-    - {{microcontrollertechnik:7_mexleclock.hex}}+    - {{microcontrollertechnik:7._uhr_und_zeitraster.hex}}
     - {{microcontrollertechnik:lcd_lib_de.h}}     - {{microcontrollertechnik:lcd_lib_de.h}}
  
Zeile 17: 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:simulide_open.jpg?25}} die Datei ''7_mexleclock.simu''  +    - Öffnen Sie SimulIDE und öffnen Sie dort mittels {{microcontrollertechnik:simulide_open.jpg?25}} die Datei ''7._uhr_und_zeitraster.sim1''  
-    - Laden Sie ''7_mexleclock.hex'' als firmware auf den 328 Chip+    - Laden Sie ''7._uhr_und_zeitraster.hex'' als firmware auf den 88 Chip
     - 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 eine Uhr mit dem Format HH:MM:SS Menu zu sehen     - Als nächstes ist im Display eine Uhr mit dem Format HH:MM:SS Menu zu sehen
Zeile 25: Zeile 26:
 <-- <--
  
---> III. Eingabe in Atmel Studio #+--> III. Eingabe in Microchip Studio #
 <WRAP group><WRAP column 40%><sxh c; first-line: 1> <WRAP group><WRAP column 40%><sxh c; first-line: 1>
-/* ============================================================================ 
  
-Experiment 7:  7_mexleclock mit Stunden-, Minuten- und Sekunden-Anzeige +/* ============================================================================ 
-============= ========================================================= +  
- +Experiment 7:   7_mexleclock mit Stunden-, Minuten- und Sekunden-Anzeige 
-Dateiname: 7_MexleClock.c +=============   ========================================================= 
- +  
-Autoren: Peter Blinzinger +Dateiname:      7_MexleClock.c 
- Prof. G. Gruhler (Hochschule Heilbronn) +  
- D. Chilachava  (Georgische Technische Universitaet) +Autoren:        Peter Blinzinger 
- +                Prof. G. Gruhler (Hochschule Heilbronn) 
-Version: 1.vom 01.05.2020 +                D. Chilachava    (Georgische Technische Universitaet) 
- +  
-Hardware: MEXLE2020 Ver. 1.0 oder höher +Version:        1.vom 22.10.2022 
- AVR-USB-PROGI Ver. 2.0 +  
- +Hardware:       MEXLE2020 Ver. 1.0 oder höher 
-Software: Entwicklungsumgebung: AtmelStudio 7.0 +                AVR-USB-PROGI Ver. 2.0 
- C-Compiler: AVR/GNU C Compiler 5.4.0 +  
- +Software:       Entwicklungsumgebung: AtmelStudio 7.0 
-Funktion: Digitaluhr mit Anzeige von Stunden, Minuten und Sekunden. Eine +                C-Compiler: AVR/GNU C Compiler 5.4.0 
- einfache Stellfunktion ist mit den Tasten S2 und S3 realisiert. +  
- +Funktion:       Digitaluhr mit Anzeige von Stunden, Minuten und Sekunden. Eine 
-Displayanzeige: Start (fuer 2s): Betrieb: +                einfache Stellfunktion ist mit den Tasten S2 und S3 realisiert. 
- +----------------+ +----------------+ +  
- |- Experiment 7 -| |=== 00:00:00 ===| +Displayanzeige: Start (fuer 2s):        Betrieb: 
- | Digital Clock  | |   Std Min      | +                +----------------+      +----------------+ 
- +----------------+ +----------------+ +                |- Experiment 7 -|      |=== 00:00:00 ===| 
- +                | Digital Clock  |      |   Std Min      | 
-Tastenfunktion: S2: Std (zaehlt Stunden bei Flanke aufwaerts. Überlauf bei 24) +                +----------------+      +----------------+ 
- S3: Min (zaehlt Minuten bei Flanke aufwaerts. Überlauf bei 60) +  
- (setzt Sekunden beim Druecken zurueck auf 00) +Tastenfunktion: S2: Std (zaehlt Stunden bei Flanke aufwaerts. Überlauf bei 24) 
- +                S3: Min (zaehlt Minuten bei Flanke aufwaerts. Überlauf bei 60) 
-Jumperstellung: keine Auswirkung +                        (setzt Sekunden beim Druecken zurueck auf 00) 
- +  
-Fuses im uC: CKDIV8: Aus (keine generelle Vorteilung des Takts) +Jumperstellung: keine Auswirkung 
- +  
-Header-Files: lcd_lib_de.h (Library zur Ansteuerung LCD-Display Ver. 1.3) +Fuses im uC:    CKDIV8: Aus (keine generelle Vorteilung des Takts) 
- +  
-Module: 1) Taktgenerator +Header-Files:   lcd_lib_de.h    (Library zur Ansteuerung LCD-Display Ver. 1.3) 
- 2) Zaehler fuer Uhr (Takt: 1 s) +  
- 3) Anzeigetreiber  (Takt: 100 ms) +Module:         1) Taktgenerator 
- 4) Stellfunktion   (Takt: 10 ms) +                2) Zaehler fuer Uhr (Takt: 1 s) 
- +                3) Anzeigetreiber   (Takt: 100 ms) 
- Modul 1: Das Modul "Taktgenerator" erzeugt den Takt von 1s fuer die Uhr. +                4) Stellfunktion    (Takt: 10 ms) 
-     Zusaetzliche Takte: 10 ms fuer Stellfunktion +  
-    100 ms fuer Anzeige. +    Modul 1:    Das Modul "Taktgenerator" erzeugt den Takt von 1s fuer die Uhr. 
- +                Zusaetzliche Takte: 10 ms fuer Stellfunktion 
- Verwendung von Hardware-Timer 0 und T0 Overflow-Interrupt. +                                   100 ms fuer Anzeige. 
-   Frequenzen: Quarzfrequenz      12,288 MHz. +  
-                   Timer-Vorteiler /  8 =>   1,536 MHz +                Verwendung von Hardware-Timer 0 und T0 Overflow-Interrupt. 
- Hardware-Timer     /256 =>   6 kHz / 166 µs +                Frequenzen: Quarzfrequenz                   12,288 MHz. 
-      Software-Vorteiler  / 60 => 100 Hz  /  10 ms +                            Timer-Vorteiler     /  8    =>   1,536 MHz 
-                 Hundertstel-Zaehler / 10 =>  10 Hz  / 100 ms +                            Hardware-Timer      /256    =>   6 kHz / 166 µs 
- Zehntel-Zaehler / 10 =>   1 Hz  /   1 s +                            Software-Vorteiler  / 60    => 100 Hz  /  10 ms 
- +                            Hundertstel-Zaehler / 10    =>  10 Hz  / 100 ms 
- Modul 2:  Das Modul "Zaehler fuer Uhr" wird durch den Takt 1s aufgerufen. +                            Zehntel-Zaehler     / 10    =>   1 Hz  /   1 s 
-     Sekunden, Minuten und Stunden werden als Binaerzahlen gezaehlt +  
-     Sekunden und Minuten zaehlen 00..59, die Stunden 00..23. +    Modul 2:    Das Modul "Zaehler fuer Uhr" wird durch den Takt 1s aufgerufen. 
-     Ein "Tick" auf dem Lautsprecher wird jede Sekunde ausgegeben. +                Sekunden, Minuten und Stunden werden als Binaerzahlen gezaehlt 
- +                Sekunden und Minuten zaehlen 00..59, die Stunden 00..23. 
-  Modul 3: Das Modul "Anzeigetreiber" startet alle 100 ms. Es gibt die +                Ein "Tick" auf dem Lautsprecher wird jede Sekunde ausgegeben. 
-     Hintergrundinformationen und die aktuelle Uhrzeit aus. +  
-   Darstellung auf der Anzeige (mittig in Zeile 1):  [23:59:59] +    Modul 3:    Das Modul "Anzeigetreiber" startet alle 100 ms. Es gibt die 
-  +                Hintergrundinformationen und die aktuelle Uhrzeit aus. 
-  Modul 4:  Das Modul "Stellfunktion" ist an den 10 ms-Takt gekoppelt. +                Darstellung auf der Anzeige (mittig in Zeile 1):  [23:59:59] 
-     Es dient  1. zum Einlesen und Entprellen der Stelltasten +      
-    - Auswertung der fallenden Flanke 1=> 0 +    Modul 4:    Das Modul "Stellfunktion" ist an den 10 ms-Takt gekoppelt. 
- 2. zum Ausfuehren der Stellfunktion: +                Es dient    1. zum Einlesen und Entprellen der Stelltasten 
-         - S2 zaehlt die Stunden aufwaerts +                               - Auswertung der fallenden Flanke 1=> 0 
-        - S3 zaehlt die Minuten aufwaerts +                            2. zum Ausfuehren der Stellfunktion: 
-        - solange Taste S3 gedrueckt: Sekunden = 00 +                               - S2 zaehlt die Stunden aufwaerts 
-   (einfache Synchronisierung der Uhr!)  +                               - S3 zaehlt die Minuten aufwaerts 
-    Beim Stellen kein Uebertrag von den Minuten auf die Stunden. +                               - solange Taste S3 gedrueckt: Sekunden = 00 
 +                                (einfache Synchronisierung der Uhr!)  
 +                Beim Stellen kein Uebertrag von den Minuten auf die Stunden.  
 +   
 +    Die Kopplung der Module wird ueber global definierte Variable realisiert: 
 +  
 +    1-Bit-Variable:     takt10ms:   Taktgenerator => Stellfunktion 
 +                        takt100ms:  Taktgenerator => Anzeigetreiber 
 +                        takt1s:     Taktgenerator => Zaehler fuer Uhr 
 +  
 +    8-Bit-Variable:     sekunden    Stellfunktion => Zaehler => Anzeige 
 +                        minuten 
 +                        stunden
    
- Die Kopplung der Module wird ueber global definierte Variable realisiert: 
- 
-  1-Bit-Variable: takt10ms: Taktgenerator => Stellfunktion 
- takt100ms: Taktgenerator => Anzeigetreiber 
- takt1s: Taktgenerator => Zaehler fuer Uhr 
- 
- 8-Bit-Variable: sekunden Stellfunktion => Zaehler => Anzeige 
- minuten 
- stunden 
- 
 =============================================================================*/ =============================================================================*/
 + 
 // Deklarationen ============================================================== // Deklarationen ==============================================================
 + 
 // Festlegung der Quarzfrequenz // Festlegung der Quarzfrequenz
-#ifndef F_CPU // optional definieren +#ifndef F_CPU                   // optional definieren 
-#define F_CPU 12288000UL // ATmega 328 mit 12,288 MHz Quarz +#define F_CPU 18432000UL        // ATmega 88 mit 18,432 MHz Quarz 
-#endif  +#endif                               
 + 
 // Include von Header-Dateien // Include von Header-Dateien
-#include <avr/io.h> // I/O-Konfiguration (intern weitere Dateien) +#include <avr/io.h>               // I/O-Konfiguration (intern weitere Dateien) 
-#include <avr/interrupt.h> // Definition von Interrupts +#include <avr/interrupt.h>        // Definition von Interrupts 
-#include <util/delay.h> // Definition von Delays (Wartezeiten) +#include <util/delay.h>           // Definition von Delays (Wartezeiten) 
-#include "lcd_lib_de.h" // Header-Datei fuer LCD-Anzeige +#include "lcd_lib_de.h"         // Header-Datei fuer LCD-Anzeige 
 + 
 // Makros // Makros
-#define SET_BIT(PORT, BIT) ((PORT) |=  (1 << (BIT))) // Port-Bit Setzen +#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 VORTEILER_WERT 60 // Faktor Vorteiler = 90 +#define PRESCALER_VAL 90      // Faktor Vorteiler = 90 
-#define HUNDERTSTEL_WERT  10   // Faktor Hundertstel = 10 +#define CYCLE10MS_MAX 10      // Faktor Hundertstel = 10 
-#define ZEHNTEL_WERT 10   // Faktor Zehntel = 10 +#define CYCLE100MS_MAX      10      // Faktor Zehntel = 10 
- +  
-#define SPEAK_PORT PORTD // Port-Adresse fuer Lautsprecher +#define SPEAK_PORT          PORTD   // Port-Adresse fuer Lautsprecher 
-#define SPEAK_BIT 5 // Port-Bit fuer Lautsprecher +#define SPEAK_BIT                 // Port-Bit fuer Lautsprecher 
 + 
 #define ASC_NULL            0x30        // Das Zeichen '0' in ASCII #define ASC_NULL            0x30        // Das Zeichen '0' in ASCII
 #define ASC_COLON           0x3A        // Das Zeichen ':' in ASCII #define ASC_COLON           0x3A        // Das Zeichen ':' in ASCII
 +#define INPUT_PIN_MASK 0b00001111 
 + 
 // Variable // Variable
-unsigned char vorteiler VORTEILER_WERT; // Zaehlvariable Vorteiler +unsigned char softwarePrescaler PRESCALER_VAL; // Zaehlvariable Vorteiler 
-unsigned char hundertstel HUNDERTSTEL_WERT; // Zaehlvariable Hundertstel +unsigned char cycle10msCount CYCLE10MS_MAX; // Zaehlvariable Hundertstel 
-unsigned char zehntel ZEHNTEL_WERT; // Zaehlvariable Zehntel +unsigned char cycle100msCount   CYCLE100MS_MAX  // Zaehlvariable Zehntel 
-unsigned char sekunden  = 56; // Variable Sekunden +unsigned char seconds = 56; // Variable Sekunden 
-unsigned char minuten  = 34; // Variable Minuten +unsigned char minutes = 34; // Variable Minuten 
-unsigned char stunden = 12; // Variable Stunden +unsigned char hours = 12; // Variable Stunden 
- +  
-bool timertick; // Bit-Botschaft alle 0,166ms (bei Timer-Interrupt) +bool timertick; // Bit-Botschaft alle 0,166ms (bei Timer-Interrupt) 
-bool takt10ms; // Bit-Botschaft alle 10ms +bool cycle10msActive              // Bit-Botschaft alle 10ms 
-bool takt100ms; // Bit-Botschaft alle 100ms +bool cycle100msActive             // Bit-Botschaft alle 100ms 
-bool takt1s; // Bit-Botschaft alle 1s +bool cycle1sActive                // Bit-Botschaft alle 1s 
- +  
-bool sw2_neu = 1; // Bitspeicher fuer Taste 2 +bool button2_new = 1;               // Bitspeicher fuer Taste 2 
-bool sw3_neu = 1; // Bitspeicher fuer Taste 3 +bool button3_new = 1;               // Bitspeicher fuer Taste 3 
-bool sw2_alt = 1; // alter Wert von Taste 2 +bool button2_old = 1;               // alter Wert von Taste 2 
-bool sw3_alt = 1; // alter Wert von Taste 3+bool button3_old = 1;               // alter Wert von Taste 3
  
 +uint8_t buttonState    = 0b00001111; // Bitspeicher fuer Tasten
 + 
 // Funktionsprototypen // Funktionsprototypen
-void init_Taster(void); //Taster initialisieren +void initDisplay(void); // Init Anzeige 
-void uhrStellen(void); // Stellfunktion +void setTime(void); // Stellfunktion 
-void uhrAnzeigen(void); // Anzeigefunktion +void showTime(void); // Anzeigefunktion 
-void uhrZaehlen(void); // Uhrfunktion +void refreshTime(void); // Uhrfunktion 
-void initDisplay(void); // Init Anzeige + 
 // Hauptprogramm ============================================================== // Hauptprogramm ==============================================================
 int main() int main()
 { {
- // Initialisierung +    // Initialisierung 
- init_Taster(); //Taster initialisieren +    initDisplay();              // Initialisierung LCD-Anzeige 
- initDisplay(); // Initialisierung LCD-Anzeige +  
- +    TCCR0A = 0;                 // Timer 0 auf "Normal Mode" schalten 
- TCCR0A = 0; // Timer 0 auf "Normal Mode" schalten +    SET_BIT(TCCR0B, CS01);      // mit Prescaler /8 betreiben 
- SET_BIT(TCCR0B, CS01); // mit Prescaler /8 betreiben +    SET_BIT(TIMSK0, TOIE0);     // Overflow-Interrupt aktivieren 
- SET_BIT(TIMSK0, TOIE0); // Overflow-Interrupt aktivieren +  
- +    SET_BIT(DDRD, SPEAK_BIT);   // Speaker-Bit auf Ausgabe 
- SET_BIT(DDRD, SPEAK_BIT); // Speaker-Bit auf Ausgabe +  
- +    sei();                      // generell Interrupts einschalten 
- sei(); // generell Interrupts einschalten +  
- +    // Hauptprogrammschleife 
- // Hauptprogrammschleife +  
- +    while(1)                    // unendliche Warteschleife mit Aufruf der 
- while(1) // unendliche Warteschleife mit Aufruf der +                                // Funktionen abhaengig von Taktbotschaften 
- // Funktionen abhaengig von Taktbotschaften +    
-+        if (cycle10msActive          // alle 10ms: 
- if (takt10ms) // alle 10ms: +        
- +            cycle10msActive = 0;       //      Botschaft "10ms" loeschen 
- takt10ms = 0; // Botschaft "10ms" loeschen +            setTime();       //      Tasten abfragen, Uhr stellen 
- uhrStellen(); // Tasten abfragen, Uhr stellen +        
- +        if (cycle100msActive         // alle 100ms:  
- if (takt100ms) // alle 100ms:  +        
- +            cycle100msActive = 0;      //      Botschaft "100ms" loeschen 
- takt100ms = 0; // Botschaft "100ms" loeschen +            showTime();      //      Uhrzeit auf Anzeige ausgeben 
- uhrAnzeigen(); // Uhrzeit auf Anzeige ausgeben +        
- +        if (cycle1sActive            // alle Sekunden:  
-  if (takt1s) // alle Sekunden:  +        
- +            cycle1sActive = 0;         //      Botschaft "1s" loeschen 
- takt1s = 0; // Botschaft "1s" loeschen +            refreshTime();       //      Uhr weiterzaehlen 
- uhrZaehlen(); // Uhr weiterzaehlen +        
- +    
-+    return 0;
- return 0;+
 } }
 + 
 +// Interrupt-Routine ==========================================================
  
-// Interrupt-Routine ========================================================== 
 ISR (TIMER0_OVF_vect) ISR (TIMER0_OVF_vect)
-/*  In der Interrupt-Routine sind die Softwareteiler realisiert, die die Takt- +/*  In der Interrupt-Routine sind die Softwareteiler realisiert, die die Takt- 
- botschaften (10ms, 100ms, 1s) fuer die gesamte Uhr erzeugen. Die Interrupts +    botschaften (10ms, 100ms, 1s) fuer die gesamte Uhr erzeugen. Die Interrupts 
- werden von Timer 0 ausgeloest (Interrupt Nr. 1) +    werden von Timer 0 ausgeloest (Interrupt Nr. 1) 
- + 
- Veraenderte Variable: vorteiler +
-   hunderstel +
-   zehntel +
- +
- Ausgangsvariable:   takt10ms +
-   takt100ms +
-   takt1s+
 */ */
 { {
- timertick = 1; // Botschaft 0,166ms senden +    timertick = 1;                  // Botschaft 0,166ms senden 
- --vorteiler; // Vorteiler dekrementieren +    --softwarePrescaler                   // Vorteiler dekrementieren 
- if (vorteiler==0) // wenn 0 erreicht: 10ms abgelaufen +    if (softwarePrescaler==0)               // wenn 0 erreicht: 10ms abgelaufen 
-+    
- vorteiler VORTEILER_WERT; //    Vorteiler auf Startwert +        softwarePrescaler PRESCALER_VAL; //    Vorteiler auf Startwert 
- takt10ms = 1; //    Botschaft 10ms senden +        cycle10msActive = 1;               //    Botschaft 10ms senden 
- --hundertstel; //    Hunderstelzaehler dekrementieren +        --cycle10msCount             //    Hunderstelzaehler dekrementieren 
- +  
- if (hundertstel==0) // wenn 0 erreicht: 100ms abgelaufen +        if (cycle10msCount==0)         // wenn 0 erreicht: 100ms abgelaufen 
- +        
- hundertstel HUNDERTSTEL_WERT; // Teiler auf Startwert +            cycle10msCount CYCLE10MS_MAX; // Teiler auf Startwert 
- takt100ms = 1; //    Botschaft 100ms senden +            cycle100msActive = 1;          //    Botschaft 100ms senden 
- --zehntel; //    Zehntelzaehler dekrementieren +            --cycle100msCount             //    Zehntelzaehler dekrementieren 
- +  
- if (zehntel==0) // wenn 0 erreicht: 1s abgelaufen +            if (cycle100msCount==0)         // wenn 0 erreicht: 1s abgelaufen 
- +            
- zehntel ZEHNTEL_WERT; //    Teiler auf Startwert +                cycle100msCount CYCLE100MS_MAX; //    Teiler auf Startwert 
- takt1s = 1; //    Botschaft 1s senden +                cycle1sActive = 1;             //    Botschaft 1s senden 
- +            
- +        
- }+    }
 } }
- +  
-// Taster initialisieren ======================================================= +
-void init_Taster(void) +
-+
- DDRB = DDRB & 0xE1; // Port B auf Eingabe schalten +
- PORTB |= 0x1E; // Pullup-Rs eingeschaltet +
- _delay_us(10); // Wartezeit Umstellung Hardware-Signal +
-+
 // Stellfunktion ============================================================== // Stellfunktion ==============================================================
-void uhrStellen(void) +void setTime(void) 
-/*  Die Stellfunktion der Uhr wird alle 10ms aufgerufen. Dadurch wir eine +/*  Die Stellfunktion der Uhr wird alle 10ms aufgerufen. Dadurch wir eine 
-  Entprellung der Tastensignale realisiert. Das Stellen wir bei einer  +    Entprellung der Tastensignale realisiert. Das Stellen wir bei einer  
-  fallenden Flanke des jeweiligen Tastensignals durchgefuehrt. Darum  +    fallenden Flanke des jeweiligen Tastensignals durchgefuehrt. Darum  
-  muss fuer einen weiteren Stellschritt die Taste erneut betaetigt werden. +    muss fuer einen weiteren Stellschritt die Taste erneut betaetigt werden. 
- +  
-  Eine Flanke wird durch (alter Wert == 1) UND (aktueller Wert == 0) erkannt. +    Eine Flanke wird durch (alter Wert == 1) UND (aktueller Wert == 0) erkannt. 
- +  
-  Mit der Taste S2 werden die Stunden aufwaerts gestellt. +    Mit der Taste S2 werden die Stunden aufwaerts gestellt. 
-  Mit der Taste S3 werden die Minuten aufwaerts gestellt (kein Uebertrag) +    Mit der Taste S3 werden die Minuten aufwaerts gestellt (kein Uebertrag) 
-  Solange Taste S3 gedrueckt ist werden die Sekunden auf 00 gehalten +    Solange Taste S3 gedrueckt ist werden die Sekunden auf 00 gehalten 
- +  
-  Veraenderte Variable: stunden +    Veraenderte Variable: stunden 
-   minuten +                          minuten 
-   sekunden +                          sekunden 
- +  
-  Speicher fuer Bits:   sw2Alt +    Speicher fuer Bits:   sw2Alt 
-   sw3Alt+                          sw3Alt
 */ */
 { {
- sw2_neu (PINB & (1 << PB2)); // Tasten von Port einlesen + DDRC DDRC &~INPUT_PIN_MASK; // Port B auf Eingabe schalten 
- sw3_neu = (PINB (1 << PB3));+ PORTC |=   INPUT_PIN_MASK; // Pullup-Rs eingeschaltet 
 + _delay_us(1); // Wartezeit Umstellung Hardware-Signal 
 + buttonState    = (PINC INPUT_PIN_MASK) ; // Hole den Schalterstatus von B1..B4, 0b1 ist hier offener SChalter 
 + DDRC |= INPUT_PIN_MASK; // Port B auf Ausgabe schalten
  
- if ((sw2_neu==0)&(sw2_alt==1)) // wenn Taste 2 eben gedrueckt wurde: +    // Einlesen der Tastensignale    
-+    button2_new = (buttonState & (1 << PC1)); 
- stunden++; //    Stunden hochzaehlen, Ueberlauf bei 23 +    button3_new = (buttonState & (1 << PC2)); 
- if (stunden==24) +      
- stunden = 00; +  
-+    if ((button2_new==0)&(button2_old==1))  // wenn Taste 2 eben gedrueckt wurde: 
- if ((sw3_neu==0)&(sw3_alt==1)) // wenn Taste 3 eben gedrueckt wurde: +    
-+        hours++;                  //    Stunden hochzaehlen, Ueberlauf bei 23 
- minuten++; //    Minuten hochzaehlen, Ueberlauf bei 59 +        if (hours==24) 
- if (minuten==60) +            hours = 00; 
- minuten = 00; +    
-+    if ((button3_new==0)&(button3_old==1))  // wenn Taste 3 eben gedrueckt wurde: 
- if (sw3_neu==0) // solange Taste 3 gedrueckt:  +    
- sekunden = 00; //    Sekunden auf 00 setzen +        minutes++;                  //    Minuten hochzaehlen, Ueberlauf bei 59 
- +        if (minutes==60) 
- sw2_alt sw2_neu; // aktuelle Tastenwerte speichern +            minutes = 00; 
- sw3_alt sw3_neu; //    in Variable fuer alte Werte+    
 +    if (button3_new==0)                 // solange Taste 3 gedrueckt:  
 +        seconds = 00;              //    Sekunden auf 00 setzen 
 +  
 +    button2_old button2_new             // aktuelle Tastenwerte speichern 
 +    button3_old button3_new             //    in Variable fuer alte Werte
 } }
 + 
 // Anzeigefunktion Uhr ======================================================== // Anzeigefunktion Uhr ========================================================
-void uhrAnzeigen(void) +void showTime(void) 
-/* Die Umrechnung der binaeren Zaehlwerte auf BCD ist folgendermaßen geloest:  +/*  Die Umrechnung der binaeren Zaehlwerte auf BCD ist folgendermaßen geloest:  
- Zehner: einfache Integer-Teilung (/10) +    Zehner: einfache Integer-Teilung (/10) 
- Einer:  Modulo-Ermittlung (%10), d.h. Rest bei der Teilung durch 10+    Einer:  Modulo-Ermittlung (%10), d.h. Rest bei der Teilung durch 10
 */ */
 { {
- lcd_gotoxy(0,4);                    // Cursor auf Start der Zeitausgabe setzen +    lcd_gotoxy(0,4);                    // Cursor auf Start der Zeitausgabe setzen 
-  +      
- lcd_putc(ASC_NULL + stunden/10);    // Stunden Zehner als ASCII ausgeben +    lcd_putc(ASC_NULL + hours/10);    // Stunden Zehner als ASCII ausgeben 
- lcd_putc(ASC_NULL + stunden%10);    // Stunden Einer als ASCII ausgeben +    lcd_putc(ASC_NULL + hours%10);    // Stunden Einer als ASCII ausgeben 
- lcd_putc(ASC_COLON);                // Doppelpunkt ausgeben +    lcd_putc(ASC_COLON);                // Doppelpunkt ausgeben 
-  +      
- lcd_putc(ASC_NULL + minuten/10);    // Minuten als ASCII ausgeben +    lcd_putc(ASC_NULL + minutes/10);    // Minuten als ASCII ausgeben 
- lcd_putc(ASC_NULL + minuten%10);    // +    lcd_putc(ASC_NULL + minutes%10);    // 
- lcd_putc(ASC_COLON);                // Doppelpunkt ausgeben +    lcd_putc(ASC_COLON);                // Doppelpunkt ausgeben 
-  +      
- lcd_putc(ASC_NULL + sekunden/10);   // Sekunden als ASCII ausgeben +    lcd_putc(ASC_NULL + seconds/10);   // Sekunden als ASCII ausgeben 
- lcd_putc(ASC_NULL + sekunden%10);   //+    lcd_putc(ASC_NULL + seconds%10);   //
 } }
 + 
 // Initialisierung Display-Anzeige ============================================ // Initialisierung Display-Anzeige ============================================
-void initDisplay() // Start der Funktion+void initDisplay()              // Start der Funktion
 { {
- lcd_init(); // Initialisierungsroutine aus der lcd_lib +    lcd_init();                 // Initialisierungsroutine aus der lcd_lib 
-  +                      
- lcd_gotoxy(0,0);         // Cursor auf 1. Zeile, 1. Zeichen +    lcd_gotoxy(0,0);                // Cursor auf 1. Zeile, 1. Zeichen 
- lcd_putstr("- Experiment 7 -"); // Ausgabe Festtext: 16 Zeichen +    lcd_putstr("- Experiment 7 -"); // Ausgabe Festtext: 16 Zeichen 
- +  
- lcd_gotoxy(1,0);         // Cursor auf 2. Zeile, 1. Zeichen +    lcd_gotoxy(1,0);                // Cursor auf 2. Zeile, 1. Zeichen 
- lcd_putstr(" Digital Clock  "); // Ausgabe Festtext: 16 Zeichen +    lcd_putstr(" Digital Clock  "); // Ausgabe Festtext: 16 Zeichen 
- +  
- _delay_ms(2000); // Wartezeit nach Initialisierung +    _delay_ms(2000);            // Wartezeit nach Initialisierung 
- +  
- lcd_gotoxy(0,0);         // Cursor auf 1. Zeile, 1. Zeichen +    lcd_gotoxy(0,0);                // Cursor auf 1. Zeile, 1. Zeichen 
- lcd_putstr("=== 00:00:00 ==="); // Ausgabe Festtext: 16 Zeichen +    lcd_putstr("=== 00:00:00 ==="); // Ausgabe Festtext: 16 Zeichen 
- +  
- lcd_gotoxy(1,0);         // Cursor auf 2. Zeile, 1. Zeichen +    lcd_gotoxy(1,0);                // Cursor auf 2. Zeile, 1. Zeichen 
- lcd_putstr("   Std Min      "); // Ausgabe Festtext: 16 Zeichen +    lcd_putstr("   Std Min      "); // Ausgabe Festtext: 16 Zeichen 
-} // Ende der Funktion +                              // Ende der Funktion 
 + 
 // Zaehlfunktion Uhr ========================================================== // Zaehlfunktion Uhr ==========================================================
-void uhrZaehlen (void) // wird jede Sekunde gestartet +void refreshTime (void)              // wird jede Sekunde gestartet 
-/* Die Uhr wird im Sekundentakt gezaehlt. Bei jedem Aufruf wird auch ein  +/*  Die Uhr wird im Sekundentakt gezaehlt. Bei jedem Aufruf wird auch ein  
- "Tick" auf dem Lautsprecher ausgegeben. Ueberlaeufe der Sekunden zaehlen +    "Tick" auf dem Lautsprecher ausgegeben. Ueberlaeufe der Sekunden zaehlen 
- die Minuten, die Ueberlaeufe der Minuten die Stunden hoch. +    die Minuten, die Ueberlaeufe der Minuten die Stunden hoch. 
- +  
- Veraenderte Variable: sekunden +    Veraenderte Variable:   sekunden 
- minuten +                            minuten 
- stunden+                            stunden
 */ */
 { {
- TGL_BIT (SPEAK_PORT, SPEAK_BIT); // "Tick" auf Lautsprecher ausgeben +    TGL_BIT (SPEAK_PORT, SPEAK_BIT); // "Tick" auf Lautsprecher ausgeben 
- // durch Invertierung des Portbits +                                    // durch Invertierung des Portbits 
- +  
- sekunden++; // Sekunden hochzaehlen +    seconds++;                     // Sekunden hochzaehlen 
- if (sekunden==60) // bei Überlauf: +    if (seconds==60)               // bei Überlauf: 
-+    
- sekunden = 0; //  Sekunden auf 00 setzen +        seconds = 0;               //  Sekunden auf 00 setzen 
- minuten++; //  Minuten hochzaehlen +        minutes++;                  //  Minuten hochzaehlen 
- if (minuten==60) // bei Ueberlauf: +        if (minutes==60)            //  bei Ueberlauf: 
- +        
- minuten = 0; // Minuten auf 00 setzen +            minutes = 0;            //  Minuten auf 00 setzen 
- stunden++; // Stunden hochzaehlen +            hours++;              //  Stunden hochzaehlen 
- if (stunden==24) // bei Ueberlauf: +            if (hours==24)        //  bei Ueberlauf: 
- stunden = 0; // Stunden auf 00 setzen +                hours = 0;        //  Stunden auf 00 setzen 
- +        
-+    
-}</sxh>+} 
 +</sxh>
 </WRAP><WRAP column 55%> </WRAP><WRAP column 55%>
  
Zeile 377: Zeile 375:
   - Bei den Variablen entsprechen einige denen der letzten Programme.   - Bei den Variablen entsprechen einige denen der letzten Programme.
   - Für die Uhr werden Stunden, Minuten, Sekunden und Zehntelsekunden mit Anfangswerten deklariert. \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\   - Für die Uhr werden Stunden, Minuten, Sekunden und Zehntelsekunden mit Anfangswerten deklariert. \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\
-  - 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. \\ \\ \\ \\ \\
  
 ''Hauptprogramm ========================='' ''Hauptprogramm =========================''
  
-  - Das Hauptprogramm ähnelt sehr stark dem [[4._up_down_counter|Up/Down Counter]]. Entsprechend werden die Zeilen 143-157 hier nicht weiter erklärt. \\ \\ \\ \\ \\ \\ \\ \\ \\ \\+  - Das Hauptprogramm ähnelt sehr stark dem [[4_up_down_counter|Up/Down Counter]]. Entsprechend werden die Zeilen 143-157 hier nicht weiter erklärt. \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ 
   - In der Endlosschleife sind auf der ersten Ebene wieder nur If-Abfragen zu den Flags ''takt10ms'' und ''takt100ms'' zu finden. \\ \\   - In der Endlosschleife sind auf der ersten Ebene wieder nur If-Abfragen zu den Flags ''takt10ms'' und ''takt100ms'' zu finden. \\ \\
-    - Alle $10ms$ (bzw. wenn das entsprechende Flag gesetzt wird) wird das Flag zurückgesetzt und das Unterprogramm ''uhrStellen()'' aufgerufen \\ \\ \\  +    - Alle $10~\rm ms$ (bzw. wenn das entsprechende Flag gesetzt wird) wird das Flag zurückgesetzt und das Unterprogramm ''uhrStellen()'' aufgerufen \\ \\ \\  
-    - Alle $100ms$ (bzw. wenn das entsprechende Flag gesetzt wird) wird das Flag zurückgesetzt und das Unterprogramm ''uhrAnzeigen()'' aufgerufen \\ \\ \\  +    - Alle $100~\rm ms$ (bzw. wenn das entsprechende Flag gesetzt wird) wird das Flag zurückgesetzt und das Unterprogramm ''uhrAnzeigen()'' aufgerufen \\ \\ \\  
-    - Alle $1s$ (bzw. wenn das entsprechende Flag gesetzt wird) wird das Flag zurückgesetzt und das Unterprogramm ''uhrZaehlen()'' aufgerufen \\ \\ \\ \\  +    - Alle $1~\rm s$ (bzw. wenn das entsprechende Flag gesetzt wird) wird das Flag zurückgesetzt und das Unterprogramm ''uhrZaehlen()'' aufgerufen \\ \\ \\ \\ 
 ''Interrupt Routine ========================='' ''Interrupt Routine =========================''
-  - Mit dem Befehl ''ISR()'' wird eine Interrupt Service Routine für den  __OV__er__F__low Interrupt für __TIMER0__ angelegt.  +  - Auch die Interrupt Routine ist dem Programm [[4_up_down_counter|Up/Down Counter]] entlehnt und wird hier nicht weiter erklärt. \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ 
-  - Der Überlauf-Interrupt durch den Timer0 wird erst bei Überlauf des 8-Bit Wert ausgeführt. Auch hier ergibt sich durch den Prescaler und Modus (''TCCR0A'' und ''TCCR0B'') eine Periode von $T_{ISR}= 0,16\bar{6}ms$. + 
-  - Die Ermittlung von ''Timertick'', ''vorteiler'', ''takt10ms'', ''hundertstel'' und ''takt100ms'' ist hier wieder gleich dem im [[4._up_down_counter|Up/Down Counter]].  +'' Stellfunktion ==============''
-  - Eine große Änderung ist, dass bereits im Interrupt alle 10ms die Unterfunktion ''readButton()'' aufgerufen wird.  \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\  +
-''Taster initialisieren =============='' +
-  - Das Einstellen des Data Direction Registers und der Pullups wurde bereits in vorherigen Programmen erklärt. \\ \\ \\ +
-'' Funktion Tasten einlesen ==============''+
 \\ \\ \\ \\
-  - In dieser Funktion werden zunächst die Stellungen aller Taster eingelesen (vgl. ''counterCounting(void)'' bei [[4._up_down_counter|Up/down Counter]]). \\ \\ \\ +  - In dieser Funktion werden zunächst die Stellungen aller Taster eingelesen (vgl. ''counterCounting(void)'' bei [[4_up_down_counter|Up/down Counter]]). \\ \\ \\ 
-  - Neu hier ist, dass die Bedienung der Schalter nur das Flag ''castBit'' setzen. Falls dieses gesetzt ist, wird die Variable ''castVar'' hochgezählt. Falls diese 6 überschreitet wird sie auf 1 zurückgesetzt.  \\ \\ \\ \\ \\ \\ \\ \\ \\+  - Neu hier ist, dass die Bedienung der Schalter die Variablen für Stunden, Minuten um eins hochsetzen, bzw. bei Überlauf wider zurück auf 0 setzen. Zusätzlich wird bei eine Änderung des Minuten-Werts der Sekunden-Wert auf 0 gesetzt.  \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\
  
-''Anzeigefunktion Wuerfel ========================='' +'' Anzeigefunktion Uhr ========================='' 
-  - Hierüber wird die Augenzahl in der zweiten Zeile an Position 7 ausgegeben. +  - Hierüber wird die Uhrzeit in der ersten Zeile im Format hh:mm:ss ausgegeben. 
- \\ \\ \\ +  - Ähnlich zum Counter werden die zweistelligen Werte mit Division durch 10 und dessen Rest in zwei einzelne Ziffern gewandelt 
 +\\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\
  
 ''Initialisierung Display-Anzeige ========================='' ''Initialisierung Display-Anzeige =========================''
Zeile 407: Zeile 402:
   - Nach zwei Sekunden wird der Auswahlbildschirm angezeigt.   - Nach zwei Sekunden wird der Auswahlbildschirm angezeigt.
  
- +\\ \\ \\ \\ \\ \\ \\ \\ \\ 
 + 
 +''Zaehlfunktion Uhr ==============================='' 
 +  - Die Zähl-Funktion ''uhrZaehlen()'' ist ganz ähnlich aufgebaut zur Interrupt-Service-Routine 
 +  - Zunächst wird ein Schaltwechsel am Ausgang mit dem Lautsprecher ausgegeben, um einen Knackton zu erzeugen 
 +  - Dann werden die Sekunden hochgezählt 
 +  - ist das Maximum erreicht, so wird der Sekunden-Wert zurückgesetzt und der Minuten-Wert um eins hochgezählt. 
 +  - ebenso wird beim Maximum des Minuten-Serts dieser zurückgesetzt und der Stundenwert hochgezählt. 
 +  - beim Maximum des Stunden-Werts wird dieser wieder auf Null gesetzt
 </WRAP></WRAP> </WRAP></WRAP>
  
Zeile 423: Zeile 426:
 --> Aufgabe# --> Aufgabe#
  
-  - Darstellung des Augenwerts ändern  +  - Bauen Sie einen "ewigen Kalender" ein  
-    - Laden Sie folgende Dateien herunter: {{microcontrollertechnik:6a_mexlecast_extern.simu}}{{microcontrollertechnik:6a_mexlecast_extern.hex}} +    - Es sollen nicht nur StundeMinute, Sekunde dargestellt werden und veränderbar sein, sondern auch Tag, Monat und Jahr im Format dd:mm:yy 
-    - Simulieren Sie die Schaltung mit der beigefügten hex-Datei +    - Achten Sie auf die Schaltjahrermittlung 
-    Ändern Sie das bisherige Programm sodass Sie das gleiche Ergebnis erhalten, bzwzumindest die Ansteuerung der LEDs.+  Erweitern Sie den Kalender auf vierstellige Jahresangabe. 
 +  Überlegen Sie sichwie man Ihre Programme testen kann. 
 +  - BONUS: Wie kann der Wochentag bestimmt werden?
  
 <-- <--