Hertz used in AVR - timer

I'm very new to AVR and got confused about a question from one of our tutorials. It says:
"To toggle an output compare pin 8 times per second (4Hz period), what clock prescale and output output compare values do we need?"
My confusion is:
why it says "4Hz period"? isn't Hertz a measurement for frequency? why is it describing time period?

You are correct Hz is the unit for frequency. Frequency is changes per second so if you toggle a pin 4 times per second its frequency is 4Hz. The author was problably lazy and did not want to calculate the period time to 1/4 s

Hertz represents >> cycles per seconds in Metrical System SI system.
As mentioned above it tells you how many times a process, event anything else takes place. Mostly everything is measured in Hz because its convenient and has direct relation to time. So one can easily jump back and forth in units.
For the AVR has a system clock which is then prescaled to lower rates for use in different system peripherals. The event loop speed is also measured in Hertz. Currently on mine the loop execution time is 2.7 MHz so very fast loop.

Related

How to write a time difference function to STM32F4

i am working on STM32F4 and pretty new at it. I know basics of C but with more than 1 day research, i still not found a solution of this.
I simply want to make a delay function myself, processor runs at 168MHz ( HCLK ). So my intuition says that it produces 168x10^6 clock cycles at each seconds. So the method should be something like that,
1-Store current clock count to a variable
2-Time diff = ( clock value at any time - stored starting clock value ) / 168000000
This flow should give me time difference in terms of seconds and then i can use it to convert whatever i want.
But, unfortunately, despite it seems so easy, I just cant implement any methods to MCU.
I tried time.h but it did not work properly. For ex, clock() gave same result over and over, and time( the one returns seconds since 1970 ) gave hexadecimal 0xFFFFFFFF ( -1, I guess means error ) .
Thanks.
Edit : While writing i assumed that some func like clock() will return total clock count since the start of program flow, but now i think after 4Billion/168Million secs it will overflow uint32_t size. I am really confused.
The answer depends on the required precision and intervals.
For shorter intervals with sub-microsecond precision there is a cycle counter. Your suspicion is correct, it would overflow after 232/168*106 ~ 25.5 seconds.
For longer intervals there are timers that can be prescaled to support any possible subdivision of the 168 MHz clock. The most commonly used setup is the SysTick timer set to generate an interrupt at 1 kHz frequency, which increments a software counter. Reading this counter would give the number of milliseconds elapsed since startup. As it is usually a 32 bit counter, it would overflow after 49.7 days. The HAL library sets SysTick up this way, the counter can then be queried using the HAL_GetTick() function.
For even longer or more specialized timing requirements you can use the RTC peripheral which keeps calendar time, or the TIM peripherals (basic, general and advanced timers), these have their own prescalers, and they can be arranged in a master-slave setup to give almost arbitrary precision and intervals.

STM32F4 - Using a timer to control non-adjacent timer

My processor is an STM32F437ZGT6 and I wish to count two different pulse trains (RPM). The range is quite wide, I may have an engine that idles at 150 rpm and we get a pulse from the cam, so 0.5 pulses per revolution, or 1.25 pulses per second. At the other extreme I may need to count 460 flywheel teeth at 3000 rpm, 23000 pulses per second. I have a prescaler available so I can divide the external event by up to 8 but even so this become too intense at higher speeds because every event or eight event causes an interrupt.
One alternative I am considering would be to have one timer use the external event as the clock and it would just count events within a time window. My difficulty comes from determining how to use another timer to control the window by setting and clearing CEN or some similar action.
In RM0090, section 18.3.15 Timer synchronization the example shows one timer controlling another, timer 1 controlling timer two. I thought that may be useable but althought I did not read otherwise I don't see that any two timers could be paired. The signal I am interested in actually feeds two timers. TIM1 ch1 and TIM9 ch1.
Any suggestions would be appreciated as I don't want to cobble up some Rube Goldberg scheme where one timer fires off an ISR and then the ISR opens and closes the time window.
I should have noted that a lookup table is provided that provides the expected engine speed and the number of pulses per revolution.
Thanks,
jh
If you want to just count external events, you can select external clock source for timer. (Point "Clock selection" of reference manual). SPL should have an example.
And read count from Tim CNT register every time you need.
The problem here is to read counts often enough.
Usually auto-reload register is 2 bytes so you have up to 2 ^ 16 counts before overflow, and loosing counted value.
Timers 2 and 5 have 4 bytes auto-reload registers so you have up to 2 ^ 32 counts.
If you need more then 2 ^ 32 counts you have at least two ways:
  - Timer cascade, by setting one timer event as a clock for another.
