Pulse oximetre Timer sorunu

Başlatan h_baskent, 01 Şubat 2014, 13:27:17

h_baskent

Arkadaşlar merhaba,
Bir projede DsPic30f2012 serisinde yazılan bir kodu SMT32f4 discovery kite dönüştürmeye çalışıyorum. Bir konuda yardımızı isteyeceğim. DsPic' te hem ic1 interrupt hem de timer1 interruptı kullanılmış.
Sistem şu şekilde çalışıyor; önce ic1 ile frekans değerini yakalıyor sonra bu değerileri belirli işlemlerden geçiriyor. hazır bulduğum bir projede 30f serisi interruptlarını şu şekilde yapmışlar;


/*Interrupt routine to setup the basic timing for the system. The routine is called */
/*when timer T1 expires. This happens every 10ms. A state counter called STATE is   */
/*used to sequence the necessary events that the routine handle. Each state is 10ms */
/*Since these STATES are within an interrrupt routine, the first STATE (-1) is      */
/*is executed in the MAIN routine. STATE -1, has the timer initialization code.      */
/*STATE -1:   > Turns OFF both LEDS                                       */
/*         > Sets Initial DAC values                                    */
/*         > Initialize Timer T1                                        */
/*STATE 0:  > Set PULSE output = 0                                                  */
/*         > set measure = 0                                                       */
/*          > initialized timer T2                                                  */               
/*          > initialized IC1                                                       */
/*STATE 1:   > Set PULSE output = 1                                       */
/*         > Perform filtering                                          */
/*         > Perform DC Tracking                                       */
/*         > Set New DAC values                                       */
void __attribute__((interrupt)) _T1Interrupt(void)
   {
   IFS0bits.T1IF = 0;                           //Clear interrupt flag   

   if(STATE == 0)                              //STATE: 0
      {
//      LATB &= 0xFDFF;                           //Turn OFF diagnostic bit 9 (Measure Filter time)
      LATB &= 0xFFFE;                           //Turn OFF IRED Led (VIRon = 0)
      LATB |= 0x2;                           //Turn ON RED Led (VRon = 1)
      MEASURE = 0;                           //set state counter - Measurement: 0
      STATE++;                              //Increment state counter - STATE++
      InitT2();                              //Initialize Timer T2
      InitIC1();                              //Initialized Input Capture 1
      }
   else if(STATE == 1)                           //STATE: 1                     
      {
//      LATB |= 0x200;                           //Turn ON diagnostic bit 9 (Measure Filter time)

      //LPFilter Algorithm (Red Source)
      RFilt[0] = (N0*RFreq[0] + N1*RFreq[1] + N2*RFreq[2] + N3*RFreq[3] + N4*RFreq[4] - D1*RFilt[1] - D2*RFilt[2] - D3*RFilt[3] - D4*RFilt[4])/D0;
      RFilti = (unsigned int)RFilt[0];            //Buffer RFilt signal

      //HPFilter Algorithm or Differentiator (RED Source)
      dRFilt = K1*(RFilt[0] - RFilt[1]) + K2*dRFiltM1;

      for(indx = 4; indx > 0;indx--)               //Shift RED samples for LP Filter
         {
         RFreq[indx] = RFreq[indx-1];
         RFilt[indx] = RFilt[indx-1];
         }
      dRFiltM1 = dRFilt;                        //Shift RED samples for HP Filter

      //DC Filter Algorithm
      R_DC = R_DCM1 + (RFreq[0] - R_DCM1)/K;
      R_DCM1 = R_DC;                           //Shift RED samples for DC Filter
      R_DCi = (unsigned int)R_DC;                  //Buffer R_DC signal

      RDiff = RFilt[0] - R_DC;                  //Calculate RED AC signal
      GoodR = -1;                              //Good Data available



      //LPFilter Algorithm (IR Source)
      IRFilt[0] = (N0*IRFreq[0] + N1*IRFreq[1] + N2*IRFreq[2] + N3*IRFreq[3] + N4*IRFreq[4] - D1*IRFilt[1] - D2*IRFilt[2] - D3*IRFilt[3] - D4*IRFilt[4])/D0;
      IRFilti = (unsigned int)IRFilt[0];            //Buffer IRFilt signal

      //HPFilter Algorithm or Differentiator (IR Source)
      dIRFilt = 5.*K1*(IRFilt[0] - IRFilt[1]) + K2*dIRFiltM1;

      for(indx = 4; indx > 0;indx--)               //Shift IR samples for LP Filter
         {
         IRFreq[indx] = IRFreq[indx-1];
         IRFilt[indx] = IRFilt[indx-1];
         }
      dIRFiltM1 = dIRFilt;                     //Shift IR samples for HP Filter

      //DC Filter Algorithm
      IR_DC = IR_DCM1 + (IRFreq[0] - IR_DCM1)/K;
      IR_DCM1 = IR_DC;                        //Shift IR samples for DC Filter
      IR_DCi = (unsigned int)IR_DC;               //Buffer IR_DC signal

      IRDiff = IRFilt[0] - IR_DC;                  //Calculate IR AC signal
      GoodIR = -1;                           //Good Data available

//      LATB &= 0xFDFF;                           //Turn OFF diagnostic bit 9 (Measure Filter time)

//      DACOut(0,IRDaqVal);                        //Set IRED Intensity
//      DACOut(1,RDaqVal);                        //Set RED Intensity      
      STATE--;                              //Decrement STATE COUNTER
      }
   }



