#define SAMAX_VIELZUKLEIN 418 #define SAMAX_ZUKLEIN 408 #define SAMAX 408 #define SAMAX_OK 407 #define SAMAX_ZUGROSS 406 #define SAMAX_VIELZUGROSS 396 volatile uint16_t sndteiler = 0xFF; volatile uint16_t spaltencnt = 0; volatile uint16_t spaltenpos = 0; volatile int16_t startpunkt = 0; volatile uint16_t spaltenzaehler = 0; volatile byte subteiler = 0; volatile byte subteilercnt = 0; volatile byte textcnt = 0; void avr_init(void) { // u.a. // Spaltencounter TCCR1A = 0; TCCR1B = (1 << WGM12) | (1 << CS10) | (1 << CS11); TCNT1 = 0; OCR1A = (uint16_t) ((uint32_t)255); TIMSK |= (1 << OCIE1B); } SIGNAL(SIG_OUTPUT_COMPARE1B) // CS10+CS11 = Vort. = 64 // Spaltencounter { if(subteiler) { subteilercnt++; // damit bei zu geringer Umdrgeschw. der Teiler noch wirkt ... if(subteilercnt >= subteiler) { subteilercnt = 0; } else return; } if(spaltenpos >= SPMAX) spaltenpos = 0; spaltencnt++; // auf naechste Spalte setzen - fuer Timingberechnung spaltenpos++; // auf naechste Spalte setzen - fuer Buchstabenausgabe } SIGNAL(HALL_INTERRUPT) { uint8_t tmp_sreg = SREG; cli(); // Interrupts aus // 200 U/min (300 ms) => / 400 = 750 us = 1,3 kHz // 150 U/min (400 ms) => / 400 = 1000 us = 1,0 kHz // 125 U/min (480 ms) => / 400 = 1200 us = 0,833 kHz // 100 U/min (600 ms) => / 400 = 1500 us = 0,666 kHz TIMSK = 0; // erstmal Timer aus bewegungscnt = 0; // es dreht sich was // Teiler ermitteln // wenn spaltencnt >= SAMAX, dann Teiler zu klein // wenn spaltencnt == (SAMAX - 1) .. dann genau richtig // wenn spaltencount < (SAMAX - 1) .. dann zu gross if(spaltencnt < SAMAX_VIELZUGROSS) sndteiler -= 10; else { if(spaltencnt < SAMAX_ZUGROSS) sndteiler--; else { if(spaltencnt > SAMAX_ZUKLEIN) sndteiler++; if(spaltencnt > SAMAX_VIELZUKLEIN) sndteiler +=10; } } // fuer langsame Drehung < 150 U/min if(sndteiler > 0xFF) { subteiler = sndteiler / 255; subteilercnt = 0; } if(sndteiler > 255) sndteiler = 255; TCNT0 = 0; TCNT1 = 0; OCR1A = sndteiler; // Vort. = 64 spaltencnt = 0; spaltenzaehler = 0; // wann gibts neuen Text .. normal alle 75 * 0.2 = 15 sec .... textcnt++; // Text soll bei jedem Durchlauf verschoben werden .... startpunkt -= forewardstep; if(startpunkt >= SAMAX) startpunkt = 0; if(startpunkt < 0) startpunkt = SAMAX - 1; // Startwerte setzen 0; zum Verschieben des Textes spaltenpos = (uint16_t)startpunkt; TIMSK |= (1 << OCIE1B); TIMSK |= (1 << OCIE0); SREG = tmp_sreg; }