1.3.4 Interrupt-On-Change (IOC) With Timer
Modules | Limit High | Resolution |
---|---|---|
IOC | 1 ms |
250 ns |
TimerX |
If no hardware modules are available to measure a pulse, a single IOC pin can be configured to cause an interrupt on both the rising and falling edges. The minimum pulse width must be at least 25ns wide for the PIC16F18076 according to the electrical specifications. Other factors will limit the performance of this method, such as interrupt latency.
OVERVIEW
This method is similar to what the CCP module does, except it cannot stop the timer immediately when an event is detected (rising/fall edge). This raises the uncertainty in the calculation, since software must now stop the timer. Some PIC devices can specify rising and falling edge triggers, while others cannot differentiate between the two. The INT pins can be used as well as any of the PORTB pins if the device supports IOC.
First, the period of the periodic waveform will be measured. Then a pulse measurement will be performed.
SETUP
Steps to measure the period:
- Configure one of the IOC pins to interrupt on rising edge (IOCBP)
- Set the pin as a digital input
- Set up any timer so that it will count
‘
T
’ (Figure 2) without overflowing - Enable the timer
- When the IOC flag is set, clear it and
save the timer into a temporary variable (
temp1
) - When the interrupt flag is set again,
stop the timer and save the timer into a temporary variable (
temp2
) - Period is
now:
Period = temp2 - temp1
IOC with Timer Period Setup and Operation Code
Configure IOC Pins (Step 1) IOCBP = 0x20; // Sets Interrupt on rising edge of RB5 Input Pin Setup (Step 2) TRISBbits.TRISB5 = HIGH; // Set RB5 as a digital input Timer0 Setup (Step 3) TMR0H = 0xFF; TMR0L = 0xF0; T0CON1 = 0x70; // T0CS HFINTOSC; T0CKPS 1:1; T0ASYNC not_synchronised; T0CON0 = 0x10; // T0OUTPS 1:1; T0EN disabled; T016BIT 16-bit; Timer0_Start(); // Start Timer0 (Step 4) while(!IOCBFbits.IOCBF5); // Wait for IOC flag to set (Step 5) IOCBFbits.IOCBF5 = 0; // Clear IOC flag (Step 5) temp1 = Timer0_Read(); // Save Timer0 value into temp1 (Step 5) // Same as "(TMR0H << 8) + TMR0L)" while(!IOCBFbits.IOCBF5); // Wait for IOC Flag to set (Step 6) Timer0_Stop(); // Stop Timer0 (Step 6) temp2 = Timer0_Read(); // Save Timer0 value into temp2 (Step 6) // Same as "(TMR0H << 8) + TMR0L)"
Steps to measure the pulse:
- Configure one of the IOC pins to interrupt on rising edge (IOCBP)
- Set the pin as a digital input
- Set up any timer so that it will count
‘
W
’ (Figure 2) without overflowing - Enable the timer
- When the IOC flag is set, clear it and
save the timer into a temporary variable (
temp1
) - Configure the pin to interrupt on falling edge (IOCBN)
- When the interrupt flag is set again,
stop the timer and save the timer into a temporary variable (
temp2
) - Pulse width is
now:
MeasuredPulse = temp2 - temp1; while(MeasuredPulse > Period) MeasuredPulse -= Period;
IOC with Timer Pulse Setup and Operation Code
Configure IOC Pins (Step 1) IOCBP = 0x20; // Sets Interrupt on rising edge of RB5 Input Pin Setup (Step 2) TRISBbits.TRISB5 = HIGH; // Set RB5 as a digital input Timer0 Setup (Step 3) TMR0H = 0xFF; TMR0L = 0xF0; T0CON1 = 0x70; // T0CS HFINTOSC; T0CKPS 1:1; T0ASYNC not_synchronised; T0CON0 = 0x10; // T0OUTPS 1:1; T0EN disabled; T016BIT 16-bit; Timer0_Start(); // Start Timer0 (Step 4) while(!IOCBFbits.IOCBF5); // Wait for IOC flag to set (Step 5) IOCBFbits.IOCBF5 = 0; // Clear IOC flag (Step 5) temp1 = Timer0_Read(); // Save Timer0 value into temp1 (Step 5) // Same as "(TMR0H << 8) + TMR0L)" Configure IOC Pins (Step 6) IOCBP = 0x00; // clear Interrupt on rising edge of RB5 IOCBN = 0x20; // Set Interrupt on falling edge of RB5 while(!IOCBFbits.IOCBF5); // Wait for IOC Flag to set (Step 7) Timer0_Stop(); // Stop Timer0 (Step 7) temp2 = Timer0_Read(); // Save Timer0 value into temp2 (Step 7) // Same as "(TMR0H << 8) + TMR0L)"
LIMITATIONS
This method has a restriction that the period must be greater than the amount of time required to capture two rising edges. If the software setup time between rising edges is greater than the period, then the period measurement will be incorrect.
If the IOC flags cause a jump to the ISR when set, the designer must be aware of the latency incurred by the interrupt vectoring. Since this interrupt is asynchronous to the clock, the expected delay is 3-5 instruction cycle times, as seen below (Figure 1).