/*Interrupt routine to measure the intensity of the LEDs by measuring the frequency   */
/*being fed back from the TAOS LTF device. The routine is invoked by the IC1 input  */
/*pin (Input Capture #1). The hardware is setup so that a rising edge on the IC1 pin*/
/*causes the interrupt to occur. There four measurement states within this routine. */
/*The state counter MEASURE is used to control the events.                          */
/*MEASURE: 0   >  Read IC1 buffer and save   (T0)                           */
/*            >  Increment state counter MEASURE                           */
/*MEASURE: 1   >  Read IC1 buffer again and calculate the period for the RED Source*/
/*               Actual Period is: FCY/RFreq[0].                             */
/*            >  Compute RED Intensity - Directly proportional to frequency      */
/*            >  Turn OFF the RED Led                                    */
/*            >  Turn ON the IR Led                                    */
/*            >  Increment state counter MEASURE                           */
/*MEASURE: 2   >  Read IC1 buffer and save   (T0)                           */
/*            >  Increment state counter MEASURE                           */   
/*MEASURE: 3   >  Read IC1 buffer again and calculate the period for the IR Source   */
/*               Actual Peioud is: FCY/IRFreq[0].                           */
/*            >  Compute IR Intensity - Directly proportional to frequency      */
/*            >  Turn OFF the IRED Led                                 */
/*            >  Set the state counter MEASURE = 0                        */
/*            >  Disable the INPUT CAPTURE hardware                        */
/*            >  Disable the COUNTER T2                                 */
void __attribute__((interrupt)) _IC1Interrupt(void)
   {
   IFS0bits.IC1IF = 0;                           //Clear interrupt flag   
   if(MEASURE == 0)                           //MEASUREMENT STATE: 0
      {
      T0 = IC1BUF;                           //Save Initial Timer Value (RED Source)
      MEASURE++;                              //Increment State Counter
      }
   else if(MEASURE == 1)                        //MEASUREMENT STATE: 1
      {
      RPeriod = IC1BUF - T0;                     //Calculate Period for RED Source
//      RFreq[0] = 589824/RPeriod;                  //Calculate RED Intensity (Proportional to Frequency)
      RFreq[0] = (unsigned int)((long)1179648/(long)RPeriod);               //Calculate RED Intensity (Proportional to Frequency)
      if(RPeriod < 200)                        //If Period too small,
         RFreq[0] = 0;                        //Set Intensity to ZERO
      LATB &= 0xFFFD;                           //Turn OFF RED Led
      LATB |= 0x1;                           //Turn ON IRED Led
      MEASURE++;
      }
   else if(MEASURE == 2)                        //MEASURE STATE: 2
      {
      T0 = IC1BUF;                           //Save Initial Timer Value (IR Source)   
      MEASURE++;                              //Increment State Counter
      }
   else if(MEASURE == 3)                        //MEASUREMENT STATE: 3
      {
      IRPeriod = IC1BUF - T0;                     //Calculate Period for IR Source
//      IRFreq[0] = 589824/IRPeriod;               //Calculate IR Intensity (Proportional to Frequency)
      IRFreq[0] = (unsigned int)((long)1179648/(long)IRPeriod);            //Calculate IR Intensity (Proportional to Frequency)
      if(IRPeriod < 200)                        //If Period too small,
         IRFreq[0] = 0;                        //Set Intensity to ZERO
      LATB &= 0xFFFE;                           //Turn OFF IRED Led
      MEASURE = 0;                           //Set MEASURE STATE to 0
      IC1CON = 0;                              //Turn OFF IC1
      IEC0bits.IC1IE = 0;                        //Disable IC1 Interrupt
      T2CON = 0;                              //Disable Timer T2
      MeasurementDone = -1;                     //Set Measurement Flag
      }
   }
burda anlamadığım konu T1 timer' ını kullanıyor fakat STM32f discovery de ise yine bir timer1' i kullanabiliriz veya başka timer'ları. Dspic' te bu işlemi gerçekleştirirken neden iki ayrı işlem olarak göstermiş, bu işlemleri ic1' in içerisinde gösteremiyormu acaba ?
çünkü eğer discovery' de bir timer tanımlıyorsak bildiğim kadarıyla IQRHandler(void) {...} dosyasında ayrı ayrı timer1 için iki ayrı interrupt tanımlayamıyoruz bildiğim. yani şu şekilde olmuyor;

void TIM1_CC_IRQHandler(void)
{...}
void TIM1_IRQHandler(void)
{...} yani bir sistemde iki ayrı timer1 interruptı ?
yardımcı olursanız sevinirim.