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 }







Zitieren

Lesezeichen