Hallo, ich habe folgendes Testprogramm geschrieben. Die Aufgabe des Programms ist es, den Puls von einem Fernsteuerempfänger im AVR als 16bit Variable zu speichern und diesen Wert anschließend an den Servo weiterzuleiten. (Siehe auch http://www.mikrocontroller.net/forum/read-1-15463.html#15566) 1.) Der Puls am Ausgang wird auch erzeugt, verändert seine Länge aber ständig minimal ( Servo hat leichtes Zittern). Ich habe das ganze am Oszi angeschaut, und um die normalerweise glatten Signale vom Empfänger und auch um den Ausgangspuls(5V+- 0,5V) herum sehe ich ein Schwingen von ~2,5V bis 4,2V. Ich benutze die Bauteile aus dem Tutorial. Liegt es am Quarz, dass der unsaubere Eingangspuls nicht richtig erkannt wird, und das zur Längenänderung am Ausgang führt? 2.) Und etwas anderes ist mir noch aufgefallen: Ich starte den Timer1 mit outp(2,TCCR1B), dh bei 4MHz, Teilungsfaktor CK8 sollte ich für 2ms eigentlich 1024 Schritte benötigen, denn: 1/4MHz = 0,00000025s 0,00000025s*8= 0,000002s ,dh bis der Timer1 bis 0,002 sec gezählt hat läuft dessen Zähler bis ~1000? Da dies aber leider ,WARUM AUCH IMMER, nicht klappt, habe ich den Teilungsfaktor auf CK64 gesetzt: outp(3,TCCR1B). Dann läuft es, aber ist diese Auflösung nun vielleicht viel zu grob? (~125 Schritte für 2ms) Wenn sich jemand die Mühe machen könnte, den Code anzuschauen, wäre echt Nett... Gruß Zoltan #include <io.h> #include <sig-avr.h> #include <interrupt.h> #include <inttypes.h> uint16_t PulsL; int input (uint16_t ); //Prototype int main(void) { outp(0xFF,DDRB); /* use PortB for output (to servo) */ outp(0x04, DDRD); /* use PortD PIN2 for input (signal) */ outp((1<<INT0), GIMSK); /* enable external int0*/ outp((0<<ISC01)|(1<<ISC00) , MCUCR); /* logical change: int0 */ sei(); /* enable interrupts */ for(;;){} } SIGNAL(SIG_INTERRUPT0) /* signal handler for external interrupt int0 */ { if(bit_is_clear(PIND,2)) { outp(0,TCCR1B); //Stop timer1// PulsL=TCNT1H; //2x 8bit in 16bit// PulsL<<=8; PulsL=TCNT1L; outp(0x00,TCNT1H); //Reset timer1// outp(0x00,TCNT1L); input(PulsL); } else { outp(2,TCCR1B); //Timer Setup, CK8, 4MHz, 2ms-->2048 } } input (uint16_t PulsOut) // Use PulsL to create puls for Servo { uint8_t tcnt1L, tcnt1H; PulsOut=0xFFFF-PulsOut; //Timer can´t count backwards... tcnt1L=PulsOut; // 16bit in 2x 8bit// PulsOut>>=8; tcnt1H=PulsOut; outp((1<<TOIE1),TIMSK); /*Timer Setup...*/ outp(2,TCCR1B); outp(tcnt1H,TCNT1H); //SET!! timer1 with PulsOut// outp(tcnt1L,TCNT1L); outp(0xFF, PORTB); //Sent SERVO SIGNAL } SIGNAL(SIG_OVERFLOW1) { outp(0x00, PORTB); /* turn LEDs off */ outp(0,TCCR1B); outp((1>>TOIE1),TIMSK); outp(0x00,TCNT1H); //Reset timer1// outp(0x00,TCNT1L); }
Hab den (bzw. die) Fehler gefunden. flasch: PulsL=TCNT1H; //2x 8bit in 16bit PulsL<<=8; PulsL=TCNT1L; richtig: uint8_t a=TCNT1L; // READ LByte FIRST!!!!!!!!!! uint8_t b=TCNT1H; PulsL=b; // 2x 8bit in ... PulsL<<=8; PulsL|=a; // ...16bit Jetzt funktioniert alles super!!! Die richtige Code habe ich als Anhang gepostet.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.