You can find this in the reference manual as "Using one timer as prescaler for another timer".
Cascading offers you up to 2 ^ 64 timer.
There is an example for SPL in "TIM_CascadeSynchro" folder.
  - Less beautiful, but more easy way is to create a counter variable and, increment it in timer irq handler.
Number of counts may be found as cnt_variable * TIMx-> ARR.
Several cascaded variables give the unlimited counter).
Thanks for the post. I will try to add a little detail. RPM 1 is fed into TIM3 ch2 and TIM4 ch1. RPM 2 is fed into TIM1 ch1 and Tim9 ch1. Both have a range of 1.25 pulses per second up to 30000 pulses per second. I am given the number of pulses per revolution which can range from 0.5 to 460 and the expected engine rpm, 150 - 3000 rpm so I can scale things a bit. The reason for feeding two different timers is to be able to use different counting techniques based on speed (pulses per second). For low speed I can capture events (pulses) and grab the timer count using an ISR. But when the pulse count gets high I want to use a different method so as not to incur more than 1000 interrupts per second per channel. So my idea there is to have one timer control another. One timer would simply count events without generating interrupts. The second counter would control the period of time that the first timer would be allowed to collect events.
Thanks,
jh
Seems like you need: timer synchronization with enabling/disabling slave timer according to the trigger output of master timer.
Description can be found in the following sections of RM0090:
18.3.14 Timers and external trigger synchronization in paragraph Slave mode: Gated mode
18.3.15 Timer synchronization in paragraph Using one timer to enable another timer
Also good explanation can be found in TIMx register section for registers TIMx_SMCR: bits TS and SMS; TIMx_CR2: bits MMS.
TIMx internal trigger connection (tables 93, 97 and 100) сontains possible connections of the trigger output of one timer with the input of another. Timers that you can use as master are marked in the picture below:
TIM_ExtTriggerSynchro example from SPL library can be used for code copy-paste.
I think the best way is:
Set RPM pins as external clock source for slave timer.
Set enabling/disabling of slave timer from the output compare of master timer. So changing TIMx_CCRx register value you can change duration of measurement.
Set master timer interrupts on update event (maybe on few events TIMx_RCR register).
Do all the calculations in master timer interrupt handler
Also it seems to me that you can just use 16 bit timer as RPM counter. Even on 30000 pulses you will have overflow every 2^16/30000 = 2,18 seconds which is rarely rare for STM32F4 clock frequencies. And use other timer, with, for example, 2 second period, interrupt for calculations.
Good luck!

C - Hertz to Seconds and how to get the proper time for a delay?

