ULTRASONIC MAINBOARD TEST PROGRAM

Ultrasonic Test Program for Mainboard (PIC16F876).

This code requires Ultrasonic Test Program for Ultrasonic Board MkIII (PIC16F628).

This code requires P16Fxxx.mac to assemble (included in zip file) put it in the same folder as the .asm file and it will find it ok.

Setup:
Turn trimmer R13 fully clockwise.  With nothing obstruction the ultrasonic sensors adjust R13 anticlockwise until the LEDs on the mainboard go out.  If they are flickering on and off adjust R13 a little further anticlockwise.  The ultrasonic board is now ready to go.

Place an object or your hand about 100mm (4 inches) from the left hand ultrasonic sensor, the left hand LED on the mainboard should come on.  Remove the object and the LED will go out again.
Repeat this routine for the right hand ultrasonic sensor.

The code is too complex to explain in detail instead here is a brief description of what it does.

After a 250mS delay the mainboard sends a command to the ultrasonic board via the I2C bus to begin a scan.
10mS later it send a command to the ultrasonic board to send it's data.
If either of the values are decimal 8 or less (equivalent to 100mm) the appropriate LED is turned on.
If the value is greater than 8 the appropriate LED is turned off.
The sequence is then repeated.
The ultrasonic board scans approx every 250mS (1/4 of a second).

 

The Code:

 

	list p=16f876
#include "P16F876.inc"
#include "P16Fxxx.mac"
;Define ports so we can use them by name
#define AntL PORTA,2	;OUTPUT
#define AntR PORTA,3	;OUTPUT
#define Sw   PORTC, 1	;INPUT
#define	SCL  PORTC, 3	;OUTPUT
#define SDA  PORTC, 4	;INPUT/OUTPUT
#define flag_Sw flag0, 0
	cblock	20h
	VLDelay, LDelay, MDelay, SDelay		;variables for delay routines
	flag0
	TXBuf, RXBuf, Cnt			;I2C variables
	USLeft, USRight				;ultrasonic return values
	endc
	org 0
	nop
	goto init	;jump over interrupt vectors
	org 4
	retfie
	
	org 10
init 
	bsf	STATUS, RP0
	bcf	STATUS, RP1		;select bank 1
	movlw	b'11110011'
	movwf	TRISA			;RA2,RA3 set as outputs
	movlw	b'11111111'
	movwf	TRISB
	movlw	b'11110111'		;SCL as output
	movwf	TRISC
	movlw	b'00000110'		;set porta i/o's as digital
	movwf	ADCON1
	bcf	STATUS, RP0		;select bank 0
	bcf	AntL
	bcf	AntR
	bcf	flag_Sw
	bsf	SCL
Start
	movlw	.25			
	call	LongDelay		;wait 250mS
	call	SetDataOut
	call	SetStart		;set start condition
	movlw	h'04'			;address 02h write mode
	movwf	TXBuf
	call	PutByte			;send data
	call	SetDataIn		;set SDA to input
	call	Clock			;ignore acknowledge bit
	movlw	h'01'			;send command 01h start ulrasonic
	movwf	TXBuf
	call	PutByte			;send data
	call	SetDataIn		;set SDA to input
	call	Clock			;ignore acknowledge bit
	call	SetStop			;set stop condition
	
	movlw	.1			;1*10mS=10mS
	call	LongDelay		;wait 1 second		
	call	SetDataOut		;set SDA for output
	call	SetStart		;set start condition
	movlw	h'05'			;address 02h read mode
	movwf	TXBuf
	call	PutByte			;send TXBuf
	call	SetDataIn		;set SDA to input
	call	Clock			;ignore acknowledge bit
	call	GetByte			;recieve data
	bcf	SDA			;set SDA low for acknowledge bit
	call	Clock			;send acknowledge bit
	movfw	RXBuf
	movwf	USLeft
	call	GetByte			;recieve data
	bcf	SDA			;set SDA low for acknowledge bit
	call	Clock			;send acknowledge bit
	movfw	RXBuf
	movwf	USRight
	bsf	SCL
	call	SetStop			;set stop condition
	bcf	AntL
	cfl_jge	USLeft, .9, AntLOff
	bsf	AntL
AntLOff
	bcf	AntR
	cfl_jge	USRight, .9, AntROff
	bsf	AntR
AntROff
	goto	Start
;+++++++++++++++++++++++++++++++++++++++++++++++++++
;++                  Subroutines  		  ++
;+++++++++++++++++++++++++++++++++++++++++++++++++++
	
