Autor Thema: servo motor signal PIC 16F877  (Gelesen 5723 mal)

kolja

  • Gast
servo motor signal PIC 16F877
« am: Oktober 22, 2009, 05:01:48 Vormittag »
Hallo,

bei einem Projekt bin ich für die Steuerung mehrerer Servo Motoren zuständig. Die Aufgabe soll ein PIC 16F877A übernehmen. Habe auch schon ein Programm dazu geschrieben bei dem das Signal für die Servos mit einem Timer und Interrupt generiert wird. Allerdings habe ich noch Probleme die richtige Frequenz zu bestimmen. Die Interrupt Routine soll alle 10µs ausgelöst werden. Dazu habe ich berechnet, dass der Timer mit 206 geladen werden muss. Beim Messen mit dem Oszilloskop stellt sich aber leider nicht die erwünschte Periodenlänge ein.

#int_rtcc                       
clock_isr()
{
   timer_cnt++;

   //control servo motor
   if(timer_cnt%2)             
   {
      //timer_cnt=0;
      output_high(pin_d7);
      output_high(pin_d6);
      output_high(pin_d5);
   }
   else
   {
      output_low(pin_d7);
      output_low(pin_d6);
      output_low(pin_d5);
   }
   set_rtcc(206);
}

In der main Funktion wird der Timer und der Interrupt ordnungsgemäß konfiguriert. Zu meinen Fragen: wann muss ich den Timer immer vorladen? So wie jetzt in der ISR oder reicht einmal im Hauptprogramm? Und warum komme ich nicht auf die errechnete Frequenz?

Wert für den Timer0= 256-(.000010/(4/20000000)) -> sollte doch eigentlich einen Überlauf nach 10µs erzeugen

Formel müsste doch eigentlich stimmen, oder?

Hoffe ihr könnt mir helfen, danke schonmal.

Beste Grüße,
Kolja.

Edit: Bitte Code-Tags verwenden.
Bernd
« Letzte Änderung: Oktober 22, 2009, 22:36:33 Nachmittag von Bernd »

Offline Bernd

  • Hero Member
  • *****
  • Beiträge: 3820
    • Profil anzeigen
Re: servo motor signal PIC 16F877
« Antwort #1 am: Oktober 22, 2009, 22:38:51 Nachmittag »
Zitat
Zu meinen Fragen: wann muss ich den Timer immer vorladen? So wie jetzt in der ISR oder reicht einmal im Hauptprogramm?

In der ISR.

Zitat
Und warum komme ich nicht auf die errechnete Frequenz?

Du hast zwischen den Interrupts nur 50 Befehlszyklen für die Abarbeitung. Zum einen benötigt die Sicherung und Wiederherstellung in der ISR eine nicht unerhebliche Zeit, zum anderen muß der Code der ISR auch noch abgearbeitet werden.

Zwischen den Interrupts stehen nur 50 Befehlszyklen zur Verfügung und die gesamte Abarbeitungszeit des Interrupts ist einfach größer als diese 50 Befehlszyklen. In diesem Zusammenhang ist

Zitat
if(timer_cnt%2) 

nicht wirklich optimal.  Sobald der verwendete Compiler die Division tatsächlich ausführt, um den Rest zu ermitteln, wird das Ergebnis niemals rechtzeitig zur Verfügung stehen.  Da es nur darum geht, zu ermitteln, ob timer_cnt gerade oder ungerade ist, würde ich nur das LSB testen (die Chancen sind dann viel höher, daß der Compiler einen möglichst optimalen Code generiert).

if (timer_cnt & 0x01)   // timer_cnt ungerade
{
    ...
}
else                    // timer_cnt gerade
{
    ...
}

Viele Grüße

Bernd

kolja

  • Gast
Re: servo motor signal PIC 16F877
« Antwort #2 am: Oktober 23, 2009, 02:34:13 Vormittag »
Ok erstmal vielen Dank, dass hift mir schon sehr weiter. Allerdings stehe ich nun vor einem anderen Problem. Die Aufgabe des Programms ist eigentlich Servo Motoren zu steuern. Dazu habe ich gedacht, dass mit der ISR ein geeignetes Signal erzeugt wird, Frequenz 40Hz. Hat soweit auch geklappt, allerdings wird die ISR nur alle 0,05ms aufgerufen und dadurch kann man die Impulsbreite nur um diesen Wert erhöhen oder senken. Deshalb ist die Winkelauflösung nicht optimal. Mein Plan ist es dadurch die Geschwindigkeit zu regulieren. Ist dies überhaupt der richtige Ansatz?

Hier der Code.

#int_rtcc                        //this routine creates the basic signal to control the servo motor
clock_isr()
{
   timer_cnt++;

   //control servo motor
   if(timer_cnt>500)
   {
      timer_cnt=0;
      output_high(pin_d7);
      output_high(pin_d6);
      output_high(pin_d5);
      output_high(pin_d4);
   }
   if(motor_cnt1==timer_cnt)     //set the pulse for servo motor 1
   {
      output_low(pin_d7);
   }
}

void main()
{
   set_tris_d(0xF0);
  
   set_rtcc(0);
   setup_counters(RTCC_INTERNAL, RTCC_DIV_1);
   enable_interrupts(int_rtcc);

   do
   {
      for(int i=10; i<40; i++)
      {
         motor_cnt1++;
         delay_ms(500);
      }

      for(i=40; i>10; i--)
      {
         motor_cnt1--;
         delay_ms(500);
      }

   }while(1);
}

Offline DroidgamesBab

  • Newbie
  • *
  • Beiträge: 2
    • Profil anzeigen
    • Droidgames
servo motor signal PIC 16F877
« Antwort #3 am: Juli 25, 2016, 22:28:34 Nachmittag »
We would like to slow down the speed for the servo.  The set speed function doesnt seem to control the servos.  Is there a way to control the servo speed?

nevermind
Android information you can find here click

 


* Recent Topics