/* * HalloweenaugenServo_II.c * * Created: 02.01.2024 16:42:32 * Author : xxx */ #define F_CPU 9600000 // ---CKDIV8-Fuse muss deaktiviert sein !!!--- #include #include #include #include #include //Augen-Zeitvariablen: volatile uint8_t zeitAugenFst=0; volatile uint8_t zeitAugenEinsSek=0; volatile uint8_t zeitAugenZweiSek=0; volatile uint8_t zeitAugenDreiSek=0; volatile uint8_t zeitAugenVierSek=0; //Augenzustandsvariablen: volatile bool zustandAugenEinsAn=false; volatile bool zustandAugenZweiAn=false; volatile bool zustandAugenDreiAn=false; volatile bool zustandAugenVierAn=false; //Servo-Code: volatile uint8_t phase=0; volatile uint8_t ZeitZaehlerServo=0; volatile uint8_t servoZyklus=0; // Timer ist übergelaufen (alle 6,8267ms (=256*0,02666ms)), neue Phase beginnt (Clock : Timer-Prescaler=> 9,6MHz : 256 = 0,02666ms je Timer-Takt) // Jede 3. Phase (20,5ms) wird PB0=1 gesetzt und dann bei Erreichen des Vergleichswertes (OCR0A in der Main-Schleife löst "ISR(TIM0_COMPA_vect)" aus),s.u., wieder auf 0 gesetzt ISR(TIM0_OVF_vect) { // Servo nur in Phase 0 ansteuern if (phase==0) { PORTB |=(1< 1,004Sek) ZeitZaehlerServo = ZeitZaehlerServo+1; //alle 3 Phasen (20,5 ms) eins hochzählen zeitAugenFst = zeitAugenFst+1; } phase = phase+1; // Nächste Phase 1... 2...3 => 0 if (phase > 2) { phase=0; } } // Timer hat Vergleichswert erreicht ISR(TIM0_COMPA_vect) { PORTB &= ~(1<1ms(37) bis 2ms(70, korrigierter Wert)) } //Zufallszahlen für Zeitwerte volatile uint8_t laufZeit=0; //Zur Info: 0=> 1Sek., Max-Werte für Zeit: 255, Anzahl: 50 //Ablage erfolgt im Flash-Speicher, um RAM zu sparen //const uint8_t zeitWerteSekundaer[50] PROGMEM = {52, 99, 167, 3, 55, 22, 119, 27, 153, 85, 22, 10, 103, 48, 24, 124, 11, 7, 57, 120, 47, 77, 138, 79, 20, 116, 52, 5, 191, 8, 153, 26, 72, 64, 18, 185, 30, 12, 3, 129, 112, 17, 197, 89, 15, 107, 2, 61, 164, 79}; //const uint8_t zeitWerteSekundaer[50] PROGMEM = {68, 9, 133, 14, 99, 104, 96, 93, 7, 123, 141, 39, 32, 29, 131, 6, 30, 148, 41, 122, 77, 43, 103, 5, 42, 81, 146, 24, 38, 82, 52, 136, 89, 118, 48, 71, 87, 69, 8, 61, 106, 73, 153, 109, 40, 147, 50, 10, 63, 121}; //const uint8_t zeitWerteSekundaer[50] PROGMEM = {1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2}; const uint8_t zeitWerteSekundaer[50] PROGMEM = {1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1}; uint8_t zufallsZeitWert(); int main(void) { //Servo-Code cli(); // Loesche globales Interruptflag //Setzen der Register fuer 20 ms Timerinterrupt TCNT0 = 0; //Loesche Timer Counter 0 // Starte Timer 0 im Fast PWM Modus mit Prescaler TCCR0A=0; //Loesche Timer Counter Controll Register A TCCR0A |= (1< 8Bit Fast-PWM //Timer/Counter Interrupt Mask Register: TIMSK0=0; TIMSK0 |= (1<Timer0 starten, Prescaler 256 // Erlaube Interrupts sei(); //Setzen des globalen Interrupt-Enable-Bit // Aktiviere PWM und LED Ausgänge //DDRB = 0x1f; // Eingänge: Reset PB5; Ausgänge: PB0-PB4 (0: Servo; 1-4: LED-Augen 1-4) DDRB |= (1<48){ //Sekundentaktgeber //Sekunden-Taktgeber zurücksetzen zeitAugenFst = 0; //49 entspricht ca. 1 Sek. (1,004s) //Auge 1: zweite Zeitvariable prüfen (Anzahl an Sekunden) if (zeitAugenEinsSek>0) { zeitAugenEinsSek--; //Sekundären Zeitzähler reduzieren } else { //Wenn beide Zeitvariablen abgelaufen sind: //wenn Auge an, dann ausschalten if (zustandAugenEinsAn) //wenn PinB1 =1 { //ausschalten PORTB &= ~(1<0) { //Sekundären Zeitzähler reduzieren zeitAugenZweiSek--; } else { //Wenn beide Zeitvariablen abgelaufen sind: //wenn Auge an, dann aus schalten if (zustandAugenZweiAn) //wenn PinB2 =1 { //ausschalten PORTB &= ~(1<0) { zeitAugenDreiSek--; //Sekundären Zeitzähler reduzieren } else { //Wenn beide Zeitvariablen abgelaufen sind: //wenn Auge an, dann ausschalten if (zustandAugenDreiAn) //wenn PinB3 =1 { //ausschalten PORTB &= ~(1<0) { zeitAugenVierSek--; //Sekundären Zeitzähler reduzieren } else { //Wenn beide Zeitvariablen abgelaufen sind: //wenn Auge an, dann ausschalten if (zustandAugenVierAn) //wenn PinB4 =1 { //ausschalten PORTB &= ~(1<48 && ZeitZaehlerServo<98) { // Servo nach rechts fahren OCR0A = 70; //berechnet 75, nach Messung auf 70 korrigiert } if (ZeitZaehlerServo>98) //Ein links-rechts-Zyklus durchlaufen { //Sekundenzähler zurücksetzen ZeitZaehlerServo=0; servoZyklus=servoZyklus+1; } } } //while (1) return 0; } uint8_t zufallsZeitWert(){ //gibt Zufallswert für Zeit zurück laufZeit++; if (laufZeit>49){laufZeit=0;} return pgm_read_byte (zeitWerteSekundaer[laufZeit]); //Zugriff & Rückgabe von Wert aus dem im Flash abgelegten Array }