Hallo an alle

Bei meinem Gesichtsbräunertimer hab ich noch ein paar Probleme.

Doch leider funktioniert noch nicht alles ganz zuverlässig. Am Auslesen
des EEproms happerts noch ein bisschen. Woran kann das liegen??

Und was mir noch aufgefallen ist, wenn ich KEY0 gedrückt halte, dann
zählt er viel langsamer die Variable time herunter als wenn ich KEY1
gedrückt halte und er nach oben zählt.

Hier mal der Source Code:

Code:
/*******************************************
Title:      Belichtungstimer
Author:     Robert Schilling
Date:       9.8.2006
Hardware:   Atiny26 + Board
********************************************/

#include <avr/io.h>
#include <stdlib.h>
#include <avr/eeprom.h>
#include <avr/interrupt.h>

#define LEDPORT					PORTA
#define LED_A					PA0
#define LED_B					PA1
#define LED_C					PA2
#define LED_D					PA3
#define LED_E					PA4
#define LED_F					PA5
#define LED_G					PA6

#define RELAISPORT				PORTA
#define RELAISPIN				PA7

#define TASTER_TRANSPORT		PORTB

#define KEY_PIN					PINB
#define KEY0					4
#define KEY1					5
#define KEY2					6
 
#define REPEAT_MASK				(1<<KEY0^1<<KEY1^1<<KEY2)		// repeat: key1, key2
#define REPEAT_START			50								// after 500ms
#define REPEAT_NEXT				20								// every 200ms

#define EEP_ADRESS_MIN			0x01
#define EEP_ADRESS_SEC			0x02

#define DONE					0x01
#define UNDONE					0x00
#define TIMER_1SEC_ENABLED		0x01
#define TIMER_1SEC_DISABLED 	0x00

#define _D						0x0B
#define _O						0x0C
#define _N						0x0D
#define _E						0x0E

const uint8_t symbol[]={0x3F, 		//0
						 0x05, 		//1
						 0x5B, 		//2
						 0x4F,		//3 
						 0x65, 		//4
						 0x6E, 		//4
						 0x7E, 		//5
						 0x07, 		//6
						 0xFF, 		//7
						 0x6F, 		//8
						 0x08, 		//9							
						 0x5D, 		//d
						 0x5C, 		//o	
						 0x54, 		//n
						 0x7A};		//E
						
const uint8_t active_position[] =  {0x78, 
									0x74, 
									0x72, 
									0x71};

uint8_t segment[4];
uint8_t position;

volatile uint16_t time = 0;
volatile uint8_t done = UNDONE;
volatile uint8_t counter;
volatile uint8_t timer_1sec = TIMER_1SEC_DISABLED;
volatile uint8_t counter_1sec = 0;

uint8_t key_state;				// debounced and inverted key state:
								// bit = 1: key pressed
uint8_t key_press;				// key press detect
 
uint8_t key_rpt;				// key long press and repeat

void time2dispay(void);
void eeprom_read(void);
void eeprom_write(void);
void init(void);
void update_display(void);
void timer_init(void);
uint8_t get_key_press(uint8_t key_mask);
uint8_t get_key_rpt(uint8_t key_mask);
uint8_t get_key_short(uint8_t key_mask);
uint8_t get_key_long(uint8_t key_mask);


void timer_init(void)
{
	TCCR1B = ((1 << CS12) | (1 << CS11) | (1 << CTC1));	//Prescaler = 32; Enabale CTC Mode
	OCR1C = 0xFA;											//Compare Interrupt at 250
	TIMSK |= (1 << OCIE1A);
}

void time2display(void)	//ZEit wird zerlegt in die einzelnen Ziffern
{ 
	uint16_t rest;

	segment[0] = time / 600;
	rest = time % 600;

	segment[1] = rest / 60;
	rest %= 60;

	segment[2] = rest / 10;
	rest %= 10;

	segment[3] = rest; 
}

void eeprom_read(void)		//EEProm wird ausgelesen und Zeit wird berechnet
{
	time = (eeprom_read_byte((uint8_t *)EEP_ADRESS_MIN) * 60) + eeprom_read_byte((uint8_t *)EEP_ADRESS_SEC);
	time2display();
}

void eeprom_write(void)	
{
	uint8_t minuten, sekunden;
	
	minuten = time / 60;			//Zeit wird in Minuten und Sekunden Zerlegt 
	sekunden = time % 60;
	
	if(minuten != eeprom_read_byte((uint8_t *)EEP_ADRESS_MIN))		//Zuerst wird der EEPROM ausgelesen
		eeprom_write_byte((uint8_t *)EEP_ADRESS_MIN, minuten);		//Falls die Werte nicht übereinstimmen, 
																	//wird der EEPROM neu beschrieben
	if(sekunden != eeprom_read_byte((uint8_t *)EEP_ADRESS_SEC))
		eeprom_write_byte((uint8_t *)EEP_ADRESS_SEC, sekunden);
}

