SUPER PROBE
MKII
P2


Home

P1

 
Kits are available for this project from Talking Electronics for $18.00 plus postage.

 

This page investigates the Super Probe program written by by Luhan Monat of mondo-technology.com.
The only way to investigate and diagnose such a complex program is to pull it apart and start from the beginning.
This program combines YEARS of skill and understanding of circuit-design, program development as well as mathematical number-manipulation, to produce results on the display.
Explaining some of the mathematical-processing code is beyond the scope of this discussion and you will have to accept these sub-routines and use them "as is" whenever they are required.
However most of the program can be pulled apart and studied to see how it operates.

LOOKING AT THE SCAN ROUTINE
The first thing to do is look at the display routine. This is called the SCANNING ROUTINE and it outputs to the display "ONE PIXEL or SEGMENT AT A TIME." This is an unusual way to drive a display but has been chosen so that all the segments have the same brightness and the scan routine does not put too much load on the outputs of the micro.
You will notice the absence of current liming transistors.
This is not a good practice as it loads the FETs in the micro so that they do not turn on fully.
You can imagine show small each FET is.
They are designed to deliver up to 25mA when fully turned on.
This means the dissipation is only a few milliwatts, if the voltage across it is about 50mV.
But when you are driving a LED, the voltage increases because the LED has a characteristic voltage that does not increase and the remaining voltage must be dropped across the driving components.
The circuit uses two outputs to turn on each segment and if the voltage across the LED is 1.7v, each output has to drop: 5v - 1.7v = 3.3v This voltage is divided by two to get 1.65v
The power dissipated by each FET rises from 25x50 = one thousandth of a milliwatt, to 25x1650 = forty-one thousandths of a milliwatt. It has increased 40 times.
The FETs seem to be very robust and none have failed to-date.
To see how the display is accessed, we need to remove the code that does not apply to this function and leave only the display (scan) sections.
To do this we gradually remove sub-routines and save the new program as Scan_v43only.asm You must give it a new name so you can go back to previously-saved versions if the new version does not work. This is burnt into a chip and tested to make sure the start-up feature is still present.
More un-wanted sub-routines are removed until we get the smallest program possible.
This is what we have done.
In addition, we have increased the delay so the display routine runs very slowly and you can see it in action.
The first thing the program does is display the version number. In this case it is 043. There are more sub-routines than are really needed for this task, in the program below, but they are included  because they are "called."
The length of delay starts very short and increases by increasing the three files using the "rate" file.
The display scans "043" very quickly, then gets slower and slower to show how each segment is accessed and displayed.
The file you need is:

Scan_v43only.asm
Scan_v43only.hex
 
;Scan the version number   043

;list      p=16f870A             ; list directive to define processor
	#include          ; processor specific variable definitions

        errorlevel -302           ; Register not in bank 0 warning

        radix dec

	__CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON 
	  & _HS_OSC & _LVP_OFF & _DEBUG_OFF & _CPD_OFF

#define VERS	 043 	;Version to display

; Data storange
	org	20h
wsave		equ	20H
ssave		equ	21H
bitcnt		equ	22H		; 
flag		equ	23H
count		equ	24H
scount		equ	25H
csave		equ	26H
ddata		equ	27H   
sdata		equ	28H
temp		equ	29H   
ontime		equ	2BH
oftime		equ	2CH
isrvec		equ	2DH
qtime		equ	2EH	;comm timer for serial
timer		equ	30H
freq		equ	33H		
pwmp		equ	35H
mode		equ	36H
rate		equ	37H
baud		equ	38H
midic		equ	39H	;midi channel
pmode		equ	3AH
hi		equ	3BH
lo		equ	3CH   
rand		equ	3DH
acc		equ	40H	
xacc		equ	44H	
digits		equ	48H	
dignr		equ	4CH
dp		equ	4DH
ftimer		equ 	4EH
segmask		equ	50H
dela		equ	51H
bcd		equ	54H	
cnt		equ	59H			
ii		equ	5AH
frame		equ	5BH
place       	equ 	5Ch
port_temp   	equ 	5Dh

 
; Program Start
	org	0
	goto	start   

;  Table for number to seven segment conversion 
digseg
  addwf	  PCL,f
  retlw	  3fh		;0
  retlw   6h		;1
  retlw   5bh		;2
  retlw   4fh		;3
  retlw   66h		;4
  retlw   6dh		;5
  retlw   7dh		;6
  retlw   7h		;7
  retlw   7fh		;8
  retlw   67h		;9

; Get anode value for PORT C output
getano	
	addwf	PCL,f
						
	retlw	1	
	retlw	2
	retlw	4
	retlw	8

getdp	
	addwf	PCL,f
	retlw	03h
	retlw	03h
	retlw	03h
	retlw	03h
	retlw	94h
	retlw	0A5h
	retlw	0C6h
	retlw	0D7h
	retlw	0E8h
	retlw	0F9h

