Home‎ > ‎Homebrew‎ > ‎PICs in Radio‎ > ‎

### PIC Basics - Timing and Delays

 There are many sites and books (I've referred you to two already) but here are my musings - THERE IS NO CODE HERE YET!PICs need an Oscillator, this can be built in or external (Crystal or RC). The Oscillator frequency is not the same as the PICs internal timing frequency (the instruction cycle), in fact the instruction cycle is a quarter of the oscillator frequency. So for a 4 MHz oscillator, we see the PIC 'working at' 1 MHz - referred to as the instruction cycle or clock.To time things we count the number of instruction cycles, so 1,000,000 cycles will be one second. That's great. we can be very,very accurate with timing but counting a million in binary would require 20 bits (honest: 11110100001001000000) and most PICs only use 8 bits (255 in decimal).There are ways to make PICs count to higher numbers but there is an inbuilt prescaler (divider) especially for the clock. Using this we can divide the clock by either 2,4,8,16,32,64,128 or 256. So if we set our Prescaler to 4 our clock would be = 4 MHz/4/4 = 250 kHzIf we set the Prescaler to 256 we would get 4 MHz/4/256 = 3.90625 kHzNow as Frequency = 1 / Time so Time = 1 / Frequency3.90625 KHz gives us a clock time of 256 us or 0.256 ms - just over a quarter of a millisecond.That's still a very small amount of time.But I can prescale that even further!This needs to be done with code rather than setting a value for the PIC,  it effectively counts a number of clock pulses before returning to do what you want to do.Example (STILL NO CODE!!!)I want to send lots of morse code dits (using a buzzer) one after the other, I want each dit to be 10ms long. Now 10ms is 39 * 0.256ms (39=10ms/0.256ms) so if we count 39 clock pulses before we move on we will have waited 10ms, let's see.... I'm going to use line numbers to show the flow, note this is not code...1    Set the PIC prescaler to 2562    Turn on the buzzer3    Set my count to 394    Take one away from the count5    Is the result equal to 0 (have I counted 39 times?)6    No - go back to take another one from the count - go to step 47    Yes - we have counted 39 clocks and waited 39 * 0.256ms = 10ms so carry on8    Turn off the buzzerThat works well as a walk through, can you spot the loop? Line 6 loops back to Line 4 if the answer was No. We could put another loop in there to repeat the same code for ever1    Set the PIC prescaler to 2562    Turn on the buzzer3    Set my count to 394    Take one away from the count5    Is the result equal to 0 (have I counted 39 times?)6    No - go back to take another one from the count - go to step 47    Yes - we have counted 39 clocks and waited 39 * 0.256ms = 10ms so carry on8    Turn off the buzzer9    Set my count to 3910    Take one away from the count11    Is the result equal to 0 (have I counted 39 times?)12    No - go back to take another one from the count - go to step 1013    Yes - we have counted 39 clocks and waited 39 * 0.256ms = 10ms so carry on14     Go to line 2 to repeat it all againNow we can see where the tasks are repeated - extra typing means extra code and more PIC memory taken up so we could put the repeated steps into its own little block and just call upon is usefulness when we need it1    Set the PIC prescaler to 2562    Turn on the buzzer3    Call upon the waiting code - go to line 74    Turn off the buzzer5    Call upon the waiting code - go to line 76     Go to line 2 to repeat it all againThe waiting code is here 7    Set my count to 398    Take one away from the count9    Is the result equal to 0 (have I counted 39 times?)10  No - go back to take another one from the count - go to step 811  Yes - we have counted 39 clocks and waited 39 * 0.256ms = 10ms so carry on where we left offCan you see how that works? To assist, get a pen and a piece of paper and move along the paper for each step switching the buzzer on and off and seeing the counts go down from 39 (you'll get bored of counting from 39 down but you'll see the picture!)So now you know how to create a delay of 10ms using a LOOP and a CALL to another task list which is technically a SUBROUTINE.Can you rewrite it for a dash? There are a couple of ways!