void init(void)
{
	DDRA = 0xFF;	//PORTA als Ausgang
	DDRB = 0x0F;	//PORTB	0 - 3 als Ausgang, 4 - 6 als Eingang
	PORTB = 0x70;	//Aktiver die Pullups an PB4, PB5, PB6

	position = 0;

	eeprom_read();
	timer_init();

	counter = 0;
	counter_1sec = 0;
	timer_1sec = TIMER_1SEC_DISABLED;	//Deaktiviere die 1sec ISR
	counter_1sec = 0;
}
	
void update_display(void)
{
	position++;
	
	if(position > 3)
		position = 0;

	TASTER_TRANSPORT = active_position[position] | 0x70;
	LEDPORT = symbol[segment[position]];
}

ISR(TIMER1_CMPA_vect)
{
	static uint8_t ct0, ct1, rpt;
	uint8_t i;
	
	counter++;

	if(counter == 5)		//5ms
	{
		//Debounceroutine von Peter Danegger
		i = key_state ^ ~KEY_PIN;				// key changed ?
		ct0 = ~( ct0 & i );					// reset or count ct0
		ct1 = ct0 ^ (ct1 & i);					// reset or count ct1
		i &= ct0 & ct1;							// count until roll over ?
		key_state ^= i;							// then toggle debounced state
		key_press |= key_state & i;				// 0->1: key press detect
			 
		if( (key_state & REPEAT_MASK) == 0 )	// check repeat function
			rpt = REPEAT_START;					// start delay
				
		if( --rpt == 0 )
		{
			rpt = REPEAT_NEXT;					// repeat delay
			key_rpt |= key_state & REPEAT_MASK;
		}
			
		counter = 0;
		counter_1sec++;
	
		if(time > 0)
			time2display();
		
		update_display();
		
		if((counter_1sec == 200) && (timer_1sec == TIMER_1SEC_ENABLED))	//1sec ISR
		{
			counter_1sec = 0;
			time--;
			time2display();

			if(time == 0)
			{
				RELAISPORT &= ~(1 << RELAISPIN);	//Switsch OFF Relais
				done = DONE;
	
				segment[0] = _D;	//"DONE"
				segment[1] = _O;
				segment[2] = _N;
				segment[3] = _E;
				
				timer_1sec = TIMER_1SEC_DISABLED;			//Disable 1sec interrupt				
			}
		}
	}
}

uint8_t get_key_press(uint8_t key_mask)
{
  cli();					// read and clear atomic !
  key_mask &= key_press;                        // read key(s)
  key_press ^= key_mask;                        // clear key(s)
  sei();
  return key_mask;
}
 
 
uint8_t get_key_rpt(uint8_t key_mask)
{
  cli();					// read and clear atomic !
  key_mask &= key_rpt;                        	// read key(s)
  key_rpt ^= key_mask;                        	// clear key(s)
  sei();
  return key_mask;
}
 
 
uint8_t get_key_short(uint8_t key_mask)
{
  cli();			// read key state and key press atomic !
  return get_key_press( ~key_state & key_mask );
}
 
 
uint8_t get_key_long(uint8_t key_mask)
{
  return get_key_press( get_key_rpt( key_mask ));
}

void tastenauswertung(void)
{
	if(done == DONE && (get_key_press(1 << KEY0) || get_key_press(1 << KEY1) || get_key_press(1 << KEY2)))
	{
		done = UNDONE;
		init();
	}
	
	if(get_key_press(1 << KEY2))			//START
	{
		RELAISPORT |= (1 << RELAISPIN);	//Switsch On Relais
		eeprom_write();
		timer_1sec = TIMER_1SEC_ENABLED;
	}
	
	if(get_key_rpt(1 << KEY0) && get_key_rpt(1 << KEY1) && timer_1sec == TIMER_1SEC_ENABLED)
		init();
		
	if(get_key_rpt(1 << KEY0) && time > 0 && timer_1sec != TIMER_1SEC_ENABLED)
		time--;
		
	if(get_key_press(1 << KEY0) && time > 0 && timer_1sec != TIMER_1SEC_ENABLED)
		time--;
		
	if(get_key_rpt(1 << KEY1) && time < 3600 && timer_1sec != TIMER_1SEC_ENABLED) 	//1 Stunde
		time++;
		
	if(get_key_press(1 << KEY1) && time < 3600 && timer_1sec != TIMER_1SEC_ENABLED)	//1 STunde
		time++;
}

int main(void)
{
	init();
	sei();
	time2display();	
		
	while(1)
	{
		tastenauswertung();
	}

}
Warum ist denn das so??

Ich hoffe es kann mir helfen

Gruß Robert