Forum: Mikrocontroller und Digitale Elektronik Servo


von Zoltan (Gast)


Angehängte Dateien:

Lesenswert?

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);
  }

von Zoltan (Gast)


Angehängte Dateien:

Lesenswert?

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
Noch kein Account? Hier anmelden.