// Servotester V 1.0 (c) Oliver Mezger 7.9.2010 #include // Definitionen laden #include // Delay-Bibliothek laden #include // Zuordnungen zu Ports #define SegmenteIn PIND #define SegmenteOut PORTD #define SegmenteDdr DDRD #define SteuerungIn PINB #define SteuerungOut PORTB #define SteuerungDdr DDRB #define StelleIn PINC #define StelleOut PORTC #define StelleDdr DDRC const unsigned char bcd_7[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xaf}; const unsigned char SMIN = 100, mitte = 150, SMAX = 200; const unsigned char mtoleranz = 3; const unsigned char LEDmask = 0b00111011; const unsigned char LEDrot = 0b01000000; const unsigned char LEDgn = 0b10000000; const unsigned char LEDblau = 0b00000100; //an PC4 angeschlossen const unsigned char Taster = 5; // Taster an PB5 const unsigned char Piepser = 3; volatile unsigned char anzeige[3]={0,0,0}; unsigned char dunkel = 0; typedef enum {reset,initservo,servo,initimpulsmessung,impulsmessung,initprog,prog} betriebsmode; betriebsmode bmode = reset; ISR(TIMER0_OVF_vect){ // Timer fuer Anzeige static unsigned char stelle=6,dzeiger=0,blink=0;; SegmenteOut = bcd_7[anzeige[dzeiger++]]; // Zeile laden if (dzeiger == 2) SegmenteOut &= 0b01111111; // Dezimalpunkt setzen StelleOut = (StelleOut & 0b11111000) | stelle; // Stelle anschalten stelle = (stelle * 2 + 1) & 0b111; // naechste Stelle neg. Logik if (dzeiger >2){ stelle = 6; // 110 wegen neg. Logik dzeiger = 0; } blink++; // Blinken erzeugen if (blink > 25){ dunkel = ~dunkel; blink = 0; } } void ausgebenAnzeige(unsigned int n){ if (n <= mitte-mtoleranz) // Binaerer Baum fuer 5 Faelle if (n < SMIN) SteuerungOut = (SteuerungOut & LEDmask) | LEDgn; // unter Minimum else SteuerungOut = (SteuerungOut & LEDmask) | (LEDgn & dunkel); // zwischen Minimum und unterer Toleranz else if (n < mitte+mtoleranz) SteuerungOut = (SteuerungOut & LEDmask) | LEDblau; // in der Neutral-Tolleranz else if (n <= SMAX) SteuerungOut = (SteuerungOut & LEDmask) | (LEDrot & dunkel); // zwischen Toleranz und Maximum else SteuerungOut = (SteuerungOut & LEDmask) | LEDrot; // ueber Maximum anzeige[0] = n % 10; n /= 10; anzeige[1] = n % 10; anzeige[2] = n / 10; } void ausgebenMeldung(unsigned char n){ switch (n){ case 1: // Ausgabe 0FF anzeige[2]=0; anzeige[1]=15; anzeige[0]=15; break; default: // Ausgabe Err anzeige[2]=14; anzeige[1]=16; anzeige[0]=16; } } ISR(ADC_vect){ // Abfragen des Potentiometers static unsigned int wert = 0; static unsigned char i = 0; const unsigned int messungen = 8; // mehrere Messungen mitteln unsigned int n; wert += ADC; i++; if (i >= messungen){ i = 0; n = (wert >> 5) + 30; // n = wert / messungen / 4 + 30; wert = 0; OCR1A = n * 10; ausgebenAnzeige(n); } } ISR(TIMER1_COMPA_vect){ // ISR fuer Timer-Ueberlauf wenn kein Impuls kommt ausgebenMeldung(1); } ISR(TIMER1_CAPT_vect){ // ISR fuer Signalwechsel am Eingang static unsigned int n = 0; if (SteuerungIn & 1){ // War es eine steigende Flanke TCCR1B &= ~(1<<6); // auf fallende Flanke reagieren n = ICR1; } else { TCCR1B |= (1<<6); // auf steigende Flanke reagieren n = (ICR1-n)/10; if (n>20 && n < 250) ausgebenAnzeige(n); else ausgebenMeldung(0); TCNT1 = 0; // Setze den Zaehler auf 0 } } int main(){ unsigned char taste = 0; TCCR0 = 2; // Systemtakt / 8 TCCR2 = 0b00011010; // CTC,Toggle, Systemtakt / 8 OCR2 = 15; TIMSK |= (1<