Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Having problems with pic16f872

Status
Not open for further replies.

cjgalway1000

New Member
Hi am trying to send data from 2 sharp GP2D02 proximity sensors and 2
devantech srf04 ultrasonic sensors being controlled by a PIC16F872
through gigatechnology's usbmod2 (Serial To Usb module) to my
computer. I have given the code below that I am using but
unfortunately I cannot get it working. A very strange thing happens
when I connect a wire between VSS pin 19 and OSC2 pin 10, once I turn
on the power I pull this wire out. When I do this and check the pins
on a oscilloscope I get the correct measurements for example a 10us
trigger going to the srf04 and output from the GP2D02 going from low
to high although I do not get the correct information into the
computer. Due to this I think most of my code is correct and it may be
something very small stopping the PIC from working correctly. Please
help me if you can as I've been trying to get this working for weeks
with no success.

; pin assignments
; portB 0-7 = USB D0-D7 normally inputs, switched to outputs when
; writing to usb

; portC.7 = output USBWR normally low - pulse high to write

; portC.6 = input USBTXF low means ok to write
; portC.5 = output USBRD normally high - pulse low to read
; portC.4 = input USBRXF low means ok to read

; portC.3 = output SRF1Trigger normally low
; portC.2 = input SRF1Echo - time high pulse following trigger
; portC.1 = output SRF2Trigger
; portC.0 = input SRF2Echo
; pulse trigger hi for 10usec to start conversion
; Echo duration 100usec to 36000usec
; divide by 58 for millimeters or 148 for inches
; range of 1(1.7) to 620 cm = 0(0.67) to 243 inches

