RM2H Let’s work with the SYSTEM CLOCK! Now we are going to move on to work with the system clock! Timing Delays with the System Clock Certain I/O operations are much easier to study with code that controls the timing of certain events, such as when an LED lights or how long a pushbutton is pressed. The three basic Spin building blocks for event timing are: 1. cnt – a register in the Propeller chip that counts system clock ticks. 2. clkfreq – a command that returns the Propeller chip’s system clock frequency in Hz.(Think of it is as a value that stores the number of Propeller system clock ticks in one second.) 3. waitcnt – a command that waits for the cnt register to get to a certain value. Essentially, this is the way waitcnt works: Lets use an example; waitcnt(clkfreq + cnt) ‘ causes the program to WAIT for 1 second, then move on. To create a delay that lasts only a FRACTION of a second, the code would look like this; waitcnt(clkfreq/3 + cnt) ‘ this command causes a delay for 1/3 of a second, then moves on. If we really want to get fancy, we write; waitcnt(clkfreq/1000 + cnt) ‘ now it waits for 1 Millisecond before it moves on! Lets try writing some code for this: ‘File: LEDOnOffP20.spin PUB LEDOnOff dira[20] := 1 repeat outa[20] := 1 waitcnt(clkfreq/4 + cnt) outa[20] := 0 waitcnt(clkfreq/4*3 + cnt) Load the program LEDOnOffP16.spin into RAM or EEPROM by selecting F10 or F11. So what happened? 1. Is the LED flashing? 2. Can you figure out what the flash rate is? (for example..how long does it stay on then go off?) 3. Put your BRAIN in GEAR! Can you figure out a way to make the LED Stay on for 1 second and stay OFF for 3 seconds? TRY IT! INDENTATION IS CRITICAL! In case you have missed it, indentation when writing spin code is VERY important! Whenever you have commands that need to be linked together such as commands that follow a repeat command, be sure the code below is INDENTED to avoid unexpected results! The BLUE area shown below should be shown in GREY in the Parallax Propeller Tool program when indenting! repeat outa[20] := 1 waitcnt(clkfreq/4 + cnt) outa[20] := 0 waitcnt(clkfreq/4*3 + cnt) Quick info on the waitcnt command: If you write the code: waitcnt(clkfreq + cnt) it’s the SAME as waitcnt(12_000_000 + cnt) Essentially, it’s the Propeller chips DEFAULT clock. If we want to change the system clock to speed it up or slow it down, we use special code in the CON block to do that. Be aware that if NO Clock Config Constant (CON) is set, the Propeller will use the default setting. Let’s take a look in the next slide! Let’s break down the SPECIFICS! CON _xinfreq = 5_000_000 _clkmode = xtal1 + pll16x The code is broken down like this; _xinfreq = 5_000_000 ‘ defines the expected frequency from the crystal (Oscillator) on the circuit board. (It’s the silver looking can) In our case the crystal is 5 Mhz (5 Megahertz = 5 Million cycles per second) _clkmode = xtal1 + pll16x ‘ _clkmode sets the chip into clock mode. xtal1 configures the PROP chip to work with our external crystal. Pll16x tells the PROP chip to set its Phase Locked Loop (pll) circuitry to multiply the 5Mhz crystal value X 16. …………... so 16 X 5Mhz = 80 Mhz! That’s Pretty Cool STUFF! Now you know how to change the time on a PROP chip so that you can make the chip turn something ON or OFF at a rate you want! Just think..it only takes a little math to make this chip do some interesting things! ***IMPORTANT*** The EXTERNAL crystal is ACCURATE when used with correctly written code…. HOWEVER, the PROP chips INTERNAL timing is NOT very accurate. SO….If you want to make something work within a timing sequence and you want the time to be accurate…you need to use the EXTERNAL CRYSTAL to set the timing. (This means you have to write the CON block of code to set the external crystal to work!) Let’s write some code to try this out! ‘’File: ConstantBlinkRate.spin CON _xinfreq = 5_000_000 _clkmode = xtal1 + pll16x PUB LEDonOFF dira[16] := 1 repeat outa[16] := 1 waitcnt (clkfreq/2 + cnt) outa[16] := 0 waitcnt (clkfreq/2 + cnt) Load the program ConstantBlinkRate.spin into RAM or EEPROM by selecting F10 or F11. So what happened? 1. Is the LED connected to P20 flashing? 2. Is it flashing 1 time every second? (remember that 1 flash per second = 1 Hz) 3. Can you explain how the PROP knows to flash the LED one time per second? See the next slide to break it down a little further! A little more info on clkfreq: When you write the code; waitcnt(clkfreq/2 + cnt) ‘ the waitcnt is like a pause while the cnt register counts clock ticks. The clkfreq command returns the number of ticks PER SECOND (Based on the PROP chips clock settings) So…even though the _clkmode = xtal1 + pll16x tells the PROP to run at 80 Mhz, this has NO effect on the flash rate. This is just telling the PROP chip at what speed to run! Let’s make a change in the code and test it out! ‘File: ConstantBlinkRate.spin CON _xinfreq = 5_000_000 _clkmode = xtal1 + pll8x PUB LEDonOFF Only 1 change was made in your previous code! Change your 16 to an 8. (This sets the system clock to run at 40 Mhz instead of 80Mhz) dira[20] := 1 repeat outa[20] := 1 waitcnt (clkfreq/2 + cnt) outa[20] := 0 waitcnt (clkfreq/2 + cnt) Download the code and see if there is a change in the flash rate of the LED. So what happened? 1. Did your flash rate remain the same? 2. What happens if you change the pll8x to pll4x or pll2x? Although an actual NUMBER can be used to replace the clkfreq command its use should be limited. clkfreq is used when PREDICTABLE DELAYS are essential! (This is very critical when you want an object to be used by another object!)