Sida 5 av 5

Re: Fler problem med avbrottsrutin * LÖST VIDEO BIFOGAD*

Postat: 9 september 2012, 14:43:16
av kimmen
Behöver man ha if-satsen alls? Är problemet att displayen flimrar när man anropar Print_RPM(); även utan att ändra vilket värde som skrivs?
Icecap skrev:Och det är sant att det finns ett läge där de två funktioner kan komma i konflikt med varandra, i detta fall kan det vara vid Capture-värden runt 0xFFFF och möjligen några steg innan. Jag har dock bedömd att för att visa RPM ville det vara likgiltigt då det bara är en visning.
Ja visst är det så att det kanske inte spelar någon större roll i det här fallet. I min tillämpning gjordes mätningen på signaler upp till 20 kHz så det var ganska vanligt att det mätte fel.

Fast skall man vara petig borde det väl problemet fortfarande finnas kvar i din tidigare kod fast tvärt om. Om capture kommer efter overflow men före if(!PIR1.CCP1IF) körs mäter man 65536 för få timerticks i differens. (Istället för att mäta 65536 för många i det motsatta fallet)

Re: Fler problem med avbrottsrutin * LÖST VIDEO BIFOGAD*

Postat: 9 september 2012, 15:11:17
av SeniorLemuren
Som sagt var. I denna applikation, som tråden gäller så finns inget behov av ändringar av programmet som det ser ut nu. Inget flicker förekommer. Varvtalsvisningen är stabil inom det varvtalsområde som är aktuellt.

Re: Fler problem med avbrottsrutin * LÖST VIDEO BIFOGAD*

Postat: 9 september 2012, 16:49:25
av Icecap
Ändå så retar detta mig lite...

Kod: Markera allt

void interrupt(void)
  {
  if(PIR1.CCP1IF)
    { // Save data
    Time_Now.Byte[0]  = CCPR1L; // Transfer the value, low byte
    Time_Now.Byte[1]  = CCPR1H; // Transfer the value, high byte
    if(PIR1.TMR1IF) if(Time_Now.Word[0] <= 0x0002) Overflow++; // Catch the very rare problem, 0x0002 should be calculated better
    if(!Flag.Running)
      {
      Time_Diff.Dword = Time_Now.Dword - Time_Then.Dword;
      }
    Time_Then.Word[0] = Time_Now.Word[0]; // Save only the lower word
    Overflow          = 0;     // Start from known state
    Flag.Running      = true;
    PIR1.CCP1IF       = false; // Acknowledge interrupt
    }
  if(PIR1.TMR1IF)
    { // ~15,26Hz
    PIR1.TMR1IF = false; // Acknowledge interrupt
    if(Overflow < TIMEOUT_LIMIT) if(++Overflow >= TIMEOUT_LIMIT)
      { // Here after ~3,26 sek
      Flag.Timeout = true;  // Set the timed-out flag
      Flag.Running = false; // OK, a measurement is made - sort of...
      }
    }
  }
Jag tror att jag skulle ha adresserat problemet här, i just detta projekt kanske det inte är så himla viktigt men i andra projekt kan det ställa till med en del strul som kan vara mycket svårt att hitta och detta är ju tänkt för andra som kan behöva detta.

Petig som jag är har jag även ändrat lite med utskriften enl. vad som Senior önskar:

Kod: Markera allt

#define DEVIATION_MIN   5

#if DEVIATION_MIN
WORD RPM_Old;
#endif // DEVIATION_MIN

void main(void)
  {
  Initiate_Hardware();
  RPM.Dword    = 0;     // Initial value
  Flag.Running = false;
  Flag.Update  = true;  // Forces a initial readout
  Flag.Timeout = false;
#if SHIFTS
  Intermediate = 0;
#endif // SHIFTS
#if DEVIATION_MIN
  RPM_Old      = 0;
#endif // DEVIATION_MIN
  while(true)
    {
    if(Flag.Running)
      {
      RPM.Dword    = (MAGIC_CONSTANT / Time_Diff.Dword); // Calculate the RPM
      Flag.Running = false; // Allow further updates
      Flag.Update  = true;
#if SHIFTS
      Intermediate = (Intermediate - (Intermediate >> SHIFTS)) + RPM.Dword;
      if(!Intermediate) Intermediate = RPM.Word[0] << SHIFTS; // Gives fast response from zero
      RPM.Dword    = Intermediate >> SHIFTS;
#endif // SHIFTS
      }
    if(Flag.Timeout)
      {
      Flag.Timeout = false;
      Flag.Update  = true;
      RPM.Dword    = 0;
      Intermediate = 0;
      }
    if(Flag.Update)
      { // Print out RPM as needed
      // Här kan man skriva ut RPM om man vill det, en mätning är iaf. gjort
#if DEVIATION_MIN
      if(abs(RPM.Word[0] - RPM_Old) >= DEVIATION_MIN)
        {
        RPM.Word[0] -= (RPM.Word[0] % DEVIATION_MIN);
        RPM_Old = RPM.Word[0];
        Print_RPM();
        }
#else
      Print_RPM();
#endif
      Flag.Update = false; // Mark that measurement as used
      }
    }
  }