; portA.3 = output IR1Clock pulse hi 10usec to start conversion
; portA.2 = input IR1Data - time high pulse following trigger
; portA.1 = output IR2Clock
; portA.0 = input IR2Data
; drop clock low to start conversion and wait for data
; to go high (about 70 milliseconds
; set clock high for 2 usec then low and read Data bit,
; after 2usec set clock high again
; repeat for 7 additional bits
; end with clock high.


list P=16F872
#include <p16f872.inc>
;=====================
; Declaration
#define USBWR PORTC,7
#define USBTXF PORTC,6
#define USBRD PORTC,5
#define USBRXF PORTC,4

#define SRF1Trigger PORTC,3
#define SRF1Echo PORTC,2
#define SRF2Trigger PORTC,1
#define SRF2Echo PORTC,0

#define USBData PORTB

#define IR1Clock PORTA,3
#define IR1Data PORTA,2
#define IR2Clock PORTA,1
#define IR2Data PORTA,0

#define LED1 PORTA,5
#define LED2 PORTA,4

;start general purpose registers
N equ 0x20 ;simple counter counts 1 second periods
T equ 0x21 ;counts 4 ms periods for the 1 second counter
U equ 0x22 ;stores value read from USB port
I equ 0x23 ;general purpose temp variable
J equ 0x24 ;general purpose temp varaible

org 0x0000
goto Init

org 1ch
Init
movlw 0x10
movwf T1CON ;Timer1 - prescale 1:2, oscillator disabled, internal
clock, not running,
;set for 1 usec. rate
clrf INTCON ; Disable all interrupts and clear T0IF
clrf PORTA ;set all outputs low
clrf PORTB
clrf PORTC ;except...
bsf USBRD ;normally high
bsf IR1Clock ;normally high
bsf IR2Clock ;normally high
bsf STATUS, RP0 ; Bank1
movlw 0xc4 ; PortB pull-ups are disabled
movwf OPTION_REG ; Interrupt on rising edge of RB0 - interrrupts
are not enabled
; Timer0 increment from internal clock
; with a prescaler of 1:16 - will count at 8usec rate.
; wdt will timeout at 18msec.

movlw 0x06
movwf ADCON1 ;port A is all digital i/o - no a/d
movlw b'11000101' ;1,3,4 and 5 are outputs
movwf TRISA
movlw b'11111111'
movwf TRISB
movlw b'01010101' ;1,3,5 and 7 are outputs
movwf TRISC
bcf STATUS, RP0 ; Bank0

bsf USBRD ;normally high
bcf USBWR ;normally low
bsf IR1Clock ;normally high
bsf IR2Clock ;normally high
bcf SRF1Trigger ;normally low
bcf SRF2Trigger ;normall low

clrf N ;start at 0
clrf T
clrf U
;*******************************************************************
;main program loop here

;output sequence will be 0,0,SRF1Hi,SRF1Lo,IR1,SRF2Hi,SRF2Lo,IR2,
repeat...
;can synchronize by waiting for two zero values in fast succession,
;less than 1ms apart
Loop
movlw 0
call WriteUSB
movlw 0
call WriteUSB

call ReadSRF1 ;returned in Timer1 - 1 to 36 ms
movfw TMR1H
call WriteUSB
movfw TMR1L
call WriteUSB

call ReadIR1 ;returned in W - 70 ms
call WriteUSB

call ReadSRF2 ;returned in Timer1 - 1 to 36 ms
movfw TMR1H
call WriteUSB
movfw TMR1L
call WriteUSB

call ReadIR2 ;returned in W - 70 ms
call WriteUSB

goto Loop
;*******************************************************************

ReadUSB ;if USBRXF is low, read usb port to W
btfsc USBRXF
goto ReadUSBDone
bcf USBRD ;RD low
nop
nop ;pause a little
movf USBData,W ;data from USB
movwf U ;save it in U
bsf USBRD ;RD back to high
ReadUSBDone
return
;*******************************************************************
WriteUSB ;if USBTXF is low, write W to usb port
btfsc USBTXF
goto WriteUSBDone ;if USBTXF is high, skip writing
movwf USBData ;W to data port
bsf STATUS,RP0
movlw 0x00
movwf TRISB ;data port to output mode
bcf STATUS,RP0
bsf USBWR ;WR high
nop ;pause just a little
nop
bcf USBWR ;WR low
bsf STATUS,RP0
movlw 0xff
movwf TRISB ;data port back to input mode
bcf STATUS,RP0
WriteUSBDone
return
;*******************************************************************
;Reads IR1 Sensor, returns value in W, takes about 70 milliseconds
;uses temp variables I and J
;set clock low
;wait for data to go low
;set clock high then low
;read data bit - rotate bit into J
;repeat for rest of 8 bits
;set clock high
ReadIR1
bcf IR1Clock
btfsc IR1Data
goto $-1 ;wait for IR1Data low

clrwdt ;keep watch dog happy
btfss IR1Data
goto $-2 ;wait for IR1Data high

movlw .8
movwf I ;counter for 8 bits

ReadIR1Loop
bsf IR1Clock ;set clock high
nop
nop ;pause a little
bcf IR1Clock ;set clock low
nop
nop ;pause a little
bcf STATUS,C ;clear carry bit
btfsc IR1Data
bsf STATUS,C ;if data is high, set carry bit
rlf J ;shift carry bit into J

decfsz I
goto ReadIR1Loop ;repeat for all 8 bits
movfw J
bsf IR1Clock ;set clock high again
return
;*******************************************************************
ReadIR2
bcf IR2Clock
btfsc IR2Data
goto $-1 ;wait for IR2Data low

clrwdt ;keep watch dog happy
btfss IR2Data
goto $-2 ;wait for IR2Data high

movlw .8
movwf I ;counter for 8 bits

ReadIR2Loop
bsf IR2Clock ;set clock high
nop
nop ;pause a little
bcf IR2Clock ;set clock low
nop
nop ;pause a little
bcf STATUS,C ;clear carry bit
btfsc IR2Data
bsf STATUS,C ;if data is high, set carry bit
rlf J ;shift carry bit into J

decfsz I
goto ReadIR2Loop ;repeat for all 8 bits
movfw J
bsf IR2Clock ;set clock high again
return
;*******************************************************************
;set SRF1Trigger high
;wait at least 10us
;set SRF1Trigger low
;wait for SRF1Echo to go high
;time until SRF1Echo goes low (100 to 36000 usec.)
ReadSRF1
bsf SRF1Trigger ;set trigger high

movlw .7
movwf I
decfsz I
goto $-1 ;delay 11.5 usec.

bcf SRF1Trigger ;set trigger low
bcf T1CON,0 ;stop timer1
clrf TMR1H
clrf TMR1L ;and set it to zero

clrwdt ;keep watch dog happy
btfsc SRF1Echo
goto $-2 ;wait for echo low

;echo is now high
bsf T1CON,0 ;start timer1
clrwdt
btfss SRF1Echo
goto $-2 ;wait for echo low again

bcf T1CON,0 ;stop timer1
;timer1 contains echo pulse in usec.
return
;*******************************************************************
ReadSRF2
bsf SRF2Trigger ;set trigger high

movlw .7
movwf I
decfsz I
goto $-1 ;delay 11.5 usec.

bcf SRF2Trigger ;set trigger low
bcf T1CON,0 ;stop timer1
clrf TMR1H
clrf TMR1L ;and set it to zero

clrwdt ;keep watch dog happy
btfsc SRF2Echo
goto $-2 ;wait for echo low

;echo is now high
bsf T1CON,0 ;start timer1
clrwdt
btfss SRF2Echo
goto $-2 ;wait for echo low again

bcf T1CON,0 ;stop timer1
;timer1 contains echo pulse in usec.
return
;*******************************************************************
SetLED1 ;turns LED1 on or off according to low bit of N
btfsc N,0
goto SetLED1On
SetLED1Off
bcf LED1
return
SetLED1On
bsf LED1
return
;*******************************************************************
SetLED2 ;turns LED2 on or off according to low bit of U
btfsc U,0
goto SetLED2On
SetLED2Off
bcf LED2
return
SetLED2On
bsf LED2
return
;*******************************************************************

END
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top