I am playing around with a PIC 24 and currently I have a bit of a problem with converting hertz to seconds and then using it as a delay for a signal send to a piezo piece(buzzer, zoomer, speaker, etc) and I would like to make it play certain notes.
I want to know if I am doing my conversion from hertz to seconds(mseconds in the code provided) and if I am doing my signal processing properly.
Here is the code where I am troubled with:
My hertz to int conversion:
int16 note(int i)
{
float time = (1.0/i);
int fin = ((time/2) * 1000);
return fin;
}
and here is how I send the signal to the pic24 I am using:
void main()
{
InitMCU();
output_high(PIN_D1);
delay_ms(note(E));
output_low(PIN_D1);
delay_ms(200);
output_high(PIN_D1);
delay_ms(note(E));
output_low(PIN_D1);
delay_ms(200);
}
Here is how I have defined the notes:
#define C 255 //do
#define D 227 //re
#define E 204 //mi
#define F 191
#define G 170
#define A 153
#define B 136
#define C2 127
You need a loop!
repeat for note length:
on
delay
off
delay
Also consider calculating the required period for each note off-line and enter it as an integer instead of in Hz - the CPU wont be wasting time in floating point calculations
first off you are trying to use square waves to make sine waves. So it is always going to sound a bit wrong if you aim specifically for the target frequency with the timer. make a 440Hz square wave it doesnt "sound" like a 440Hz sine wave. Maybe the physics will round it off but, I am betting not as much as you want.
You can if you have the speed. Do the one bit DAC thing from the 90s or whenever that was. If you can make your square waves go faster than the speaker can physically move you can say sprinkle more ones than zeros for a while say pushing the speaker out a bit at a controlled rate then more zeros than ones for a while teasing the speaker in. The speaker becomes a physical low pass filter. You can probably use the PWM in the microcontroller to help with this. But you need to dynamically change it and this is PIC so you are likely to run out of resources before you can code up a lot of tables for clean sound.
To do the square wave thing, you need to change the output pin at half the frequency. Do not do the calculations at runtime, do then on your calculator or let the toolchain do it. Say you are running your processor/timer at 1Mhz, and you want 440Hz on a pin. You need the period to be 1/440. hz is cycles per second so inverting that makes it seconds per cycle. 0.00227272 (repeating) seconds per cycle or period, so you need it high for half and low for half (or vice versa, doesnt matter) so
that means 0.00113636... between output state changes. If your timer was 1Mhz that is 1/1Million seconds per cycle. Or one microsecond. how many microseconds in 0.00113636... 1136. So every 1136 timer ticks you change state, you read the docs on the timer and have it count down or up or whatever 1136 counts (usually these are zero based numbers so 1135 and then count the zero and then the interrupt or status flag or whatever). you can also probably poll a counter that counts to/from all ones to/from all zeros and rolls over, subtract then from now and mask it with the number of bits that are counting and the difference is the time. with a 16 bit counter (start-now)&0xFFFF is the difference so long as your desired time is enough less than 0xFFFF. 1136 would certainly be. wait until the start minus now (if it is a down counter or now mins start if up counter).
Pre-compute your count times for a half cycle of each of these frequencies you want. when you make a tone you have to in some way loop every cycle on for the half period, off for half period, on for half period off for half period.
Depending on the speaker and your frequency it should sorta work. If you want to try the one bit thing
https://en.wikipedia.org/wiki/1-bit_DAC
you could start with a triangle wave do a say 66% duty cycle for 1/4th of the 1136 microseconds, a 33% duty cycle for 1/2 of the 1136 microseconds then 66% for the final 1/4th. Or one time do a 1/4th then do 1/2 at one duty cycle then 1/2 at another. You should be able to find or write a low pass filter, not that you would know what the speaker properties are but you can get a feel for how to generate the slower wave within the higher. After a triangle you could try a trapezoid. ramp up at some rate, do a 50% for a bit, then ramp down, repeat for the other half of the period.
For experimental purposes, find or pre-compute a sequence covering the whole period, you could have code that generates some few hundred or thousand lines of code, with a pic you can be fairly if not exactly deterministic X number of microseconds can be achived by executing exactly Y number of instructions or the right mix of Y instructions like
on
on
off
on
off
on
on
off
then the last instruction jumps to the top, again experimental, but you may find if you do it right you get a cleaner sound, perhaps much cleaner than a square wave.
you can add a simple R/C filter, literally two components, to convert your bit stream into an analog waveform that you then feed the speaker or amplify then feed the speaker, the feature here is you can look at it on a scope.
The other path you can take on the cheap and easy is a resistor ladder, instead of one bit you output basically the analog value for that place in the period and use a resistor ladder to turn that into an analog signal.
Or just use a real dac. based on how fast you can feed the dac pre-compute the number of values you need to send for one period, and make a table and just send them, in a loop until you are done with that frequency.
so with all that back to your code. you are trying to use some I guess millisecond library function? so lets say that is what you want to do.
440Hz as we saw is 0.00113636 seconds for a half period, so that would be 1millisecond on then one millisecond off, your code should do this
for(i=0;i<nperiods;i++)
{
on
delay_ms(1)
off
delay_ms(1)
}
any other delays in there just make it wrong...for a square wave. for others then I doubt you will have hardcoded delays.
So there are a number of problems with the above, first off a millisecond delay is way to slow for what you are trying you need a microsecond delay and you need to understand how long it takes for the overhead in the loop, our math showed 1136 microseconds for 440hz, with some truncating of accuracy. but the code that does the delay, esp on a slow mcu like this takes many clock cycles, if this is C code and not asm then many many more, plus the code to turn the gpio pin on and off, you have to subtract/tune those out. A scope will help, if you start off with 1136 and the scope is showing a period of 3000us instead of 2272.7 then you need to subtract that out and try again. so a delay of 772 instead of 1136. that kind of thing.
Middle C is 261.6Hz according to google, right or wrong lets run with it. that is 3823 microseconds. feeding your note function 255, which I assume is what the defines are for gives 1.9 I assume milliseconds. which is right as far as milliseconds goes. which gets truncated to 1 millisecond or 2000 microseconds which is 500hz which is of course way off. that define should have been 261 or 262 not 255 anyway right?
hmmm so you are trying to make a high pulse then a fixed length low pulse of 200ms? so if you fed it note E and assumed that the code took no time to run. it would be high for 2 ms then low for 200, and assuming you repeated that that is a 1% duty cycle at the frequency of 1/201ms or 4.97...Hz, the piano frequencies
https://en.wikipedia.org/wiki/Piano_key_frequencies
dont show a note at 5hz. I am sure it is close to some harmonic down there, but pretty low.
A would be 3ms high 200 low or a frequency of 1/203ms or 4.9hz
Other than the math, doing runtime floating point on a pic (or anywhere that doesnt have an fpu) is extremely costly, the math alone probably takes longer than your entire cycle. absolutely no reason to compute that runtime. you could have easily made the defines with the math or used your calculator and made the defines with hardcoded hand computed numbers. It still wouldnt have worked with a fixed low period esp one that is so significantly large compared to the numbers you need. with millisecond delay assuming the code ran instantly. on delay 1ms off delay 1ms is 500hz. on, delay 2, off delay 2, 250hz, delay 3 is 166, delay 4 is 125 and so on. you are not going to hit many real notes assuming the code ran instantly which it doesnt and using a millisecond delay.
to make the pressure wave you want to basically have the speaker pushed out from its resting state for half the cycle and sucked back in from its resting state for half the cycle, ideally in a sine fashion so that it slowly goes out and comes back then pulls in and goes out. going from reseting state to out only will work sure, but you still need to have the duty cycle right to get close with a square wave. so understand the timers you have, with a pic you can easily hand code some loops that burn clock cycles as they are deterministic from what I remember. start with the frequency of your processor, what is it? how many processor cycles for one period of your note? same as the 440hz to 1mhz math above. 0.0011363636 times 1million (seconds per half period times ticks per second the seconds cancel out and you get ticks per half period math works on units just like numbers) if your mcu is running at 2million clock ticks per second then it is 2million times 0.001136363636...
THEN figure out how to turn it on wait that number of cpu clocks then off and wait that number of cpu clocks. feed that into your piezo or other and see how it sounds.
If you had 16 bit registers which I bet you dont but assuming a 1mhz clock you would
load reg with some number
top
subtract reg,1
compare with zero
branch to top
in assembly of course. assuming one clock cycle for the subtract and compare each then two for the branch lets say that is four per loop, so 1136/4 = 284. load the register with the pre-computed value 284.
hand code some assembly
top:
gpio on
load reg,284
one:
sub reg,1
cmp reg,0
bne one
gpio off
load reg,284
two:
sub reg,1
cmp reg,0
bne two
jmp top
crude but it would get you started down the path.
if you dont have 16 bit registers but 8 bit instead, 1mhz 1136/0x100 = 4 remainder 112 that would come out quite nice if this processor takes 4 clocks per loop as I have fantasized above. each delay would be
mov reg,0xFF
A:
sub reg,1
cmp reg,0
bne A
mov reg,28
B:
sub reg,1
cmp reg,0
bne B
there are no doubt countless resources here and other places describing delay loops for the PIC family members.
You could just wing it and see the sounds change
#define DELX 300
volatile unsigned int x;
while(1)
{
output_high(PIN_D1);
for(x=0;x<DELX;x++) continue;
output_low(PIN_D1);
for(x=0;x<DELX;x++) continue;
}
and play with different numbers for the define. the tone should change, the quality may not be that great or maybe much better than what you have now, but it should change if audible at all. there are likely cliffs that you will hit I assume it is an 8 bit processor so counting to 200 is WAYY different then counting to 300, it is not going to be a frequency that is one and a half times lower. possible it wont be linear, might be depends on the compiler, but it might be linear segments with kinks here and there. 100 to 200 might be linear and 300 to 400 but 200 to 300 might not be.
This is probably linear though
volatile unsigned int x;
unsigned int y,z;
for(z=0;z<1000;z++)
for(y=0;y<100;y++)
{
output_high(PIN_D1);
for(x=0;x<z;x++) continue;
output_low(PIN_D1);
for(x=0;x<z;x++) continue;
}
The middle A note is normally a 440 Hz tone. If you toggle your piezo speaker on and off 440 times per second, the delay between successive toggles is 1/880 of a second, which is 1.13636363636 ms. This shows two things:
your calculations are way off; and
timer resolution of one millisecond is way too coarse for this application.
Of course you need a loop to play a tone with some duration.

