/* ANKS Anklappssteuerung fuer Aussenspiegel */ /* __ _ */ /* __________/ /_ (_)________ ___ __ __ */ /* / ___/ ___/ __ \/ / ___/ __ \ / _ \/ / / / */ /* (__ ) /__/ / / / / / / /_/ // __/ /_/ / */ /* /____/\___/_/ /_/_/_/ / .___(_)___/\__,_/ */ /* /_/ */ /* */ /* (c) C.Schirp released under the creative commons BY-NC-SA license */ /* for further details see */ /* http://creativecommons.org/licenses/by-nc-sa/3.0/ */ /* schirp.eu must be named in derived software coyright notes */ /* */ /* V1.0 Erstausgabe */ /* V1.1 Änderung der Unterspannungserkennung HW1.3 erforderlich */ /* V1.2 Entprellen der Eingangsinale, schneller Wechsel in Sleep */ /* */ /* */ #include #include #include #pragma config = 0x3F38 // INTIO2 /* Port- Defines */ #define TR1 0b.0001.0000 // PA Transistor 1 (L) linkslauf #define TR2 0b.0000.1000 // PA Transistor 2 (L) rechtslauf #define TR3 0b.0000.0100 // PA Transistor 3 (H) rechtslauf #define TR4 0b.0000.0010 // PA Transistor 4 (H) linkslauf #define IN_UNTER 0b.0100.0000 // PA Unterspannungssignal IN #define PU_UNTER 0b.1000.0000 // PA Unterspannungssignal Pullup #define INP_A 0b.0001.0000 // PB Eingang A #define INP_B 0b.0010.0000 // PB Eingang B #define INP_AB 0b.0011.0000 // PB beide Eingaenge /* Programmkonstanten */ #define MOTORSTROM_H 80 // 1,2A x 0,33R #define MOTORSTROM_L 10 // 1,2A x 0,33R #define MOTORZEIT_H 60 // Max laufzeit in 100ms-Schritten #define ST_IDLE 0 // Stati-Defines #define ST_ANKLAPP 1 #define ST_AUSKLAPP 2 #define END_STROM 0xFF // Werte für Abbruch eines Klappvorganges in main() #define END_ZEIT 0xFE #define END_RICHTUNG 0xFD #define END_SLEEP 0xDC #define PWM_MAX 100 // Max-Tastgrad/Auflösung fuer Soft-PWM /* Funktionsprototypen */ void Eingang_testen(void); /* Variablen */ uns8 dummy, dummy2; // Hilfsvariablen uns8 Motorstrom; // Ergebnis des Medianfilters uns8 med_a; // Filterwerte uns8 med_b; uns8 med_c; uns8 soll_status; // Resultat der Eingangspegelauswertung uns8 result; // Zwischenergebnis der Eingangsauswertung uns8 i; // for-index fuer Verzoegerung in Eingangsauswertung uns8 laufzeit; // Zähler für die Laufzeitüberwachung in main() uns8 takt, cyc, duty; // Fuer Soft-PWM bank0 uns8 Blink:1; // Bitcounter /*------------------------------------------------------------------*/ /* II N N TTTTT */ /* II NN N T */ /* II N N N T */ /* II N NN T */ /* II N N T */ /*------------------------------------------------------------------*/ #pragma origin 4 interrupt int_server(void) { int_save_registers // wenn int-on-change, dann status auswerten Eingang_testen(); int_restore_registers } /*------------------------------------------------------------------*/ /* II N N II TTTTT */ /* II NN N II T */ /* II N N N II T */ /* II N NN II T */ /* II N N II T */ /*------------------------------------------------------------------*/ void init (void) { /* Oszillatorblock */ OSCCON = 0b0110.0000; // 4MHz Clock - wie 16F628 mit INTRC /* PORT A, B Config */ PORTA = 0x00; ADCON1 = 0b1000.1110; // AD-Wandler rechtsbuendig, Clk, nur PIN AN0 TRISA = 0b0110.0001; // RA0, 5 und 6 input PORTB = 0b0000.0000; // TRISB = 0b0011.0000; // 4 Inp_A, 5 Inp_b, Rest Ausgang /* ADC */ ADCON0= 0b0100.0000; // Fosc/8, Channel AN0, Stopped, AD_ON /*sonstiges*/ T1CON = 0x00; // Timer disabled OPTION_REG = 0x04; /* pull-up portB, falling edge int, no WDT prescaler, prescale=32 */ INTCON = 0b.0000.1000; // int disabled und gelöscht nur Int-on-change aktiv /* Variablen initialisieren */ med_a = MOTORSTROM_L; med_b = MOTORSTROM_L; med_c = MOTORSTROM_L; soll_status = ST_IDLE; } /*------------------------------------------------------------------*/ /* */ /* */ /* */ /* */ /* */ /*------------------------------------------------------------------*/ // // Pause für ms Milisekunden // void Delay1ms(uns16 ms) { while(ms) // Schleife verlassen wen ms=0 ist { OPTION = 2; // Vorteiler auf 8 einstellen TMR0 = 131; // 125 * 8 = 1000 (= 1 ms) while (TMR0); // abwarten einer Milisekunde ms--; // "ms" mit jeder Milisekunde ernidrigen } } // // 3-Tap Medianfilter für die Motorstromwerte // ältestes Element ist a, neuestes ist c // void MedianFilter(void) { #pragma updateBank 0 /* OFF, all cores */ // Medianfilter if (med_a>med_b) if (med_amed_c) Motorstrom = med_a; else if (med_b MOTORSTROM_H) laufzeit = END_STROM; // Kein Strom koennte Leerlauf oder short to GND sein..: abschalten! if (Motorstrom < MOTORSTROM_L) laufzeit = END_STROM; // hat sich das klappziel geändert? if (akt_status != soll_status) laufzeit = END_RICHTUNG; } // von while (laufzeit) // wenn Motor tatsächlich bewegt wurde, stoppen if (laufzeit != END_SLEEP) motor_stop(); // bei Überstom und -zeit klappvorgang beenden if (laufzeit != END_RICHTUNG) soll_status = ST_IDLE; } // von if != IDLE }; // von while(immer) }