'Picaxe 08m2
'polls pwm signal from master picaxe to get 1/2000th of a second resolution
'pwm signal from master picaxe to timer picaxe pin C.2 (leg 5)
'run signal from master picaxe to timer picaxe pin C.3(leg 3) is normally low / high means run the timer
'MAX7219 code from westaust55 tutorial
'MAX7219 DIn on C.0(leg7)
'MAX7219 LOAD(also called CS) on C.1(leg6)
'MAX7219 CLK on C.4(leg3)
'Max7219 code by westaust55
#picaxe 08m2
'#terminal 38400 'for sertxd to work at M32
#no_data
setfreq M32 'run as fast as possible
; MAX7219 Registers - Note we are only using 4 of the 8 possible 7-seg digits
SYMBOL No_Op = 0
SYMBOL Digit0 = 1
SYMBOL Digit1 = 2
SYMBOL Digit2 = 3
SYMBOL Digit3 = 4 ; for more digits, dig4 thru dig7 = 5 to 8 respectively
SYMBOL Decode = 9
SYMBOL Intens = 10
SYMBOL ScanLim = 11
SYMBOL ShutDwn = 12
SYMBOL DigTest = 15
;
; MAX7219 Data Constants
SYMBOL Set_Off = 0
SYMBOL Set_On = 1
SYMBOL No_Digits = 3 ; Scan limit for digits 0 to 3 = 4
SYMBOL Dec_Digits = 15 ; decode digits 0 to 3 according to "code B"
SYMBOL Init_Inten = 8 ; 0 (=1/32 PWM on time) to 15 (=31/32 PWM on time)
SYMBOL DigBlank = 15 ; "Code B" value to black a digit
SYMBOL DecimPnt = 128 ; Add this value to a digit value/code when we want the demical point illuminated
SYMBOL Decimal = 10
SYMBOL Hexadec = 16
; Define variables
SYMBOL Data_7219 = b0 'bits 7-0
SYMBOL Register = b1 'bits 15-8
SYMBOL Counter = w2 ; w2 = b5:b4
SYMBOL Thous = b6
SYMBOL Hundr = b7
SYMBOL Tens = b8
SYMBOL Units = b9
SYMBOL Blanking = b10
SYMBOL Base = b11
SYMBOL dummy = b12
SYMBOL PWM_in = pinC.2 '2 KHz signal from master
SYMBOL run_signal = pinC.3 ' Start signal; 1=start
; Control signal lines from PICAXE to MAX7219
SYMBOL DIn_7219 = pinC.0 'leg 7
SYMBOL Load_7219 = C.1 'leg 6
SYMBOL Clk_7219 = C.4 'leg 3
disabletime 'might help
disconnect
Init:
dirsc = %00010011 ' C.0,C.1,C.4 outputs
LOW Load_7219
LOW Clk_7219
DIn_7219 = 0
Base = Decimal
Blanking = Set_On
GOSUB Initialise7219
GOSUB DisplayTest
'-----------------------------------Timer code -------------------------------------------------------
top:
counter = 0 ' Clear timer
hold:
if run_signal = 0 then hold
timing:
if run_signal = 0 then finish ' If run signal goes low were done timing
here:
inc counter
pulsin C.2,0,dummy 'wait until trailing edge of pulse
goto timing ' Loop until race over.
finish:
counter = counter / 2 'adjust for 2KHz clock
if counter < 5 then 'less than .005 seconds resets the display to all zeros
counter = 0
endif
'sertxd(#counter,13,10)
GOSUB CalcDigits
Thous = Thous OR DecimPnt ; turn on the decimal point for digit0 just to show how it can be done
GOSUB SetDigitDisplay
counter = 0 ' Clear timer
goto hold
'-------------------------------end of Timer code-----------------------------------------------------
;===============================================
; Subroutines
;===============================================
; Subroutine to initialise the MAX7219 7-Seg LED display driver
Initialise7219:
Register = Decode : Data_7219 = Dec_Digits : GOSUB ShiftTo7219
Register = Intens : Data_7219 = Init_Inten : GOSUB ShiftTo7219
Register = ScanLim : Data_7219 = No_Digits : GOSUB ShiftTo7219
Register = ShutDwn : Data_7219 = Set_On : GOSUB ShiftTo7219
Register = DigTest : Data_7219 = Set_Off : GOSUB ShiftTo7219
; subroutine to send the data for display on the 4 digits to the MAX7219
; leading zero blanking applied when the blanking flag is set to "on"
SetDigitDisplay:
IF Blanking = Set_On THEN
IF base = decimal THEN
IF Thous = 0 THEN
Thous = DigBlank
IF Hundr = 0 THEN
Hundr = DigBlank
IF Tens = 0 THEN
Tens = DigBlank
ENDIF
ENDIF
ENDIF
ELSEIF base = Hexadec THEN
IF Thous = $7E THEN
Thous = 0
IF Hundr = $7E THEN
Hundr = 0
IF Tens = $7E THEN
Tens = 0
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
Register = Digit0 : Data_7219 = Units : GOSUB ShiftTo7219
Register = Digit1 : Data_7219 = Tens : GOSUB ShiftTo7219
Register = Digit2 : Data_7219 = Hundr : GOSUB ShiftTo7219
Register = Digit3 : Data_7219 = Thous : GOSUB ShiftTo7219
RETURN
; Subroutine to turn on all LED segments on the display as a test
DisplayTest:
Register = DigTest : Data_7219 = Set_On : GOSUB ShiftTo7219
PAUSE 5000
Register = DigTest : Data_7219 = Set_Off : GOSUB ShiftTo7219
PAUSE 1000
RETURN
; Subroutine to shift the register address and data value out to the MAX7219
; Tests have identified that the MAX7219 incoming data is clocked in through the lsb towards the msb.
; If only one MAX7219 is conencted then the first four significant bits of data can be ignored to
; improve the data transfer speed by 25%
;
ShiftTo7219:
; PULSOUT Clk_7219, 1 ; bit 15 is don't care - enable if two or more MAX7219 are cascaded together
; PULSOUT Clk_7219, 1 ; bit 14 is don't care
; PULSOUT Clk_7219, 1 ; bit 13 is don't care
; PULSOUT Clk_7219, 1 ; bit 12 is don't care
DIn_7219 = bit11 : PULSOUT Clk_7219, 1
DIn_7219 = bit10 : PULSOUT Clk_7219, 1
DIn_7219 = bit9 : PULSOUT Clk_7219, 1
DIn_7219 = bit8 : PULSOUT Clk_7219, 1
DIn_7219 = bit7 : PULSOUT Clk_7219, 1
DIn_7219 = bit6 : PULSOUT Clk_7219, 1
DIn_7219 = bit5 : PULSOUT Clk_7219, 1
DIn_7219 = bit4 : PULSOUT Clk_7219, 1
DIn_7219 = bit3 : PULSOUT Clk_7219, 1
DIn_7219 = bit2 : PULSOUT Clk_7219, 1
DIn_7219 = bit1 : PULSOUT Clk_7219, 1
DIn_7219 = bit0 : PULSOUT Clk_7219, 1
PULSOUT Load_7219, 1 ' minimum high duration is 50 ns -still okay at 64 MHz
RETURN
; Calculate (Extract) the individual digits for the current value
CalcDigits:
Thous = Counter / Base / Base / Base
Hundr = Counter / Base / Base //Base
Tens = Counter / Base // Base
Units = Counter // Base
RETURN