Guten Abend,

ich benötige mal wieder weiter Augen.

Es geht darum einen Taster einer Matrix als POWER-Taste zu verwenden und meinen Mikrocontroller in den Schlaf zu schicken. Das scheint auch bisher zu funktionieren.
Dann soll er allerdings, nach erneutem drücken der POWER-Taste durch den Watchdog Reset das Programm neu starten.
Manchmal Startet er wieder, gibt aber nur Murks auf dem Display aus und reagiert dann auch nicht mehr. Oder er reagiert überhaupt nicht mehr.

Hier der relevante Teil meines Codes:
Code:
#include "includes.h"

//------------------------------------------
//Makros und Definitionen

	#define KP_ROWDIR 	DDRD
	#define KP_COLDIR	DDRB
	#define KP_ROWPORT 	PORTD
	#define KP_COLPORT	PORTB
	#define KP_ROWPIN	PIND
	#define KP_COLPIN	PINB
	#define KP_ROWS		0b00110000
	#define KP_COLUMNS	0b00000111
	#define KP_ROWSHIFT	4
	#define KP_COLSHIFT	0 //Rechtsshift um bei 0 anzufangen
	#define KP_COLVAR 	3				//Anzahl verwendeter Spalten

	#define KP_ISR_VECT			PCINT1_vect
	#define KP_PCMSK			PCMSK1
	#define KP_PCIFR			PCIF1
	#define ENABLE_KP_PCINT 	PCICR |= (1<<PCIE1)
	#define DISABLE_KP_PCINT 	PCICR &= ~(1<<PCIE1)

	#define ENABLE_SLEEP_MODE	SMCR |= (1<<SM1)
	#define DISABLE_SLEEP_MODE	SMCR &= ~(1<<SM1)
	#define SLEEP				SMCR |= (1<<SE)
	#define WAKEUP				SMCR &= ~(1<<SE)
	#define PWRBUTTON			5

	#define RESET {asm("ldi r30,0"); asm("ldi r31,0"); asm("ijmp");}

//--------------------------------------------------
//Globale Variablen
//volatile uint8_t key_altState;
volatile struct _key_code key_code;

/*Hier Dinge vor dem schlafen gehen ausführen*/

void
Power_down (void)
{
	PCA9533_LED_select (0x30);
}

//----------------------------------------------------------------------
//Initialisierung der Tastaturmatrix

void keypad_init(void)
{
	/* Ports initialisieren*/
	KP_ROWDIR |= KP_ROWS;					//Zeilen als Ausgang definieren
	KP_COLPORT |= KP_COLUMNS; 				//Pullups für Spalten aktivieren

	/*Timer0 initialisieren*/
	//
	//Zeit bis zum Timeroverflow sollte mehr als 5ms
	//betragen um Prellen des Tasters abzuwarten
	//TCCR0B |= (1<<CS02); 				//Prescaler = 256 !Testeinstellung!
	TCCR0B |= (1<<CS00) | (1<<CS02); 	//Prescaler = 1024

	/*Pin change Interrupt aktivieren*/
	KP_PCMSK |= KP_COLUMNS;
	ENABLE_KP_PCINT;
	ENABLE_SLEEP_MODE;

}//keypad_init


//------------------
//

unsigned char
get_key(void)
{
	if(key_code.updated != 0)
	{
		key_code.updated = 0;
		return key_code.scan;
	}
	else
	{
		return 0xff;
	}
}

//-----------------------------------------------------------
//PCINT deaktivieren und Timer aktivieren

ISR(KP_ISR_VECT)
{
	DISABLE_KP_PCINT;
	
	WAKEUP;

	/*Timer0 vorbereiten und aktivieren*/
	TCNT0 = 0;							//Rücksetzen des Registers
	TIMSK0 |= (1<<TOIE0);				//Aktivieren des Timers
}

//-------------------------
//ISR zum auslesen der Matrix

ISR(TIMER0_OVF_vect)
{	
	TCNT0 = 0;

	
	/*Deaktivieren von Timer0*/
	TIMSK0 &= ~(1<<TOIE0);
	
	/*Lokale Variablen*/
	uint8_t lineResult;
	uint8_t tempScan = 0xFF;

	/*Einlesen der gedrückten Spalte*/
	lineResult = (KP_COLPIN & KP_COLUMNS);

	if(lineResult != KP_COLUMNS)
	{
		/*Invertieren der Pinrichtungen*/
		KP_ROWPORT |= KP_ROWS;				//Zeilen auf 'high' setzen
		KP_COLPORT &= ~KP_COLUMNS;			//Deaktivieren der Pullups für Spalten
		KP_ROWDIR &= ~KP_ROWS;				//Zeilen als Eingang definieren (Pullups werden aktiviert)
		KP_COLDIR |= KP_COLUMNS;			//Spalten als Ausgang definieren

		tempScan = 0;
		
		lineResult >>= KP_COLSHIFT;

		while(lineResult & 0x01)
		{
			lineResult >>= 1;
			tempScan++;
		}
		
		/*Einlesen der gedrückten Zeile*/
		lineResult = (KP_ROWPIN & KP_ROWS);

		/*Rücksetzen auf vorherige Pinrichtungen*/
		KP_ROWPORT &= ~KP_ROWS;			//Zeilen auf 'low'setzen
		KP_COLPORT |= KP_COLUMNS;			//Spalten auf 'high' setzen
		KP_ROWDIR |= KP_ROWS;				//Zeilen als Ausgang definieren
		KP_COLDIR &= ~KP_COLUMNS;			//Spalten als Eingang definieren (Pullups werden aktiviert)

		if(lineResult != KP_ROWS)
		{
			lineResult >>= KP_ROWSHIFT;

			while(lineResult & 0x01)
			{
				lineResult >>= 1;
				tempScan += KP_COLVAR;
			}

			/**/
			key_code.scan = tempScan;
			key_code.updated = 1;
		}
	}

	if (tempScan == PWRBUTTON && key_code.sleep == 0)
	{
		tempScan = 0xFF;
		Power_down ();
		key_code.sleep = 1;
		SLEEP;
	}

	if (tempScan != PWRBUTTON && key_code.sleep == 1)
	{
		SLEEP;
	}

	if (tempScan == PWRBUTTON && key_code.sleep == 1)
	{
		cli();
		wdt_enable(WDTO_60MS);
	}


	/*Pinchange Interrupt wieder aktivieren*/
	ENABLE_KP_PCINT;
	PCIFR |= (1<<KP_PCIFR);	
}
Kennt sich damit jemand aus und kann mir sagen was ich falsch mache?

Vielen Dank!

MfG,
Marten83