WaitSw				;wait for switch high to low
	btfsc 	Sw		;test switch
	goto	setFlag		;if high goto setFlag
	btfss	flag_Sw		;if low test flag_Sw
	goto	WaitSw		;if flag clear back to wait
	bcf	flag_Sw		;if flag high then transition high to low occured
	return				
setFlag
	bsf	flag_Sw		;set flag_Sw
	goto	WaitSw		;back to wait
SetDataOut			;set SDA to output
	bsf	STATUS, RP0
	bcf	TRISC,	4	;set SDA output
	bcf	STATUS, RP0
	return
SetDataIn			;set SDA to input
	bsf	STATUS, RP0
	bsf	TRISC,	4	;set SDA input
	bcf	STATUS, RP0
	return
SetStart			;set start condition
	bsf	SDA	
	bsf	SCL
	movwf	.20		;20*10uS=200uS
	call	ShortDelay	;wait 200uS
	bcf	SDA		;SDA goes low while SCL high
	movlw	.20
	call	ShortDelay	;wait 200 uS
	bcf	SCL
	call	Delay		;wait 10uS
	return
SetStop				;set stop condition
	bcf	SDA
	bsf	SCL
	call	SetDataOut	;Set SDA output
	movwf	.20		;20*10uS=200uS
	call	ShortDelay	;wait 200uS
	bsf	SDA		;SDA goes high while SCL high
	movlw	.20
	call	ShortDelay	;wait 200uS
	return
PutByte				;send TXBuf out
	call	SetDataOut	;Set SDA output
	movlw	.8		;8 bits to send
	movwf	Cnt
PBLoop
	call	PutBit		;send single bit
	decfsz	Cnt, f		;decrment count
	goto	PBLoop		;if not zero then loop again (next bit)
	return
PutBit				;send single bit out
	rlf	TXBuf, f	;shift left TXBuf into carry flag
	bcf	SDA			
	btfsc	STATUS,C	;test carry flag
	bsf	SDA		;if set set SDA else leave SDA clear
	call	Clock		;clock pulse high then low
	return
GetByte				;Recieve RXBuf in
	call	SetDataIn	;set SDA to input
	clrf	RXBuf
	movlw	.8		;8 bits to recieve
	movwf	Cnt
GBLoop		
	call	GetBit		;recieve single bit
	decfsz	Cnt, f		;decrement count
	goto	GBLoop		;if not zero then loop again (next bit)
	return
GetBit				;recieve single bit in
	bsf	SCL		;set clock high
	call	Delay		;wait 10uS
	clrc
	btfsc	SDA		;Test SDA input
	setc			;if set set carry else leave carry clear
	rlf	RXBuf, f	;shift left carry flag into RXBuf
	bcf	SCL		;set SCL low
	call	Delay		;wait 10uS
	return
Clock				;set clock transition high then low
	bsf	SCL		;SCL high
	call	Delay		;wait 10uS
	bcf	SCL		;SCL low
	call	Delay		;wait 10 uS
	return
;***** Delay Routines from 12 uS to 255 Sec
;***** Very Long Delay 1 Sec to 255 Sec, value in w on entry, 1 tick = 1 Sec
VLongDelay	movwf	VLDelay
waitvldelay	movlw	.100
	call	LongDelay
	decfsz	VLDelay,F
	goto	waitvldelay
	return
;***** Long Delay 10 mS to 2.55 Sec, value in w on entry, 1 tick = 10 mS
LongDelay	movwf	LDelay
waitldelay	movlw	.10
	call	MedDelay
	decfsz	LDelay,F
	goto	waitldelay
	return
;***** Medium Delay 1 mS to 255 mSec, value in w on entry, 1 tick = 1 mS
MedDelay	movwf	MDelay
waitmdelay	movlw	.100
	call	ShortDelay
	decfsz	MDelay,F
	goto	waitmdelay
	return
;***** Short Delay 10 uS to 2.55 mSec, value in w on entry, 1 tick = 12 uS
Delay
	movlw	.1		;1*10uS=10uS
ShortDelay
	movwf	SDelay
WaitSDF	
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	decfsz	SDelay,F
	goto	WaitSDF
	Return
;**************************
;***    Config word     ***
;**************************
	__CONFIG h'3FFF' & _LVP_OFF & _BODEN_OFF & _XT_OSC & _PWRTE_ON & _WDT_OFF 
	end