Input Capture and Output Compare By using S12ZVML31

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Input Capture and Output Compare By using S12ZVML31

3,411 Views
frankkong
Contributor III

@Alice_Yang 

Hello, 

    I,m using s12zvml31 for capture square wave's frequency and duty。Simultaneously, output square wave with the same frequency and specific duty(5% for example). The input frequency is between 10Hz and 1000Hz.

    S12zvml31 only have a Timer0 and my main interrupt cycle is 100us, what can I do to solve this problem?  The main iterrupt cycle has the highest priority.

       My timer's frequency is 625K now. 

Tags (1)
0 Kudos
Reply
8 Replies

3,031 Views
lama
NXP TechSupport
NXP TechSupport

Also not absolutely sure what is the status of the code, I have really forgotten. It is longer time I was working on it.

0 Kudos
Reply

3,030 Views
lama
NXP TechSupport
NXP TechSupport

Hi,

entire code is attached, minimum measured frequency is defined only maximum number of overflows.

It worked, however, I have not seen it for, really will not lie, for years.

Yes, it is for different MCU but principle....

The code only measures frequency without measuring duty cycle.

 

1)

  1. a) The first idea of measuring both pulse parts was described previously.
  2. b) Probably I can add that the type of edge can be also investigated by interrupt flag, without enabling interrupt, at two independent pins connected also to input signal.
  3. c) The issue you have is to make a compromise for maximum precision of the 1000Hz frequency and amount of overflows for 10Hz frequency from timer prescaler point of view.
  4. d) You should perform your own analysis a decide for timer setup as presented in the example, file main.c:

 

* Detailed Description:

*   - It mesure frequency at PT1 by means of ECT module.
*   - The measaurement is sensitive on rising edges so duty cycle has no affect
      to the measurement
*   - Constants:
           BUSCLOCK
           MAX_OVERFLOWS
           TIMER_PRESCALLER
      must be defined
*   - MAX_OVERFLOWS determines minimum mesurable frequency.
      It is max. allowed number of overflows. When overflows counter reaches
      this value it the flag FREQUENCY_TOO_LOW is set. The message
      PERIOD BETWEEN TWO EDGES IS TO WIDE is then sent sent to the PC through
      SCI0. This value gives time interval:
      T = TIMER_PRESCALER * MAX_OVERFLOWS * 65536 / BUSCLOCK    
      For example:
      - TIMER_PRESCALER = 1
      - MAX_OVERFLOWS   = 1000
      - BUSCLOCK        = 8000000Hz
      T = 1 * 1000 * 65536 / 8000000 = 8,192s  => f=0.122Hz
*   - TIMER_PRESCALER = { 1,2,4,8,16,32,64,128} - smaller values give more
      precise values but it generates timer overflow more frequently

 

... for example....

pastedImage_1.png

2) The issue I see is duty cycle measurement for small a large duty cycles in the first method. Because of this I would try to solve second method.

3) Another possibility and approach is to connect input signal to two different timer inputs and calculate period from rising edges from one channel including duty provided by interrupt on different channel for falling edge. However, it also requires study and tests.

 

incomming signal     |^^^^^^^^^^^^^^^|_____________________________________________|^^^^^^^^^^^^^^^|____
ICx (rising edges)     |<----period measured by ICx, P= f(TCx_old, TCx_new,ovfs)------------->|<----period-----

ICy (falling edges)                        |- event which stores TCy and num. of ovfs to be able to calc. duty    |- again

 

4) Your task is really not simple and will require a lot of test and modifications. Probably there is also much simpler solution but not going to my mind now.

Best regrads,

Ladislav

3,030 Views
frankkong
Contributor III

Thanks,lama

      I understand the method.

0 Kudos
Reply

3,030 Views
lama
NXP TechSupport
NXP TechSupport

Hi,

I was thinking about your task and I am not sure whether you need the value of the incoming signal. If yes then OK but if you do not need it then I think easier solution is monostable flip flop circuit to generate the same frequency with the given constant duty. It looks to be easier and faster solution. Moreover it removes issues with higher range of measured frequencies considering timer prescaler setup and SW (calculation) issues...and it removes issues with creating outgoing signal.

For this purpose, if I decide to use MCU for solution, I would use S12XE MCU with integrated XGATE and use the XGATE (Risc core integrated on the chip and connected also to a CPU)  as a parallel processor (interrupt driven) for processes which I do not want to influence CPU. Wery good especially in the case of processing signals and fast direct responses while CPU calculates more complicated tasks.

