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

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