start	
	bsf	STATUS,5
	movlw	b'00111111'
	movwf	TRISA
	movlw	0
	movwf	TRISB
	movlw	b'10110000'
	movwf	TRISC
	movlw	b'10001000'
	movwf	OPTION_REG
	bcf	STATUS,5	
	clrf	segmask
	bsf	segmask,0
	clrf	dignr	
	clrf    rate      ;used to decrease scan rate for viewing
	call	signon     
	goto    start


; show version No 
signon	                
	movlw	VERS
	call	wtod		;put version No
	movlw	0		
	movwf	digits
	call	sign 	        
	return


; delay function

delay 
	movwf	dela+2
dld2
	movwf	dela+1
dld1
	movwf	dela
dld0
	decfsz	dela,f
	goto	dld0
	decfsz	dela+1,f
	goto	dld1
	decfsz	dela+2,f
	goto	dld2
	return
	
   
; show 8 bit value on display
wtod                
	movwf	acc
	clrf	acc+1
	clrf	acc+2
	clrf	acc+3
	call	b2bcd
	call	format
	return

sign	
	movlw	.30	 		
	movwf	temp
x1
	call	segout
	incf	rate,f
	movf    rate,w       ;decrease scan rate across display 
	call	delay     
	decfsz	count,f
	goto	x1
	decfsz  temp,f
	goto	x1
	return

; Convert 32-bit binary number at  into a bcd number
; at . Uses Mike Keitz's procedure for handling bcd
; adjust; Modified Microchip AN526 for 32-bits.
b2bcd
	movlw	32		; 32-bits
	movwf	ii		; make cycle counter
	clrf	bcd		; clear result area
	clrf	bcd+1
	clrf	bcd+2
	clrf	bcd+3
	clrf	bcd+4

b2bcd2
	movlw	bcd		; make pointer
	movwf	FSR
	movlw	5
	movwf	cnt

; Mike's routine_
b2bcd3
	movlw	33h
	addwf	0,f 	; add to both nibbles
	btfsc	0,3	; test if low result > 7
	andlw	0f0h	; low result >7 so take the 3 out
	btfsc	0,7	; test if high result > 7
	andlw	0fh	; high result > 7 so ok
	subwf	0,f 	; any results <= 7, subtract back
	incf	FSR,f 	; point to next
	decfsz	cnt,f
	goto	b2bcd3
	rlf	acc+0,f		; get another bit
	rlf	acc+1,f
	rlf	acc+2,f
	rlf	acc+3,f
	rlf	bcd+0,f		; put it into bcd
	rlf	bcd+1,f
	rlf	bcd+2,f
	rlf	bcd+3,f
	rlf	bcd+4,f
	decfsz	ii,f 		; all done?
	goto	b2bcd2		; no, loop
	return


; cycle thru individual segment drives on 4 digits
; (constant execution time_ 30 instructions)
; ************** Do Not Modify *******************

segout	

	movlw	0F0h
	andwf	PORTC,f		;clear low 4 bits
	movf	dignr,w		;get digit nr
	addlw	digits		;base of segment list
	movwf	FSR
	movf	0,w		;get the data
	andwf	segmask,w	;mask the bit
	xorlw	0ffh		;invert
	movwf	PORTB		;one possible segment line low
	movf	dignr,w
	call	getano	
	iorwf	PORTC,f   ; set one high.
	bcf	STATUS,C
	rlf	segmask,f
	btfsc	STATUS,C
	goto	nseg
	nop
	nop
	nop
	nop
	nop
	return

nseg
	bsf	segmask,0	;rotate
	incf	dignr,f
	btfsc	dignr,2		;overflow?
	clrf	dignr	
	return

; format first 4 significant digits on display
format
	call	first		;find 1st non-zero digit
ffx
	movf	count,w
	call	getdp		;get formatting info
	movwf	dp
	andlw	0fh
	movwf	count
ff5
	call	ff9		;get segment pattern
	movwf	digits
	call	ff9
	movwf	digits+1
	call	ff9
	movwf	digits+2
	call	ff9
	movwf	digits+3
	return

ff9
	movf	count,w
	decf	count,f
	call	getbd		;get bcd value
	call	digseg
	return

; set count to 1st non zero digit
first
	movlw	9	;start w/last digit
	movwf	count
ff2
	movf	count,w	;get next digit
	call	getbd
	xorlw	0	;set z flag
	btfss	STATUS,Z
	return		;hit non zero
	decfsz	count,f
	goto	ff2
	return

; get bcd digit specified by 'w'
getbd
	movwf	temp		;save digit No
	clrw
	btfsc	temp,7	;negative value?
	return				;zero if negative.
	bcf	STATUS,C
	rrf	temp,f		;find buffer offset
	movf	temp,w
	rlf	temp,f		;restore all bits
	addlw	bcd		;add start of bcd buff
	movwf	FSR		;set pointer
	movf	0,w		;get the byte
	movwf	ddata		;and store it.
	btfsc	temp,0	;low or hi nibble?
	swapf	ddata,f	;hi.
	movf	ddata,w
	andlw	0fh
	return

       	end 

 

 

 

 

 


 
;Scan the version number.asm     

;
       
	END


 


 

 2/7/2011