Concept of clock tick and clock cycles

I have written a very small code to measure the time taken by my multiplication algorithm :
clock_t begin, end;
float time_spent;
begin = clock();
a = b*c;
end = clock();
time_spent = (float)(end - begin)/CLOCKS_PER_SEC;
I am working with mingw under Windows.
I am guessing that end = clock() will give me the clock ticks at that particular moment. Subtracting it from begin will give me clock ticks consumed by multiplication. When I divide with CLOCKS_PER_SEC, I will get the total amount of time.
My first question is: Is there a difference between clock ticks and clock cycle?
My algorithm here is so small that the difference end-begin is 0. Does this mean that my code execution time was less than 1 tick and that's why I am getting zero?
My first question is: Is there a difference between clock ticks and clock cycle?
Yes. A clock tick could be 1 millisecond or microsecond while the clock cycle could be 0.3 nanoseconds. On POSIX systems CLOCKS_PER_SEC must be defined as 1000000 (1 million). Note that if the CPU measurement cannot be obtained with microsecond resolution then the smallest jump in the return value from clock() will be larger than one.
My algorithm here is so small that the difference end-begin is 0. Does this mean that my code execution time was less than 1 tick and that's why I am getting zero?
Yes. To get a better reading I suggest that you loop enough iterations so that you measure over several seconds.
Answering the difference between clock tick and clock cycle from a systems perspective
Every processor is accompanied by a physical clock (usually quartz crystal clock), which oscillates at certain frequency (vibrations/sec). The processor keeps track of time by the help of interrupts generated from the physical clock, which interrupts the processor at every time period T. This interrupt is called a 'clock tick'. CPU counts the number of interrupts it has seen since the system has started, and returns that value when you call clock(). By taking a difference between two clock ticks values (obtained from clock()), you would get how many interrupts that were seen between those two time points.
Most of the modern operating systems program the T value to be 1 microsecond i.e. the physical clock interrupts at every 1 microsecond, this is the lowest clock granularity which is widely supported by most of the physical clocks. With 1 microsecond as T, the clock cycle can be calculated as 1000000 per second. So, with this information, you can calculate the time elapsed from the difference of two clock ticks values i.e. diff between two ticks * tick period
NOTE: clock cycle defined by the OS has to be <= vibrations/sec on the physical clock, otherwise there will be a loss of precision
four your first question: clock ticks refer to the main system clock. It is the smallest unit of time recognized by the device. clock cycle is the time taken for a full processor pulse to complete. this u can recognize by your cpu cpeed given in Hz. a 2GHz processor performs 2,000,000,000 clock cycles per second.
for your second question: probably yes.
A clock cycle is a clock tick.
A clock cycle is the speed of a computer processor, or CPU, and is determined by the amount of time between two pulses of an oscillator. Generally speaking, the higher number of pulses per second, the faster the computer processor will be able to process information.

