I would like to use the the number of oscillator periods for each instruction in delay calculations for instructions like NOP etc.
When they say frequencies for the processor that is one cycle for every processor cycle. Typically for M series chips they have a phased locked loop driving the CPU and use either an external or internal oscillator which can have a much lower frequency than the CPU.
Correct me if I'm wrong daith, but using the crystal and NOP for delays is not really a good practice.
I think it'd be simpler, more portable, and less error prone to use a timer for that...
If for a reason or another (like having to change the XTAL, or clock speed because of some peripheral needs something else) you change the master clock, the last thing a developer wants is having to go through all the code to tweak NOPs...
Instruction cycle timing information can be found in Chapter 18 of the Cortex-M3 Technical Reference Manual. But note very carefully the wording in section 18.1 about the effect which the system architecture plays in this.
That means that Alban is right (as usual!). You are much better advised to use a timer, like the standard SysTick timer, for timing delays on a Cortex-M3. The execution time of individual instructions is not only dependent on the individual processor implementation (so, for instance, it might be different in a Cortex-M4) but also on memory latency. Memory latency will vary, sometimes considerably, from device to device.
Hope this helps.
Chris
LOL. You are perfectly correct! For some very short delays, for instance where a device you're driving just needs to get its wits together to reply, it can be a saving to do a quick delay then check if the expected result comes back. If it does then one is on track and knows exactly what to do next. Otherwise the easiest thing is to just return and handle it as a general interrupt whenever the device responds. This can give a useful increase in speed sometimes. However it should only be done when the speed is very important.
If substituting an M3 for an 8051 I'd have though the best thing to do would be to use interrupts properly to start with and the speed would more than adequate. Longer times can be got using the system clock.
albanrampon, you're right about using a timer whenever possible.
But if you're working with high-speed delays, such as one or two clock cycle delays and your processor runs at more than 20 MHz, then you will need to know the exact timing. It's also necessary to know, in case you need to synchronize an interrupt to a timer. (that is what my sync snippet for Cortex-M0 is intended for; it can be modified to work on the Cortex-M3).
akshimmu - Normally you count 1 clock cycle per NOP instruction. That could be one oscillator clock cycle, if you've set the PLL to use the main crystal as a 1:1 clock source. But as mentioned in the other answers, you can use the PLL to generate for instance 100 MHz from a 12 MHz clock crystal on the LPC1768 (good choice BTW).
So if you've chosen to run the microcontroller at 100 MHz, then 1 NOP instruction will take 1 clock cycle. If your external crystal is a 10 MHz crystal, then it means that your NOP instruction is basically using 1/10 "crystal" clock cycle.
BUT. You also have another factor, the Flash wait-states. If you're running your program from SRAM, then you won't need to worry about it, because the SRAM is zero wait-state. But the Flash memory may want to delay your instructions with something between 2 and 5 clock cycles, depending on your speed. (Normally 3 or 4, though).
If timing is critical, such as you need to make sure the GPIO pins gets the data at an exact clock cycle number, then copy your time-critical part of your code to SRAM (or even better: Use a linker-script to place selected parts of your code in SRAM), then you will not have to worry about that anymore.
Now, if you're coming from an 8051, which spends several cycles per instruction, your best choice would be as Alban says: Use a timer. You don't necessarily have to use an interrupt; you may manually poll the Timer Counter too. Using an interrupt, though, is a good idea. Also remember that in many cases, you can use the DMA to do the jobs for you. Eg. You can set up a memory-to-GPIO transfer and synchronize the DMA to a timer, so your data-stream will not suddenly be delayed by interrupt-hickups.