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();
}
}