|
ULTRASONIC TEST PROGRAM Ultrasonic Test Program for Ultrasonic Board MkIII (PIC16F628) This code requires the code I2C Test Program for Mainboard (PIC16F876) This code requires a digital scope and In Circuit Debugger (on Mainboard) to verify function. I used a PC scope and the Microchip MPLAB ICD2 In Circuit Debugger. I will program another piece of code later for the Mainboard to give a visual indication of functionality. The code is too complex to explain in detail so instead here is a brief description of what it does. Mainboard: When the switch is pressed on the
Mainboard a command is sent over the I2C to tell the Ultrasonic board to
begin a scan. Ultrasonic Board: When the Begin Scan command is
received the PIC16F628 outputs 10 pulses at 40KHz on the left ultrasonic
output. This operation is then repeated for the right ultrasonic output. When both channels are done the the data is sent over the I2C when a Send Data command is received from the mainboard. Data is sent left channel first the right channel. Test results are after the code.
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 I_wtemp, I_stattemp, I_temp ;interupt temp vars count, timeout, pgtime temp, cntL, cntR DelayF2, DelayF1, DelayF, SDelayF1, SDelayF ;delay routine vars endc ORG 0x0000 nop ;required for debug goto Start org 0x0004 ;Interupt vector goto Interupt ;+++++++++++++++++++++++++++++++++++++++++++++++++++ ;+++++++++++++++++++++++++++++++++++++++++++++++++++ Start clrf PORTA ;Init I/O clrf PORTB bsf STATUS, RP0 bcf STATUS, RP1 movlw b'11100111' ;PortA Set all as inputs movwf TRISA ; movlw b'11010110' ;PortB Set RB<7:6:4:2:1> as inputs movwf TRISB ; and set RB<5:3:0> as outputs bcf OPTION_REG, T0CS; ;Timer0 source=machine clock bsf OPTION_REG, PSA ;no prescaler on timer0 bcf STATUS, RP0 movlw .184 ;255-73 (time 1")+2 cyc lost writing Timer0 ;speed of sound is 340.29m/S or 73.4uS/25mm movwf TMR0 bsf INTCON, T0IE ;enable timer0 interupt ; bsf INTCON, GIE movlw b'00000110' ;Setup Comp Register movwf CMCON ;C2, C1 to output(C1=RA3, C2=RA4[open drain]) bcf flag_Clock bcf flag_Start bcf LED ;+++++++++++++++++++++++++++++++++++++++++++++++++++ Main bcf INTCON, GIE ;disable interrupts 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 cfl_je RXData, h'02', RecieveData ;if address =h'02' that's us goto recieve data cfl_je RXData, h'82', 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 movfw cntL movwf TXData ;put into transmit register call PutByte ;send data ; movlw b'10101010' ;byte to send movfw cntR 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 ; bsf INTCON, GIE ;enable interrupts ;ultrasonic here ;+++++++++++++++++++++++++++++++++++++++++++++++++++ Main1 bcf flag_USL ;set if bounce registered bcf flag_USR bcf INTCON, GIE ;disable interrupts movlw .10 movwf pgtime clrf count ;clear main counter inc. in IRQ ;+++++++++++++++++++++++++++++++++++++++++++++++++++ PingLoopL bcf us_OutL ;Must be kept as is due to nop ;critical timing nop nop nop nop nop nop nop nop nop nop bsf us_OutL ;Square wave nop nop nop nop nop nop nop nop nop decfsz pgtime, f goto PingLoopL ;+++++++++++++++++++++++++++++++++++++++++++++++++++ bsf INTCON, GIE ;enable interrupts movlw .40 movwf timeout ;timeout aprox. 40" (3.3 Feet, 1m)/2 PMLoopUSL movlw .19 ;4 cycles to loop 4x19=76 movwf temp PMLoopL btfss USEchoL ;Look for echo goto EchoL ;found decfsz temp, f goto PMLoopL decfsz timeout, f goto PMLoopUSL movlw .255 ;set to 255 for no echo found movwf cntL SecondUS ;Timed out so lets go again for second US bcf INTCON, GIE ;disable interrupts movlw .10 movwf pgtime clrf count ;clear main counter inc. in IRQ PingLoopR bcf us_OutR ;Must be kept as is due to nop ;critical timing nop nop nop nop nop nop nop nop nop nop bsf us_OutR ;Square wave nop nop nop nop nop nop nop nop nop decfsz pgtime, f goto PingLoopR ;+++++++++++++++++++++++++++++++++++++++++++++++++++ bsf INTCON, GIE ;enable interrupts movlw .40 movwf timeout ;timeout aprox. 40" (3.3 Feet, 1m)/2 PMLoopR movlw .19 ;4 cycles to loop 4x19=76 movwf temp PMLoopUSR btfss USEchoR ;Look for echo goto EchoR ;found noechoR decfsz temp, f goto PMLoopUSR decfsz timeout, f goto PMLoopR movlw .255 ;set to 255 for no echo movwf cntR ;Timed out so no echo found ;So just loop for now goto Main ;+++++++++++++++++++++++++++++++++++++++++++++++++++ EchoL ;Echo found so store count in cnt1 movfw count movwf cntL bsf flag_USL goto SecondUS EchoR ;Echo found so store count in cnt2 movfw count movwf cntR bsf flag_USR Mode ;Do what has to be done if bounce detected ;Then loop again goto Main 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 ;+++++++++++++++++++++++++++++++++++++++++++++++++++ ;++ Interupt Routine ++ ;+++++++++++++++++++++++++++++++++++++++++++++++++++ Interupt movwf I_wtemp ;Save 'w' and STATUS movfw STATUS ;for restoring later movwf I_stattemp movlw .184 ;255-73 (time 1")+2 cyc lost writing Timer0 ;speed of sound is 340.29m/S or 73.4uS/25mm movwf TMR0 bsf INTCON, T0IF ;Restart timer0 interupt incf count, f ;purpose of IRQ bcf INTCON, T0IF ;clear timer0 interrupt flag ; bsf LED Iend movfw I_stattemp ;Restore 'w' and STATUS movfw STATUS ;before returning movfw I_wtemp retfie ;************************** ;*** Config word *** ;************************** __CONFIG h'3FFF' & _LVP_OFF & _BODEN_OFF & _XT_OSC & _PWRTE_ON & _WDT_OFF ;+++++++++++++++++++++++++++++++ end
The Results:
The ultrasonic output pulses from the PIC16F628 (RB0, RB3).
Note the frequency is 40.07KHz this is very close to 40KHz.
The ultrasonic output at the Transmitter.
The modulated echo from the Ultrasonic Amp. (D2A, D4A)
The demodulated echo (D2K, D4K)
The output from the comparator (RA3, RA4[open drain and needs a pull up resistor])
Proof of the pudding, an object
was placed 300mm (12 inches) from the sensors the value read in to the
Mainboard was 24 decimal the distance is measured in 25mm steps, however
the value 24 has to be divided by 2 as it is twice the distance to the
receiver i.e. from the transmitter back to the receiver.
|