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:
Warum ist denn das so??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(); } }
Ich hoffe es kann mir helfen
Gruß Robert







Zitieren

Lesezeichen