Best regards,

Ladislav

0 Kudos
Reply

3,030 Views
frankkong
Contributor III

Hi,lama

I have a idea for this problem. I use the interrupt of Timer0 IOC0 and IOC3. IOC3 is for input capture and IOC0 for output compare. The timer base frequency is 200K. If I add the compare value at IOC0 interrupt , then I can generate a 10us interrupt. I will deal with the output compare using the period interrupt(10us)  for 10hz~1000Hz. The problem is when I set the different priority it will meet some problem. If I set the same priority it works well. You can see the problem below:

pastedImage_4.png

pastedImage_3.png

  I want to set the priority of IOC0 is higher than IOC3, what can I do?

0 Kudos
Reply

3,030 Views
frankkong
Contributor III

Thanks, lama

             I use the LIN as the input signal and I can't change the MCU.

0 Kudos
Reply

3,030 Views
lama
NXP TechSupport
NXP TechSupport

Fast thinking for left aligned incoming pulses…using my old code (for another MCU) for frequency measurement adding additional code. Timer channel 1 is set for both edges interrupt and main timer is set for overflows. The code is just presenting approach. Probably it is correct, I am sorry topically can't see mistake....it requires some time for thinking....I know.....

|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|___________|^^^^^^^^^^^^^^^^^                          incomming signal

Irising edge                                                          |falling edge   |rising edge

|<---------period or duty or Globalperiod_1--------------->|<----period--->|<----period-----

|<-----------------------------------------Globalperiod----------->|<---------------------Globalperiod-----

 

// Count overflows

 

//*********************************

 

#pragma CODE_SEG NON_BANKED

interrupt XX void ECT_OvfIsr(void)  // count overflows

{

  ch1ovfCnt++;                      // count overflows

 

  if(ch1ovfCnt>MAX_OVERFLOWS)

   {

     ch1ovfCnt = 0;

     FREQUENCY_TOO_LOW = TRUE;

     SCI0_SendValue();              // send message to the PC

   }

  else

   { FREQUENCY_TOO_LOW = FALSE;

   } 

 

  ECT_TFLG2 = 0B10000000;            // clear interrupt flag of main timer

}

#pragma CODE_SEG DEFAULT

 

//*********************************

//Service interrupt for rising and falling edge

// calculate topical length of the finished level and length/globalperiod of invcoming signal:

//*********************************

 

#pragma CODE_SEG NON_BANKED

interrupt XX void ECT_Ch1Isr(void)

{

  unsigned int ovfs;

 

//------

  timerNewValue = ECT_TC1;      // read new captured value and clear flag

  ovfs          = ch1ovfCnt;    // save amount of ovfs to temporary variable

  ch1ovfCnt     = 0;            // clear number of overflows

  ECT_TFLG1     = 0B00000010;   // clear interrupt flag from PT1

 

                                //-----  Ch1 period calculation, calculate lengt of currently finished level of incoming signal ---------

  if(!ovfs)                     // Did edges appear within one timer period?

    {

      period = (ULONG)(timerNewValue - timerOldValue); // per. of given level

    }

   else  // some number of overflows has appeared between two edges

    {

      // time given by overflows period=....

      period = (ULONG)( ~timerOldValue+1 ); // time in the first period

      period+= (ULONG)(  timerNewValue);    // time in the last  period

      period+= (ULONG)((ULONG)((ovfs-1)) * (ULONG)(65536));

    }

  timerOldValue = timerNewValue; // prepare new old value

 

//-------------  calculate period and duty of incomming signal

  if(rising edge)

   {

     Globalperiod = Globalperiod_1 + period;  // period of incoming signal

     Data_prepared = TRUE;

     // now you have entire period and duty cycle of the Globalperiod which

     // has now gone. This value you can use for PWM

   }

  else

   {

     Globalperiod_1 = period; // also it is duty of a new Globalperiod

   }

}

#pragma CODE_SEG DEFAULT

 

 

 

Note; if you set prescaler of main timer to be sure there is only one overflow between rising and falling edge then formulas and code could be simplified. This is general approach for pulse of long  length with maximum lengt of MAX_OVERFLOWS.

Best regards,

Ladislav

0 Kudos
Reply

3,030 Views
frankkong
Contributor III

Thanks, lama.

   It does't work. Because the max frequency of Timer1 is 50M, the overflow time is 65535/50M = 1.31ms .It's too long for checking  square wave with 1K Hz frequency.

   any other ideas?

0 Kudos
Reply