Hello
The input edge timer sample source code is required.
There is no example file in the Peripherals folder. ( edge_count, oneshot_16bit, periodic_16bit, pwm)
I need the edge_time example file.
thanks
[Attach image of desired configuration ]
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hello
The input edge timer sample source code is required.
There is no example file in the Peripherals folder. ( edge_count, oneshot_16bit, periodic_16bit, pwm)
I need the edge_time example file.
thanks
[Attach image of desired configuration ]
Jame shin said:I want sample code that does not have errors.
Mr. Shin - who here does "not" - seek just that? Yet - most often - those, "Requesting such "error-free" code" invest the required time, effort, trial - to meet that stringent requirement! This is not to say that you have not made much effort - yet as you've (not) yet reached your goal - does it not "fall squarely upon you" - to invest even more effort - in the pursuit of "code perfection?" I am quite certain that vendor's Charles has made "best effort" - and thanks to Mr. Tsai - it is very likely that you are "converging" upon your objective.
In that referenced post I was responsible for suggesting the simplification & speed-up which result (always) from "KISS." In this specific case - I chose two Timer pins - one to interrupt upon rising edges - the other upon falling ones.
There are two important PWM measurement parameters: PWM frequency (or its inverse, period) and Duty Cycle. Duty Cycle may be defined by the application - but most usually represents the, "Percent time "Active" scaled against the PWM period.
While your drawing is nice - it appears (to me) in error. In terms of your diagram, Duty Cycle is that portion of the waveform which is at/around logic High and then "scaled" by the signal's period! (i.e. Duty Cycle = Signal's time "high" / Signal's Period) PWM Period is the time between back to back, like-polarity, signal edges. (that designated by "T" in your drawing) Your drawing neglects the scaling required between "Signal's time high & Signal's Period)
Should highest accuracy be your goal it may prove best to capture the "time delta" between "n" such "like-polarity" signal edges - which will reduce the effect of "timing jitter" upon your measurement. (you would then divide that "total duration" by "n" - to determine the signal's period.)
The beauty of such an MCU and closely coupled IDE system is the ability offered to perform such code development experiments. The "feedback" you'll require is immediate - which enables you to move systematically toward YOUR (more proper) GOAL of, "Jame's created code" - which (of course) does NOT have errors!"
So James - time for you to develop YOUR "error-free" code - and provide it here for your "helpers."
Jame shin said:I want to get the example code.
Jame shin said:I want sample code that does not have errors.
Seriously???
Does TI ever promised/advertised you they will sell microcontrollers and also make the program for your application?
Being critical here won't help, but if that's ALL what it takes to develop products, the lady serving coffee downstairs is a serious competitor to you, Jame shin.
And if you don't understand the reason beyond the inspiring solution of using two timers for measuring one PWM signal, then I suggest you study it some more... or the lady serving coffee might as well get the position...
Bruno
Hi Charles,
It should be noted as well that the "Two Timer" method (which "sprang" from my far earlier suggestion of "KISS") proves far simpler & faster to program & implement - and that (always) should be a strong consideration. The time for "absolute optimization" is NOT during, "First Pass Code Development" - instead should only be attempted when it has been "proven" that any such "optimization" answers a "real need" or yields a measurable "saving." (thus justifies the required extra time/effort/cost.)
I wrote - rather clearly for Jame - that one timer captured "Rising Edge" - the second "Falling Edge" - his "miss of that" may indicate that "several slower readings" of detailed, "helper response" will prove helpful.
Again - the "demand" for "error-free" code is highly unusual - and is outside the purpose & intent of this (and to my mind) "ANY" forum! Each/every forum user - in pursuit of such - must employ (their own) time/effort/diligence - in that pursuit! It is NOT something to be "commanded" - and/or "ordered up" - which appears to be poster's (improper and/or misunderstood) desire...
Charles.
Go back to the first question
I have two worries.
1. Can not read the clock of the set time module?
2. The order of the Printf statements depends on the position of the interrupt routine.
How do I change it?
Thanks.
[Attached Images]
[ example Source Code]
- It is modified from the Ti example source.
//***************************************************************************** // // edge_count.c - Timer edge count mode example. // // Copyright (c) 2013-2015 Texas Instruments Incorporated. All rights reserved. // Software License Agreement // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the // distribution. // // Neither the name of Texas Instruments Incorporated nor the names of // its contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // This is part of revision 2.1.2.111 of the Tiva Firmware Development Package. // //***************************************************************************** #include <stdint.h> #include <stdbool.h> #include "inc/hw_ints.h" #include "inc/hw_memmap.h" #include "inc/hw_types.h" #include "driverlib/debug.h" #include "driverlib/fpu.h" #include "driverlib/interrupt.h" #include "driverlib/sysctl.h" #include "driverlib/timer.h" #include "driverlib/gpio.h" #include "driverlib/pin_map.h" #include "driverlib/rom.h" #include "driverlib/rom_map.h" #include "grlib/grlib.h" #include "drivers/cfal96x64x16.h" #include "utils/ustdlib.h" #include "driverlib/uart.h" #include "utils/uartstdio.h" // Flags that contain the current value of the interrupt indicator as displayed on the CSTN display. uint32_t g_ui32Flags; // An interrupt counter indicating how often the timer down counter reached volatile uint32_t g_ui32IntCount; // The graphics context used to draw on the display. tContext g_sContext; // A buffer used for string formatting. #define PRINT_BUFF_SIZE 8 char g_pcPrintBuff[PRINT_BUFF_SIZE]; void InitConsole(void) { // Enable GPIO port A which is used for UART0 pins. SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); // Enable UART0 so that we can configure the clock. SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); GPIOPinConfigure(GPIO_PA0_U0RX); GPIOPinConfigure(GPIO_PA1_U0TX); // Use the internal 16MHz oscillator as the UART clock source. UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC); // Select the alternate (UART) function for these pins. GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1); // Initialize the UART for console I/O. UARTStdioConfig(0, 115200, 16000000); } void ProcessInterrupt(void) { // // Update our interrupt counter. // g_ui32IntCount++; // // Toggle the interrupt flag telling the main loop to update the display. // //HWREGBITW(&g_ui32Flags, 0) ^= 1; HWREGBITW(&g_ui32Flags, 1) ^= 1; } // Initialize the display. This function is specific to the EK-LM4F232 board void InitDisplay(void) { tRectangle sRect; // Initialize the display driver. CFAL96x64x16Init(); // Initialize the graphics context and find the middle X coordinate. GrContextInit(&g_sContext, &g_sCFAL96x64x16); // Fill the top part of the screen with blue to create the banner. sRect.i16XMin = 0; sRect.i16YMin = 0; sRect.i16XMax = GrContextDpyWidthGet(&g_sContext) - 1; sRect.i16YMax = 9; GrContextForegroundSet(&g_sContext, ClrDarkBlue); GrRectFill(&g_sContext, &sRect); // Change foreground for white text. GrContextForegroundSet(&g_sContext, ClrWhite); // Put the application name in the middle of the banner. GrContextFontSet(&g_sContext, g_psFontFixed6x8); GrStringDrawCentered(&g_sContext, "edge-count", -1, GrContextDpyWidthGet(&g_sContext) / 2, 4, 0); // Initialize timer status display. GrContextFontSet(&g_sContext, g_psFontFixed6x8); GrStringDraw(&g_sContext, "Countdown:", -1, 8, 26, 0); GrStringDraw(&g_sContext, "Interrupts:", -1, 8, 36, 0); } void MainLoopRun(void) { uint32_t ui32Count, ui32LastCount; // Set up for the main loop. ui32LastCount = 1; // Loop forever while the timer runs. while(1) { // Get the current timer count. ui32Count = ROM_TimerValueGet(TIMER4_BASE, TIMER_A); if(ui32Count != ui32LastCount) { // update the display. usnprintf(g_pcPrintBuff, PRINT_BUFF_SIZE, "%d ", ui32Count); GrStringDraw(&g_sContext, g_pcPrintBuff, -1, 80, 26, true); // Remember the new count value. ui32LastCount = ui32Count; UARTprintf("Button CNT = %d \n", ui32Count); } // Has there been an interrupt since last we checked? if(HWREGBITW(&g_ui32Flags, 1)) { // Clear the bit. HWREGBITW(&g_ui32Flags, 1) = 0; // Update the interrupt count. usnprintf(g_pcPrintBuff, PRINT_BUFF_SIZE, "%d ", g_ui32IntCount); GrStringDraw(&g_sContext, g_pcPrintBuff, -1, 80, 36, true); UARTprintf("INT-Count = %d \n", g_ui32IntCount); // UARTprintf("g_ui32Flags = %x \n", &g_ui32Flags); } } } // The interrupt handler for timer 4. void Timer4IntHandler(void) { // Clear the timer interrupt. ROM_TimerIntClear(TIMER4_BASE, TIMER_CAPA_MATCH); ProcessInterrupt(); // The timer is automatically stopped when it reaches the match value so re-enable it here. ROM_TimerEnable(TIMER4_BASE, TIMER_A); } int main(void) { //ROM_FPULazyStackingEnable(); //ROM_SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | // SYSCTL_XTAL_16MHZ); ROM_SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ); // Timer Moudle(Timer A & Timer B) Clock Source Set // TimerClockSourceSet(TIMER4_BASE, TIMER_CLOCK_SYSTEM); // Initialize the display on the board. InitDisplay(); // UART Func Call InitConsole(); UARTprintf("\nSYSCLK = %d Hz\n", SysCtlClockGet()); // Enable Timer4 & GPIOM ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER4); ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOM); // Configure PM0 as the CCP0(Timer A) pin for timer 4. ROM_GPIOPinTypeTimer(GPIO_PORTM_BASE, GPIO_PIN_0); GPIOPinConfigure(GPIO_PM0_T4CCP0); // Set the pin to use the internal pull-up. MAP_GPIOPadConfigSet(GPIO_PORTM_BASE, GPIO_PIN_0, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU); // Enable processor interrupts. ROM_IntMasterEnable(); // Configure the timers in edge count mode. //ROM_TimerConfigure(TIMER4_BASE, (TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_CAP_COUNT)); ROM_TimerConfigure(TIMER4_BASE, (TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_CAP_COUNT_UP)); ROM_TimerControlEvent(TIMER4_BASE, TIMER_A, TIMER_EVENT_POS_EDGE); ROM_TimerLoadSet(TIMER4_BASE, TIMER_A,15); //ROM_TimerLoadSet(TIMER4_BASE, TIMER_A, 9); ROM_TimerMatchSet(TIMER4_BASE, TIMER_A,15); //ROM_TimerMatchSet(TIMER4_BASE, TIMER_A, 0); // Setup the interrupt for the edge capture timer. Note that we // use the capture match interrupt and NOT the timeout interrupt! ROM_IntEnable(INT_TIMER4A); ROM_TimerIntEnable(TIMER4_BASE, TIMER_CAPA_MATCH); // Timer Moudle(Timer A & Timer B) Clock Source Set TimerClockSourceSet(TIMER4_BASE, TIMER_CLOCK_SYSTEM); // TIMER_CLOCK_PIOSC or TIMER_CLOCK_SYSTEM // Enable the timer. ROM_TimerEnable(TIMER4_BASE, TIMER_A); // timer module source clock UARTprintf("TimerClk = %d Hz \n", TimerClockSourceGet(TIMER4_BASE)); // At this point, the timer will count up every time a negative edge is detected on the relevant pin . MainLoopRun(); }
Hello Jame,
You did a great work with these diagrams and on your understanding. Well done! A few more notes to help you achieve your goal:
1- If it was not clearly said, your timers will need to run synchronized. Here's a thread about it as guidance:
2- You don't have to permanently monitor the timer value in the main loop, just let the interrupts do it for you. Here's an idea (this is untested, just wrote it as an example...)
void Timer1A_ISR(void) { uint32_t ui32Status; ui32Status = ROM_TimerIntStatus(TIMER1_BASE, true); TimerIntClear(TIMER1_BASE,ui32Status); if (ui32Status & TIMER_CAPA_EVENT) { pwmRisingCountLast = TimerValueGet(TIMER1_BASE, TIMER_A); flagNewCountAvailable = true; } }
3- Same applies, of course, for the other timer
4- Inside your main loop, you can make new calculations only when needed. Something like this:
while(1) { if (flagNewCountAvailable) { MakeCalculations(); flagNewCountAvailable = false; } }
5- For the calculations, you need to mind that the 16-bit timers are actually smaller then the expected period (unless you want to wire the signals into two 32-bit timers, which is a good idea)
void MakeCalculations(void) { /* * period = the clock difference pwmRisingCountLast - pwmRisingCountPrevious, * BUT accounting for rollover and timer width */ /* * dutywidth = the clock difference pwmFallingCountLast - pwmRisingCountPrevious, * also minding rollover and widths */ duty = dutywidth / period; pwmRisingCountPrevious = pwmRisingCountLast; }
6- If you are seeing your values on a console via UART, or on a screen, there is not much point in seeing then 1000 times per second. So you may want to determine a more convenient moment to send the current result. Also, you may want to use some filtering or averaging on your readings, depending what your sensor is.
By the way, what editing program do you use to create those schematics?
Regards
Bruno
Bruno Saraiva said:there is not much point in seeing then 1000 times per second
Nor is - (human or animal) vision - able to process visual data arriving @ 1mS intervals. (most can "barely" detect the "Olympic Timer Clocks" - usually updating at 100mS intervals...)
Indeed poster produces "best ever" diagrams - bit more "organized & focused effort" will see the (desired) SELF-CREATED, Error Free Example Code!
*** LIKE ***
(note: single, well debounced, Like Switch implemented here...) Very good explanation - poster's (obsession) w/"drawings" may cloud his basic thought process...
Simple experimentation with the Timer should clarify - poster's introduction of "So much extra" diverts him from his "central task." (think "surgery" - the area in question is "clear" - ALL else is "draped" - thus focus is "forced upon the issue (tissue) at hand" - not the extraneous!)
Of course - this proves (just another) example of KISS - most always "kicked to the curb" here... (at the cost of needless "pain/suffering.")
Hi Jame Shin,
Jame shin said:
UARTprintf("TimerClk = %d Hz \n", TimerClockSourceGet(TIMER4_BASE))
Bruno is correct that syntax only returns the source clock used for GPTM module not the value of counter registers relative to source clock time.
So we must read the GPTM register count after an interrupt to get the value for edge time examination. The datasheet explains each GPTM configuration mode in great detail yet document GPTM errata may effect method or count direction depending on usage. Be sure to check errata document for GPTM modes effected.
Below we calculate the edge count after the GPTM match count interrupt fires a one shot timer that fires a tick handler in 1 second intervals.. Similar calculation of specific syntax point inside a handler after entering an interrupt can be done with edge timer registers. We really don't care about rising/falling signal edge times into NVIC interrupt controller only that software can concatenate such time via register values of hardware. Don't worry how fast the edge time NVIC will react to your 1Khz PWM input (not so relative) rather the counters ability to capture and record said time relative to registers values and match interrupt times are.
/* Get GPTMTBV free running count value. */ ui32TBVEdgeCount = HWREG(TIMER0_BASE + TIMER_O_TBV); /* Get GPTMTBILR current matching edge counts */ ui32TBILREdgeCount = HWREG(TIMER0_BASE + TIMER_O_TBILR); /* Determine the total number of counted edges up to ISR */ ui32EdgeCount = ui32TBILREdgeCount - ui32TBVEdgeCount;
Hi Jame,
Sorry for the late reply. What Bruno meant to say was that the API simply returns the register value which indicates what the clock source is, not the frequency of the clock source. Please take a look at the API function where the timer control register is read to return the API function.
uint32_t TimerClockSourceGet(uint32_t ui32Base) { // // Check the arguments. // ASSERT(_TimerBaseValid(ui32Base)); // // Return the timer clock source. // return(HWREG(ui32Base + TIMER_O_CC));
Hello BP101.
Mr.Burono explained that the return value of the TimerClockSourceGet() function is not a numeric value.
Thank you for your attention and help.
Mr. Charles informed me of his previous post on the Edge Time Implementation Study.
" Don't worry how fast the edge time NVIC will react to your 1Khz PWM input"
I do not know what you're talking about.
They are concerned about the problem and looking for a solution.
I'm just studying the content.
I have one question.
In the attached image, please explain why the timer clock is at least 4 times the input signal ?
thanks.
[attached image]
Jame shin said:x2 time = 12.5ns x 79992 cycles (count dection) = 999.9 us
Not here - nor now! Might "scientific notation" & slight "rounding" assist?
[edit] Whoops - swear I saw that cycle number as 7992 - see (now) that it is not. To the list of "sci notation" & "rounding" - appears "eyesight" (or wakefulness) must be added...
Thus: (1.25 * 10 ^ -8) * (8 * 10 ^ 4) = 10 ^ -4 = 0.001000 which is 1000 µS! Such (back of the envelope) "Quick Calcs" usually avoid "order of magnitude" errors (but not numeric mis-reads.)
Hi Jame,
Jame shin said:In the attached image, please explain why the timer clock is at least 4 times the input signal ?
The GPTM source clock does not have to run a SYSCLK speed and can depending on the application use PIOSC 16Mhz internal precision clock source gives timer a 62.5ns tick.
Sorry for confusing your edge time example software request, it seemed you were requesting to calculate the rising edge time and not specifically concatenating the time between two different edges which has nothing to do with rising edge time. To keep it simple try to calculate edge times for CCP inputs as a total number of GPTM ticks relative to SYCLK or PIOSC using the formula 1/F. Not sure why exactly the need to use two CCP inputs interrupts when a 24 bit edge timer should easily determine the frequency of a single input signal relative to GPTM timer ticks.
There is a formula in datasheet use to determine GPTM source clock rate relative to CCP input frequency GPTM might be expected to measure.
BTW 1Khz = 1ms does it not.
In defense of vendor's Charles - we do not know how he could "write any more clearly!"
Is it possible that your drawing contains too much - thus overwhelms the thought process?
Charles described the use of TWO Timers - one configured to capture rising edge - the second to capture falling edge. The input signal is routed to BOTH Timer pins. (i.e. it is the SAME signal)
You ask, "How to implement "Sync" between these two timers. That's a standard function - available w/in the API - unknown how you've "missed" that.
The "beauty" of the TWO Timer method is its simplicity - again as Charles (clearly) wrote - the "difference between the Two Timer's latched values, "IS your x1.""
Hi Jame,
I prepare a simple example to demonstrate using two timers to calculate the duty cycle. I was able to measure a duty cycle that is is 0.01% of 1kHz PWM. The timer measures the duty correctly. You need to modify/adapt to your application. The example calls TimerSynchronize(TIMER0_BASE,TIMER_0A_SYNC|TIMER_0B_SYNC ) to synchronize the two timers. However, since timerA and timerB shares the same timebase, the synchronization should not be needed but you will need if you plan to use between different timer generators. For timerA and timerB that I use from TIMER0, I don't see any difference in the duty cycle with sync or without sync.
Hello Charles
Thank you very much for your answers so far.
I have corrected the wrong idea.
Finally, there is two question.
It was previously described.
I thought I needed at least 8 cycles to process the ISR jump.
1. How many cycles do you need to handle the ISR?
2. What is the maximum period time of detection in input edge count / time mode?
- when time module clock 80 MHz or 40 MHz
thanks.
Hello again Jame,
First, let me recommend you change one section of your drawings to represent the real signal into two timers. In a few places, you've drawn offset signals going into timers A and B. I have dragged one of them to represent what will actually happen, so that other readers don't get misguided:
Next, to answer your questions:
A) How many cycles does the interrupt routine take?
There are a few manners you can count that:
1) By measuring the time externally: configure a GPIO pin as output, and before the code block you want to measure, raise it high; right after the block, raise it low. See the signal in a oscilloscope. The time difference is the period those instructions took, PLUS the commands to raise and lower the GPIO (TOTAL_CYCLES). Then, use the same raise/lower instruction right next to each other, and measure that amount of time (TOGGLING_CYCLES). If you subtract the toggling cycles time from the total, you'll get the STUDIED_CYCLES time. Note that code optimization will affect it, so you can measure with optim turned off for a worst case.
2) Looking at the assembly code of your complete block, and adding by hand the instruction cycles taken by each assembly instruction.
3) Instead of using GPIO, configure a wide timer to run continuously, sourced by system clock. Before the code block, read the free-running timer value. After the code block, do it again. Note the difference in cycles. As with the GPIO concept, subtract the amount of cycles taken by two adjacent timer read instructions.
4) Some more powerful IDE's have features that tell you how many cycles a given block requires.
B) What is the maximum period of detection that the system can measure:
I'd say this is a good question for you to calculate and respond. Given that this thread has been a extensive study of timers for you - and maybe to others in the future - do you agree that this answer will serve as a final exercise? Do your maths and propose an answer here, I'm sure we'll be able to take a look and guide a correction if needed.
Bruno
*** LIKE *** Notable - the simplicity which your (pardon) "KISS-Based" Drawing provides! Good that.
Sometimes the fledgling needs to be "pushed" from the nest. (Momma birds are good @ that - forum folk - maybe, "not so much..."
Any post titled, "I need" shows minimal care/concern for "all others" - and as the "Timer-Sync function" is well listed/described w/in the API - yet "escaped the note of the "needy" - much of the proclaimed "need" is self-induced - is that not true? Undue "hand-holding" may result in the fledgling's "never leaving!" (unwise in both the "bird & forum" kingdoms...)
Jame shin said:I thought I needed at least 8 cycles to process the ISR jump.
Common misunderstanding: new programmers tend to confuse the value returned by TimerValueGet(). That can be partly (fully?) to blame on the TivaWare User Guide, which says:
"This function reads the current value of the specified timer." - such is UNTRUE! The code for that function is:
return((ui32Timer == TIMER_A) ? HWREG(ui32Base + TIMER_O_TAR) : HWREG(ui32Base + TIMER_O_TBR));
Register TIMER_O_TAR (or in other words GPTM_TAR) full description:
"This register shows the current value of the Timer A counter in all cases except for Input Edge Count and Time modes. In the Input Edge Count mode, this register contains the number of edges that have occurred. In the Input Edge Time mode, this register contains the time at which the last edge event took place"
It DOES NOT MATTER how many cycles your system takes to get into the ISR. When you get there and obtain the timer value, such value will reflect that "old" instant in which your signal transition happened.
Bruno
Hi Jame,
1) I never said it takes 8 CPU cycles to get to the interrupt. I took your application use case (1kHz input PWM) as a reference and tried to derived how many cycles would be if the duty cycle is 0.01% which is 8 CPU cycles. Then I said 8 cycles will be too short if for the CPU to service the interrupt before the next edge is detected and then overwrite the captured value that has yet to be read by the CPU. If you want to measure how many cycles it takes for the CPU to enter the ISR, this is what I will suggest. You use the same rise edge interrupt. When the edge is detected the timestamp is saved into the GPTMTAV, Immediately in the first instruction inside the ISR you will read the GPTMTAR register. The GPTMTAR is the free-running counter. The difference between these two registers is roughly the time it takes to enter ISR. Note that Bruno has very suggestion too.
2) The maximum period depends on your source clock frequency and whether you use 16bit, 24-bit, 32-bit or 48-bit. You simply multiply your CPU clock period by the timer resolution you are using.
Charles Tsai said:Then I said 8 cycles will be too short if for the CPU to service the interrupt before the next edge is detected and then overwrite the captured value that has yet to be read by the CPU.
Charles,
You might be inducting further confusion here... If using the split signal into two timers as suggested, this is NOT a limitation.
Bruno
Really "Time to invoke the Slaughter Rule!" (are not the helpers - as the thread count passes FIFTY - now (almost) fighting/arguing?)
And for WHAT? The best NEED is SELF-SATISFIED - not "dumped here!"
Lastly - have you NOT now "OPENED THE DOOR" to "ALL SUCH EXACT EXAMPLE NEEDS" - from "ALL POSTERS?" (i.e. should EVERY waking moment be devoted to, "I NEED?") Really?