Introduction #
These code snippets put together some previous tips to demonstrate how to pause and toggle pins with PASM!
The examples here are deliberately verbose and include comments to describe each line of code, but if you have any questions please reach out at our forums!
The code assumes you are using the Parallax Propeller FLiP module, or the Parallax Propeller Activity Board. We toggle the LEDs that are included in those boards as a simple way of demonstrating the pause duration. Simply copy/paste this code into your favourite Propeller SPIN compiler, then load the code into your Propeller 1!
Example code - milliseconds #
This code includes a milliseconds pause routine, so it will allow you to create pauses long enough to be visually identified by the LEDs flashing on and off!
spin
CON { System timing }
_XINFREQ = 5_000_000
_CLKMODE = XTAL1 + PLL16X
CON { IO Pins - Assumes FLiP module or Propeller Activity Board }
LEDA = 26
LEDB = 27
' ----------------------------------------------------------------------------------------------------
PUB start
' Initialization
MS_TICKS := clkfreq / 1_000 ' Pre-calculate the ticks duration of 1mS based on system clock
LEDA_mask := |< LEDA ' Create mask representing the LEDA pin number
LEDB_mask := |< LEDB ' Create mask representing the LEDB pin number
dira[LEDA]:= 0 ' Float pins before passing to cog
dira[LEDB]:= 0 ' - not essential in this demo as the pins had not been used yet!
cognew(@PauseDemo,0) ' Start the pause demo code running in 2nd processor cog
repeat ' Repeat here doing nothing
waitcnt(0) ' - in real code, you'd probably do something here!
' ----------------------------------------------------------------------------------------------------
DAT { PASM - PauseDemo }
PauseDemo org 0 ' Begin at Cog RAM addr 0
or dira, LEDA_mask ' Set pin to output
or outa, LEDA_mask ' Set pin to high
or dira, LEDB_mask ' Set pin to output
andn outa, LEDB_mask ' Set pin to low (default state - just showing how to do it!)
demoloop mov msecs, #125 ' Set 125mS pause
call #pausems ' Call pause routine; returns here when done
xor outa, LEDA_mask ' Toggle state of pin LEDA
xor outa, LEDB_mask ' Toggle state of pin LEDB
jmp #demoloop ' Jump back to loop label; ie. start again!
' ---------------------
' Pause in milliseconds
' ---------------------
'
' Example use:
' mov msecs, #100 ' set 100mS pause
' call #pausems
pausems mov mstimer, MS_TICKS ' set timer for 1ms
add mstimer, cnt ' sync with system clock
msloop waitcnt mstimer, MS_TICKS ' wait and reload
djnz msecs, #msloop ' update delay count
pausems_ret ret
' PASM / Global Variables
MS_TICKS long 0-0 ' ticks per ms
LEDA_mask long 0-0
LEDB_mask long 0-0
msecs res 1
mstimer res 1
FIT ' DAT PASM - PauseDemo
' ----------------------------------------------------------------------------------------------------
LEDs A and B will toggle on/off with a 125 millisecond pause between each change.
Example code - microseconds #
This version of the demo code includes a microseconds pause routine. The pause is so short that the two LEDs will appear to be always ON! But with an oscilloscope you will be able to measure and view the 150uS pulses.
spin
CON { System timing }
_XINFREQ = 5_000_000
_CLKMODE = XTAL1 + PLL16X
CON { IO Pins - Assumes FLiP module or Propeller Activity Board }
LEDA = 26
LEDB = 27
' ----------------------------------------------------------------------------------------------------
PUB start
' Initialization
US_TICKS := clkfreq / 1_000_000 ' Pre-calculate the ticks duration of 1uS based on system clock
LEDA_mask := |< LEDA ' Create mask representing the LEDA pin number
LEDB_mask := |< LEDB ' Create mask representing the LEDB pin number
dira[LEDA]:= 0 ' Float pins before passing to cog
dira[LEDB]:= 0 ' - not essential in this demo as the pins had not been used yet!
cognew(@PauseDemo,0) ' Start the pause demo code running in 2nd processor cog
repeat ' Repeat here doing nothing
waitcnt(0) ' - in real code, you'd probably do something here!
' ----------------------------------------------------------------------------------------------------
DAT { PASM - PauseDemo }
PauseDemo org 0 ' Begin at Cog RAM addr 0
or dira, LEDA_mask ' Set pin to output
or outa, LEDA_mask ' Set pin to high
or dira, LEDB_mask ' Set pin to output
andn outa, LEDB_mask ' Set pin to low (default state - just showing how to do it!)
demoloop mov usecs, #150 ' Set 150uS pause
call #pauseus ' Call pause routine; returns here when done
xor outa, LEDA_mask ' Toggle state of pin LEDA
xor outa, LEDB_mask ' Toggle state of pin LEDB
jmp #demoloop ' Jump back to loop label; ie. start again!
' ---------------------
' Pause in microseconds
' ---------------------
'
' Example use:
' mov usecs, #9 ' set 9uS pause
' call #pauseus
pauseus mov ustimer, US_TICKS ' set timer for 1us
add ustimer, cnt ' sync with system clock
usloop waitcnt ustimer, US_TICKS ' wait and reload
djnz usecs, #usloop ' update delay count
pauseus_ret ret
' PASM / Global Variables
US_TICKS long 0-0 ' ticks per us
LEDA_mask long 0-0
LEDB_mask long 0-0
usecs res 1
ustimer res 1
FIT ' DAT PASM - PauseDemo
' ----------------------------------------------------------------------------------------------------
LEDs A and B will toggle on/off with a 150 microsecond pause between each change. This will be too fast for the human eye, but you will be able to read the pulses with an oscilloscope.
Resources #
Parallax Propeller 1 Documentation