Uhr

Aus der Mikrocontroller.net Artikelsammlung, mit Beiträgen verschiedener Autoren (siehe Versionsgeschichte)
Wechseln zu: Navigation, Suche

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