De bedoeling is om met een freq van 50hz pulsen met een
pulsbreedte van 1-3ms te maken,nu vast op 1.5ms.

Alles werkt prima maar als ik meet kom ik op 35hz ipv 50hz.
ik werk met interne 4mh osci en de klok uit meet 1mhz
dus daar ligt het probleem niet.



const char minpos=5;      // Min value allowed
const char center=15;     // Center value
const char maxpos=25;     // Max value allowed
char counter=200;         // 1 period = 200 * 0.1 msecs
char position=15;         // This is the position we want

unsigned int a=0;

void main()
{

      TRISIO = 0b00001000;         // All pins output except pin 3
      GPIO=0;                      // alles uit
      OPTION_REG= 0b10000001;      // pullups off Prescaler 1/4
      CMCON0=0b0111;               // comparator uit.    Belangrijk vr GP0-1
      ADCON0=0;                    // AD is off
      CCP1CON=0;                   // Capture  / compare / pwm off
      OSCCON=0b01100110;           // 4Mhz int clock
      ANSEL=0;                     // Pins are digital   (na deze werkte led op GP0)
      TMR0 = 231;                  // T0=256-25 PS=1/4 (4Mhz/(4*25*4) )
      INTCON=0b10100000;           // Global + Timer0 Interrupt on
      
      while(1) ;
}
//==============================================================================
void interrupt()                    // Every 100 uSecs
{
  if(INTCON.T0IF )                  // TMR0 Interrupt?
   {
     if(200-counter >= position)
      {
        GPIO &=0xfe;                // GP0 Servo pin=0
      }
     else { GPIO |=0x01; }          // GP0 Servo pin=1

     if(counter > 0) counter--;
     else counter=200;              // Start with new period

     TMR0 = 231;                    // T0=256-25 PS=1/4 (4Mhz/(4*25*4) )
     INTCON.T0IF = 0;               // clear T0IF
   }
}


TMR2 lijkt me daar beter voor. Die heeft een compare register. Als je de pre- en postscaler op 1:1 zet kan je 99 in dat register zitten en geeft dan elke 100 klokpulzen een interrupt af. Eens ingesteld blijft de waarde in het compare register staan en gaat het helemaal automatisch

De waarde die je nu in TMR0 zet zorgt er voor dat deze een aantal klokpulzen niet kan tellen vandaar dat ook de frequentie verandert. De tijd worden langer dus de frequentie lager. Even lezen in de datasheet hoe lang de timer dan stel gezet word. Als dat 6 klokpulzen is moet je 237 ipv 231 in TMR0 zetten.

EDIT
Klopt niet omdat de prescaler op 1:4 staat het getal zou dan 6/4 moeten zijn. Prescaler dan anders instellen.

EDIT2
Je doet te veel in de interrupt.

   {
     if(200-counter >= position)
      {
        GPIO &=0xfe;                // GP0 Servo pin=0
      }
     else { GPIO |=0x01; }          // GP0 Servo pin=1

Deze horen niet in de interrupt thuis en kan ook in het hoofdprogramma worden afgehandeld.

[Bericht gewijzigd door benleentje op (19%)]

Kan het zijn doordat ik teveel doe in mijn
interrupts dat mijn puls freq trager wordt.

De interrupts komen om de 100us en mijn interrupt
duurt ongeveer 40us om af te handelen.
Hoewel de interrupts natuurlijk perfect op tijd komen.

Ik dacht de port naar de servo via de interrupt doen omdat
ik dan meer tijd heb in mijn main voor andere zaken.

Ik heb eens de test met timer2 gedaan
maar GP0 genereert geen puls.
Ziet iemand een fout?


void main()
{

      TRISIO = 0b00001000;         // All pins output except pin 3
      GPIO=0;                      // alles uit
      OPTION_REG= 0b10000001;      // pullups off Prescaler 1/4
      CMCON0=0b0111;               // comparator uit.    Belangrijk vr GP0-1
      ADCON0=0;                    // AD is off
      CCP1CON=0;                   // Capture  / compare / pwm off
      OSCCON=0b01100110;           // 4Mhz int clock
      ANSEL=0;                     // Pins are digital   (na deze werkte led op GP0)
      TMR2=0;
      INTCON=0b10000000;           // Global Interrupts on
      PIE1=00000010;               // Timer2 interrupt on
      T2CON=00000100;              // Postscaler = 1/1 T2=on Prescale = 1/1
      PR2=100;                     // 1 Mhz / 100 = 100us / interrupt
      
      
      while(1) ;
}
//==============================================================================
void interrupt()                    // Every 100 uSecs
{
  if(PIR1.TMR2IF )                  // TMR2 Interrupt?
   {
     if(200-counter >= position)
      {
        GPIO &=0xfe;                // GP0 Servo pin=0
      }
     else { GPIO |=0x01; }          // GP0 Servo pin=1

     if(counter > 0) counter--;
     else counter=200;              // Start with new period

     PIR1.TMR2IF = 0;               // clear T2 flag
   }
}

In de main heb je tijd genoeg maar de interrupt afhandeling moet alles zo kort mogelijk zeker als er interrups van meerdere bronnen kunnen komen.

Op 30 augustus 2009 20:23:47 schreef tubos:
Kan het zijn doordat ik teveel doe in mijn
interrupts dat mijn puls freq trager wordt.

Heb ik toch al uitgelegd. Dit komt omdat je elke een nieuwe waarde in je tmr0 register schrijft. Hierdoor kan deze een aantal klokpulzen niet tellen.

If the TMR0 register is written, the increment is
inhibited for the following two instruction cycles.

2 klokpulzen dus als je dan 100µS wilt dan moet je 256 - 100 + 2 =158 invullen. En je prescaler op 1:1 zetten. Die is voor zulke korte tijden onzin. Prescaler gebruik je enkel als je grotere tijden nodig hebt die dan niet in de 256 passen.

Opgelost:

Gewoon door Timer2 en compare register te gebruiken
ipv timer0 is de freq nu 49.50 hz voor de rest niks
veranderd.

Bedankt benleen voor de tip

Ik weet niet of je nu op de interne RC oscillator zit of op een kristal. Bij een kristal kan je dat bij regelen door een van de condensatoren van het kristal te vervangen door regelbare condensator.

Het interne signaal is in sommige chips ook bij te regelen met het osccall register.

Maar een kristal is altijd nauwkeuriger.

Ik zit op intern RC maar freq is niet kritisch
voor deze toepassing.

Normaal kan ik nu 10 standen links en 10 standen rechts
gebruiken op de servo's. ( besteld op ebay komen
binnen de week af)

Als het niet kritisch is dan is het goed. En 49,5 is afgerond 50:P