Tag,

ich versuche gerade mal ein wenig mit dem Power Pown Modus zu experimentieren.

Dabei soll der Controller nach dem Start und der Initialisierung sofort in den Power-Down-Mode gehen. Durch einen gedrückten Taster ensteht dann ein Low-Pegel am INT1, welcher als Level Interrupt programmiert ist und den Controller aus dem Power-Down-Mode aufweckt. Das Programmm läuft..... Bis dahin läuft auch alles einwandfrei.

Nun mein Problem:

Durch erneutes drücken des Tasters, also erneuter Low-Pegel am INT1 soll der Controller wieder in den Power-Down-Mode gehen. Das funktioniert nur leider nicht. Vielleicht hat einer ne Idee woran das liegen kann?

Hier ist der Code:

Code:
#include<avr/io.h>
#include<avr/sleep.h>
#include<avr/interrupt.h>
#include <stdio.h>
#include <inttypes.h>
 
typedef unsigned char	u8;
typedef signed short	s16;

#define FOSC 14745600 //Clock Speed
#define BAUD 9600
#define UBRR ((FOSC / (BAUD * 16L)) - 1)
 
#define	XTAL		1e6		// 1MHz
 
#define KEY_PIN		PIND
#define KEY0		0
#define KEY1		1
#define KEY2		2
#define KEY3		3
#define KEY4		4
 
#define LED_DDR		DDRB
#define LED_PORT	PORTB
#define LED0		0
#define LED1		1
#define LED2		2
#define LED3		3
#define LED4		4
 
//#define REPEAT_MASK	(1<<KEY1^1<<KEY2)	// repeat: key1, key2
#define REPEAT_START	50		// after 500ms
#define REPEAT_NEXT	20		// every 200ms

//Initialisierung AD-Wandler
void ADC_wandlung();

//Initialisierung UART
void uart_init();
 
 
u8 key_state;				// debounced and inverted key state:
					// bit = 1: key pressed
u8 key_press;				// key press detect
 
u8 key_rpt;				// key long press and repeat

unsigned int pause;

unsigned char taster = 0xFF;
unsigned char a;


void uart_init()
{

/* Port als Ausgang */
//DDRB |= (1 << PB0) | (1 << PB1) | (1 << PB2) | (1 << PB3);

//PORTB |= (1 << PB0) | (1 << PB1) | (1 << PB2) | (1 << PB3);

/* Aktivieren des Empfängers, des Senders und des "Daten empfangen+Daten leer"-Interrupts */
UCSR0B = (1<<RXCIE0)|(1<<RXEN0) |(1<<TXEN0) | (1 << UDRIE0);

/* baud rate*/
UBRR0H = (unsigned char) (UBRR>>8);
UBRR0L = (unsigned char) UBRR;

/* frame format: 8data, 2stop bit*/
UCSR0C = (1 << USBS0) | (3 << UCSZ00);
}
 
 
ISR(TIMER0_OVF_vect )			// every 10ms
{
  static u8 ct0, ct1;
  u8 i;
 
  TCNT0 = (u8)(s16)-(XTAL / 1024 * 10e-3 + 0.5);	// preload for 10ms
 
  i = key_state ^ ~taster;		// 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
}
 
 
u8 get_key_press( u8 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;
}
 
 
u8 get_key_rpt( u8 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;
}
 
 
u8 get_key_short( u8 key_mask )
{
  cli();			// read key state and key press atomic !
  return get_key_press( ~key_state & key_mask );
}
 
 
u8 get_key_long( u8 key_mask )
{
  return get_key_press( get_key_rpt( key_mask ));
}
 
 
int main( void )
{

 	 //UART Initialisieren
  	uart_init();

  	TCCR0B = 1<<CS02^1<<CS00;			// divide by 1024
  	TIMSK0 = 1<<TOIE0;				// enable timer interrupt

  	DDRD &= ~( 1<< PD3) | (1 << PD0) | (1 << PD2);    
  	
	SMCR &= ~(1 << SM0) | (1 << SM2);  				//Power Down Modus
	SMCR |=  (1 << SM1) | (1 << SE);				//Power Down & Sleep Enable

	EICRA &= ~(1 << ISC11) | (1 << ISC10);  		//Low Level of INT1 generates Interrupt Request
	EIMSK |= (1 << INT1);							//External Interrupt Request Enable
	sei();

	set_sleep_mode(SLEEP_MODE_PWR_DOWN);
    sleep_mode();
	EIMSK &= ~(1 << INT1);							//External Interrupt Request Diable
 	
  	LED_PORT = 0xFF;
  	LED_DDR = 0xFF;
  
 
  for(;;){	

    ADC_wandlung();

	if(!(PIND & (1 << PIND3)))
	taster &= ~(1 << 4);
	
	else
	taster |= (1 << 4); 

    if( get_key_press( 1<<KEY4 ))					//Interrupt at INT1
	{
	EIFR |= (1 << INTF1);							//INT1 Interrupt Flag löschen
	EIMSK |= (1 << INT1);							//External Interrupt Request Enable
	sleep_mode();
	EIMSK &= ~(1 << INT1);							//External Interrupt Request Diable

	}
	
    //erste LED
 	if((ADCH <=35) && (ADCH >= 30))
	taster &= ~(1 << 0);
	
	else
	taster |= (1 << 0); 

    if( get_key_press( 1<<KEY0 ))
    LED_PORT ^= 1<<LED0;

	
    //zweite LED
	if((ADCH <=110) && (ADCH >= 105))
	taster &= ~(1 << 1);
	
	else
	taster |= (1 << 1); 
 

    if( get_key_press( 1<<KEY1 ))
      LED_PORT ^= 1<<LED1;


    //dritte LED
 	if((ADCH <=207) && (ADCH >= 202))
	taster &= ~(1 << 2);
	
	else
	taster |= (1 << 2); 

    if( get_key_press( 1<<KEY2 ))
    LED_PORT ^= 1<<LED2;

    //vierte LED
	if((ADCH <=253) && (ADCH >= 248))
	taster &= ~(1 << 3);
	
	else
	taster |= (1 << 3); 
 

    if( get_key_press( 1<<KEY3 ))
      LED_PORT ^= 1<<LED3;

  }
}

void ADC_wandlung()		//ADC0/PCINT - PORTC, Bit0
{
  DDRC = 0x00;		// Alle Pins von Port C als Eingang definiert
  ADMUX &= ~((1<<MUX0)|(1<<MUX1)|(1<<MUX2)|(1<<MUX3));	//ADC0 eingestellt.
  ADCSRA = (1<<ADEN)|(1<<ADPS0)|(1<<ADPS1)|(1<<ADPS2);
  ADMUX |= (1<<REFS0) | (1 << ADLAR); //|(1<<REFS0);

  ADCSRA |= (1<<ADSC);		//AD Wandlung
  while (ADCSRA & (1<<ADSC))
  {
  ;
  }
  
}

ISR(USART_UDRE_vect)
{
  if(pause == 50000)
  {
  UDR0 = ADCH;
  pause = 0;
  }
  pause++;
  a = ADCH;

}


ISR(INT1_vect )
{
//EIMSK &= ~(1 << INT1);							//External Interrupt Request Diable
}