Uhr
Aus der Mikrocontroller.net Artikelsammlung, mit Beiträgen verschiedener Autoren (siehe Versionsgeschichte)
Dieser kleine Code zeigt die beispielhafte Implementierung einer Siebensegment Uhr.
Version 1.0.1
Eckdaten
Eigenschaft | Wert |
---|---|
Controller | AVR ATTiny2313 |
Spannung | 5V |
Quarz | erforderlich; 8MHz |
Flashspeicherbelegung | 913Bytes (44,6%) |
SRAM-Belegung | 19Bytes (14,9%) |
Funktionen
- Einstellen der Uhr (PD4 bzw. PD5 gegen GND)
- Blinkender Sekundenpunkt
Code
/* Belegungen: PB0 B PD0 1er, PNP-Transistor PB1 C PD1 10er, PNP-Transistor PB2 D PD2 100er, PNP-Transistor PB3 E PD3 1000er, PNP-Transistor PB4 F PD4 Schalter, interne Pullups sind an PB5 G PD5 Schalter, interne Pullups sind an PB6 DP PD6 - PB7 A Takt: 8MHZ Quarz Siebensegmentanzeige: Gemeinsame Anode */ #include <avr/io.h> //Grundfunktionen #ifndef F_CPU //Vordefinieren für delay.h #define F_CPU 8000000UL //Definition von F_CPU in Hertz #endif #include <util/delay.h> //Warteschleifen #include <avr/interrupt.h> //Interruptheader //Konstanten //Hier kann man den Code an seine Siebensegment Anzeige anpassen const unsigned char Zahl[10] = {0b01100000, 0b11111100, 0b01010010, 0b01011000, 0b11001100, 0b01001001, 0b01000001, 0b01111100, 0b01000000, 0b01001000}; //Globale Variablen volatile unsigned long int Sekunden=0; //32Bit Variable; 24Bit würdens auch tun unsigned char Tausender; unsigned char Hunderter; unsigned char Zehner; unsigned char Einer; unsigned char Blink; ISR(TIMER1_COMPA_vect) //Bei Compare-Match mit OCR1A (31250) wird Sekunden um eins erhöht. { Sekunden++; if (Sekunden >= 86400) //Wenn 24h vorbei sind, wird wieder auf 0 gesetzt Sekunden = 0; } void Berechnung (void) //Sekunden zu BCD { Tausender = (Sekunden / 3600) / 10; Hunderter = (Sekunden / 3600) - Tausender*10; Zehner = ((Sekunden % 3600) / 60) / 10; Einer = ((Sekunden % 3600) / 60) - Zehner*10; Blink = (Sekunden % 2); } void Einstellen (void) //Dient dem Einstellen der Uhr { if ( !(PIND & (1<<PIND5)) ) Sekunden = Sekunden + 60; if ( !(PIND & (1<<PIND4)) ) Sekunden = Sekunden + 3600; if (Sekunden >= 86400) //Wenn 24h vorbei sind, wird wieder auf 0 gesetzt Sekunden = 0; } void Anzeige (void) //Zeigt die BCD Werte an, Eine 4fach Siebensegmentanzeige wird gemultiplexed { unsigned int i; //Variable für die Schleife for (i=10; i>0; i--) //10*12ms=120ms Schleifenlaufzeit { if (Sekunden > 35999) { PORTD=0b01110111; //PD3 an --- Tausenderstelle PORTB=Zahl[Tausender]; } _delay_ms(3); PORTD=0b01111011; //PD2 an --- Hunderterstelle PORTB=Zahl[Hunderter]; if (Blink) { PORTB &= ~(1 << PB6); //löscht und setzt Bit 6 in PORTB, dadurch blinkt der Punkt zwischen den Stunden und Minuten } else { PORTB |= (1 << PB6); } _delay_ms(3); PORTD=0b01111101; //PD1 an --- Zehnerstelle PORTB=Zahl[Zehner]; _delay_ms(3); PORTD=0b01111110; //PD0 an --- Einerstelle PORTB=Zahl[Einer]; _delay_ms(3); } } int main (void) { //Registerinitialisierung TCCR1A = 0b00000000; //Timer im CTC-Mode; Prescaler 256; CPU-Clock TCCR1B = 0b00001100; //Timer im CTC-Mode; Prescaler 256; CPU-Clock TCCR1C = 0b00000000; //Timer im CTC-Mode; Prescaler 256; CPU-Clock TIMSK = 0b01000000; //Interrupt bei Compare Match OCR1A = 31249; //genau eine Sekunde; Comparematch-Register DDRB = 0b11111111; //Alles Ausgang; Siebensegmentanzeige DDRD = 0b11001111; //PD4 und PD5 sind Eingänge sei(); //Interrupts an Sekunden = 43200; //Hauptschleife while(1) { Berechnung(); Anzeige(); Einstellen(); } }