I2C Ultrasonic Board Test Program

I2C Test Program for Ultrasonic board (PIC16F628).

This code require the include file "P16fxxx.mac" included in zip file. Ensure the .mac file is in the same folder as the .asm file and it will find it ok.

This test requires the use of a logic probe to verify the test. Available from Maplins.

This code requires the code I2C Test Program for the mainboard (PIC16F876)

I'll not explain the code here as it's too complex, the code is fully commented anyway.

Using a logic probe on pin 11 (RB5) of U2 (PIC16F628), press the switch on the mainboard.
The pulse LED on the logic probe will flash once to show first communication successful.
One second later the pulse LED will flash again to show second communication successful.
Press the switch on the mainboard to repeat the test.

 

The Code:

	list p=pic16f628
#include "P16f628.inc"
#include "P16fxxx.mac"
;#define us_OutR	PORTB,3
;#define us_OutL	PORTB,0
#define LED		PORTB, 5
#define SCL		PORTB, 2
#define SDA		PORTB, 1
;#define flag_USL 	flags0,0
;#define flag_USR 	flags0,1
#define	flag_Start  flags0,2
#define	flag_Clock  flags0,3
;#define USEchoL    CMCON,C1OUT
;#define USEchoR    CMCON,C2OUT
	cblock 0x20
	flags0, RXData, TXData, cnt
	endc
	ORG	0x0000
	nop			;required for debug 
	goto	Start
	
;+++++++++++++++++++++++++++++++++++++++++++++++++++
;+++++++++++++++++++++++++++++++++++++++++++++++++++
	
Start
	clrf	PORTA		;Init I/O
	clrf	PORTB
	bsf	STATUS, RP0
	bcf	STATUS, RP1
	movlw 	b'11111111' 	;PortA	Set all as inputs
	movwf 	TRISA 		;			
	movlw 	b'11011111' 	;PortB	Set RB<7:6:4:3:2:1:0> as inputs
	movwf 	TRISB 		;		and set RB<5> as outputs	
	bcf	STATUS, RP0
	bcf	flag_Clock
	bcf	flag_Start
	bcf	LED	
;+++++++++++++++++++++++++++++++++++++++++++++++++++
Main
	call	WaitDatHL	;wait for start condition
	btfss	SCL
	goto	Main		;if clock low goto Main
Start_condition_found
	call	WaitClkHL	;Wait for clock transition high to low
	call	GetByte		;get device address
;	bcf	RXData, 7	;clear read /write bit (ignored)
	cfl_je	RXData, h'04', RecieveData	;if address =h'02' that's us goto recieve data	
	cfl_je	RXData, h'05', SendData		;if address =h'02' that's us goto send data	
	bcf	LED
	call	SetDataIn
	goto	Main
SendData			;address true so send data (2 Bytes)
	bsf	LED
	movlw	b'10001000'	;byte to send
	movwf	TXData		;put into transmit register
	call	PutByte		;send data
	movlw	b'10101010'	;byte to send
	movwf	TXData		;put into transmit register
	call	PutByte		;send data
Done
	call	SetDataIn	;set data port for input	release I2C port
	bcf	LED
	goto	Main
RecieveData			;address true so recieve data (1 byte)
	bsf	LED
	call	GetByte		;recieve data
	cfl_je	RXData, h'01', GetUltraSonic	;if command word 01h then check ultrasonic
	goto	Done
GetUltraSonic
	call	SetDataIn	;set data port for input	release I2C port
	bcf	LED
		;ultrasonic here
	goto	Main	
;+++++++++++++++++++++++++++++++++++++++++++++++++++
;++                  Subroutines  				  ++
;+++++++++++++++++++++++++++++++++++++++++++++++++++
WaitClkHL			;wait for clock transition high to low
	btfsc 	SCL		;test clock
	goto	setFlag		;if high goto setFlag
	btfss	flag_Clock	;if low test flag_Clock
	goto	WaitClkHL	;if flag clear back to wait
	bcf	flag_Clock	;if flag high then transition high to low occured
	return				
setFlag
	bsf	flag_Clock	;set flag_Clock
	goto	WaitClkHL	;back to wait
WaitDatHL			;wait for data transition high to low
	btfsc 	SDA		;test data line
	goto	setDFlag	;if high goto setFlag
	btfss	flag_Clock	;if low test flag_Clock
	goto	WaitDatHL	;if flag clear back to wait
	bcf	flag_Clock	;if flag high then transition high to low occured
	return				
setDFlag
	bsf	flag_Clock	;set flag_Clock
	goto	WaitDatHL	;back to wait
GetBit				;recieve bit into RXDAta
	call	WaitClkHL	;wait for clock high to low
	clrc
	btfsc	SDA		;test data line
	setc			;if data high set carry high else leave it clear
	rlf	RXData,F	;shift carry into RXData
	return
PutBit				;send bit to data line
	rlf	TXData,F	;shift TXData into carry flag	
	bcf	SDA		;clear data line
	btfsc	STATUS, C	;test carry flag
	bsf	SDA		;if carry set then set data line else leave clear
	call	WaitClkHL	;wait for clock high to low
	return
SetDataOut
	bsf	STATUS, RP0
	bcf	TRISB, 1	;set SDA to o/p
	bcf	STATUS, RP0
	return
SetDataIn
	bsf	STATUS, RP0
	bsf	TRISB, 1	;set SDA to i/p
	bcf	STATUS, RP0
	return
GetByte				;returns with byte in RXData
	call	SetDataIn
	clrf	RXData		;clear Recieve data byte
	movlw	.8		;8 bits to recieve
	movwf	cnt
Loop1
	call	GetBit		;recieve bit
	decfsz	cnt,F		;decrement counter and check for zero
	goto	Loop1		;if not zero then back to loop1
	call	SetDataOut	;if zero then we're done, set data for output
	bcf	SDA		;send acknowledge bit
	call	WaitClkHL	;wait clock high to low
	return
PutByte				;sends byte in TXData
	Call	SetDataOut
	movlw	.8		;8 bits to send
	movwf	cnt
Loop2
	call	PutBit		;send bit
	decfsz	cnt,F		;decrement counter and check for zero
	goto	Loop2		;if not zero back to loop2
	call	SetDataIn	;if zero then we're done set data for input
	call	WaitClkHL	;ignore acknowledge bit	
	return

;**************************
;***    Config word     ***
;**************************
	__CONFIG h'3FFF' & _LVP_OFF & _BODEN_OFF & _XT_OSC & _PWRTE_ON & _WDT_OFF 
;+++++++++++++++++++++++++++++++
	end