Regarding timers in embedded C [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
So I am having my exam tomorrow. I missed a lecture but I have a recorded professor's lecture. During the lecture, the professor mentioned that we will need to know how Timers work within embedded procesors.
I have a basic understanding, however I am confused on the Math part. Professor said that for example he will give us a 12-bit timer running at some rate X. We will have to set the timer value initially and wait for it to overflow. If we want the timer to wait for 3 miliseconds, what do we set the timer to?
In addition, professor said that "it is a simple math, giving us clocks equal to 1,000,000 and the time will be 1000 so we can do divisions easily."
Can somebody please explain how timers exactly work and what would I need to do in order to get the math part correctly.
Most embedded timers work as follows:
set timer to some initial value, T
start timer
timer decrements once per timer clock
when timer reaches 0 (or underflows beyond 0) an interrupt is generated
So the elapsed time will just be T / timer_clock_rate, where T is the initial timer value and timer_clock_rate will depend on how you've configured the timer.
So for example if you want a 3 ms delay and your timer clock rate is 1 MHz (i.e. the timer decrements once every 1 µs) then you need an initial timer value of 3000 (3000 x 1 µs = 3 ms).
EDIT: see also #Rev1.0's answer - apparently AVR timers count up rather than down - note that some other micro-controller families use count down timers. The same general principle applies to both however, but the initial constant that you would load will be different depending on whether you are counting up or down.
While Paul's example maybe sufficient for you to get the idea how it works, it addresses the problem somewhat different from what your question suggested.
The mentioned overflow occurs when the timer reaches the maximum value. That would be 4096 for a 12 bit timer (2^12). Having a given clock of 1MHz (1us per tick) you have to count to 3000 to get 3ms like Paul already pointed out.
So you would set the initial value of the timer to 4096 - 3000 = 1096 to get an overflow after 3ms.
Just follow the dimensions. X is cycles per second, assume that one tick is one cycle (if there is a prescaler, then there is another adjustment here, the timer counts in ticks). And one second is 1000 milliseconds. so just arrange all of these dimensions so that they cancel out leaving only the one you want
1 tick X cycles 1 second 3 milliseconds
-------- * -------- * ----------------- * --------------
1 cycles 1 second 1000 milliseconds
cancel out all the units divided by themselves. from grade school math (almost) anything divided by itself is one, just apply that to units. leaving:
1 tick X 1 3
------ * --- * ----- * ---
1 1 1000
So whatever your timer clock source frequency is in cycles per second (Hz) is multiplied by 3 and divided by 1000. If that clock frequency is 1000000 then (1000000*3)/1000 = 3000.
That is how you can easily figure out what is multiplied and what is divided, works for every flavor of conversion. Miles per hour to kilometers per second, whatever.
then just follow Rev1.0's answer or Paul R.
Sometimes there is an N-1 thing you have to be aware of which is either documented or you can test for. For example if you have a down counter the docs will/should say if the timer rolls over or interrupts WHEN it reaches zero or AFTER, usually they are AFTER, when the actual roll over happens, so 3000 to 0 inclusive is 3001 counts, you are off by a little, so for a system like that you need to program the timer with 2999 to get 3000 ticks. For an up counter it is usually one of two ways, it counts from zero to the programmed value, same deal count from 0 to 2999 to get 3000 counts so you would probably program a 2999 in the register not 3000. Or the value you program is the start count as Rev1.0 showed, and the rollover is after the all ones value for whatever the register size is, in this case they tell you 12 bits which is 0xFFF, dont make the 0xFFF - 3000 mistake and get 1095, easy to do it the way Rev1.0 shows (0xFFF+1)-3000 = 4096-3000 = 1096 that is your start count.
Same goes for prescalers, you have to be very careful to read what they are saying do you program a 2 to divide by 2 or program a 1 to divide by 2? What happens if you program a 0 is that a divide by 1 or invalid or a divide by the max value, or an invalid divisor setting? Where does that fit into the dimensional analysis? ticks / cycles. A prescaler that divides by 8 means that for every 8 cycles you get one tick, so that is a 1 tick / 8 cycles.
Now sometimes you will have a system clock that divides down for the peripheral clock and the the peripheral clock is what feeds the timer, then you may have a prescaler there so n system clocks / 1 peripheral clock, then 1 peripheral clock / 1 timer clock, then 1 tick is M timer clocks. Get everything lined up so all but one cancels out and there you go.
You can do this in reverse as well and will and should. From the numbers we have right now 3000 timer ticks is 3ms or 0.003 seconds. 3000/0.003 is ticks per second or cycles per second of 1000000.
But what if we had a different controller or one with a clock we didnt know (or we have a crystal we know but we suspect there is a prescaler somewhere we cant find in the docs) so let the timer roll over 4096 ticks for example, we measure that with a stopwatch or oscilloscope or something, not that accurate in either case but might give us a rough enough idea to figure out if there is a prescaler or what clock we are actually running on if there is a pll multiplying the clock, etc. Say it was 0.0005 seconds for every 4096 timer ticks, 4096/0.0005 = 8192000 hz. Now if the crystal/oscillator in the schematic or we can read off of the part says 16Mhz that would make some sense 8000000/4096 = 0.000512 and 8Mhz is half of 16Mhz, so your measurement is probably off by a smidge and the clock has some accuracy as well and may be off by some amount. So you check the docs to see if there is an internal oscillator, if not then you are probably running off of the 16Mhz clock but there is a divide by 2 that is documented and you have not found it or isnt documented (it happens some times) and your timer is running off of system clock/2. Now you can use that number as X and figure out whatever you need. Why not have the timer count to 1000 or some other number that is easier to compute. that is fine too, but can take more work and more experiments, sometimes you have a free running timer you cannot reset at a some max or min count and instead you can just say
while(1)
{
while((read_timer()&0x1000)==0) continue;
turn_gpio_on();
while((read_timer()&0x1000)!=0) continue;
turn_gpio_off();
}
Measure the on time or the off time and that is 0x1000 ticks. hex not as pretty a number as 1000 decimal when doing decimal math on your calculator, but it is pretty when you can simply use an and operation with one bit to toggle the gpio/led.
This last point being, you can read the docs and schematics and think you know how it is working, but you should test your results, and if you are off by some whole multiple, esp if it is a power of two either your math was wrong by some whole number or there is a clock divisor somewhere in the chip you dont know about or have not looked hard enough to find, this could also mean you may have thought you boosted the crystal speed to some other speed using the pll, and maybe there is a mistake there and everything in the chip is not running at the desired speed.
(if this answer is useful to you then upvote Paul and Rev1.0 before upvoting me, thanks, just expanding on their answers).

Resources