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.

Rewriting PIC16F628A code for PIC16f876

Status
Not open for further replies.

huub8

New Member
I am making a wifi controlled "robot" for a school project, and i wanted to use this project as a starting point. It uses a modified linksys router to connect over wifi with a computer and the router sends any commands (left, right, forward or backwards) it recieves to a microcontroller, wich then drives the h-bridge.

In the project above the microcontroller used is a PIC16F628A, but instead of using a remote controlled car I build my own tank like robot that uses 2 engines, so i would like to use pwm to control it in the future and therefor I would like to rewrite the code so it will work on a PIC16f876 which has 2 pwm channels.

The original code does a couple of things:
it turn a red led on on powerup
when it revieves the alive message from the router it turn a green led on and the right led of
it now waits for commands (left, right, forward, backwards and the horn)

This is the original code for the PIC16F628A:

Code:
;*******************************************************************
; Function:  Wifi Robot Controller
; Processor: pic16f628 at 4 MHz using internal RC oscillator
; Filename:  car_pic.asm
; Author:    Jon Bennett
; Website:   www.jbprojects.net/projects/wifirobot
; Credit:    Based on UART Test Program
;            http://www.oz1bxm.dk/PIC/628uart.htm
;*******************************************************************

#define DEBUG 0
greenLED	equ b'10000000' ;128,RB7
redLED 		equ b'01000000' ;64, RB6
horn 		equ b'00100000' ;32, RB5


right 		equ b'00001000' ;8,  RA3
left 		equ b'00000100' ;4,  RA2
back 		equ b'00000010' ;2,  RA1
forward 	equ b'00000001' ;1   RA0


        LIST P=16F628, R=DEC    ; Use the pic16f628 and decimal system

        #include "P16F628.INC"  ; Include header file

        	__config _INTRC_OSC_NOCLKOUT & _LVP_OFF & _WDT_OFF & _PWRTE_ON & _BODEN_ON & _MCLRE_OFF

        CBLOCK 0x20             ; Declare variable addresses starting at 0x20
        dataL
		in_char
	    temp
    	d1
		d2	
        ENDC

        ORG    0x000            ; Program starts at 0x000
;
; --------------------------------
; set ANALOG/DIGITAL INPUTS PORT A
; --------------------------------
;
        movlw 7
        movwf CMCON             ; CMCON=7 set comperators off
;
; ----------------
; INITIALIZE PORTS
; ----------------
;
        movlw b'00000000'       ; set up portA
        movwf PORTA

        movlw b'00000100'       ; RB2(TX)=1 others are 0
        movwf PORTB

        bsf STATUS,RP0          ; RAM PAGE 1

        movlw 0x00
        movwf TRISA             ; portA all pins output

        movlw b'00000010'       ; RB1(RX)=input, others output
        movwf TRISB

; ------------------------------------
; set BAUD RATE TO COMMUNICATE WITH PC
; ------------------------------------
; Boot Baud Rate = 9600, No Parity, 1 Stop Bit
;
        movlw 0x19              ; 0x19=9600 bps (0x0C=19200 bps)
        movwf SPBRG
        movlw b'00100100'       ; brgh = high (2)
        movwf TXSTA             ; enable Async Transmission, set brgh

        bcf STATUS,RP0          ; RAM PAGE 0

        movlw b'10010000'       ; enable Async Reception
        movwf RCSTA
;
; ------------------------------------
; PROVIDE A setTLING TIME FOR START UP
; ------------------------------------
;
        clrf dataL
settle  decfsz dataL,F
        goto settle

        movf RCREG,W
        movf RCREG,W
        movf RCREG,W            ; flush receive buffer
;
; ---------
; MAIN LOOP
; ---------
;
		clrf PORTA
		movlw redLED
		movwf PORTB

        call message            ; prints out a message if DEBUG is 1
		call check_init ; wait for INIT message from WRT54GL
		bsf PORTB,7
loop    call receive_delay            ; wait for a char		
		call add_green				  ;set greenLED on
		call process_input			  ;make sure that forward and backward aren't both high! or that greenLED and redLED aren't both high! or that left and right aren't both high!
        call send               ; send the char
        goto loop

process_input
; Make sure that Forward & Backward cannot be ON at the same time
; Make sure that Left & Right cannot be ON at the same time
; Output result to PORTB
	MOVWF temp
	BTFSC temp,0 ;//Execute next line if temp,0 is HIGH
		BCF temp,1
    BTFSC temp,2 ;//Execute next line if temp,2 is HIGH
		BCF temp,3
    BTFSC temp,6 ;//Execute next line if temp,6 is HIGH
		BCF temp,7
	MOVF temp,0
    andlw b'00001111'
	movwf PORTA
	movf temp,0
	andlw b'11110000'
	movwf PORTB
	movf temp,0
	return

add_green
	movwf temp
	btfss temp,7  ;If greenLED is LOW execute next line
		bsf temp,7
	movf temp,0
	return

;
; -------------------------------------------
; RECEIVE CHARACTER FROM RS232 AND STORE IN W
; -------------------------------------------
; This routine does not return until a character is received.
;
receive btfss PIR1,RCIF         ; (5) check for received data
        goto receive
data_received
        movf RCREG,W            ; save received data in W
        return


check_init
; waits to receive 'jbpro' from the router meaning that the software is up and running
; after the message is received, the greenLED is turned on and microcontroller can drive the car
	call receive_delay
	sublw 'j'
	btfss STATUS, Z
	   goto check_init
	call receive_delay
	sublw 'b'
	btfss STATUS, Z
	   goto check_init
	call receive_delay
	sublw 'p'
	btfss STATUS, Z
	   goto check_init
	call receive_delay
	sublw 'r'
	btfss STATUS, Z
	   goto check_init
	call receive_delay
	sublw 'o'
	btfss STATUS, Z
	   goto check_init

#if DEBUG
;prints message and goes in to an endless loop of flashing greenLED
	call message

Loop	
;	movlw	greenLED
	movlw 0xff
	movwf	PORTA			;set all bits on
	call	Delay			;this waits for a while!
	movlw	0x00
	movwf	PORTA
	call	Delay
	goto	Loop			;go back and do it again
#endif

return


receive_delay
			;299993 cycles
	movlw	0x5E
	movwf	d1
	movlw	0xEB
	movwf	d2
delay_0
	btfsc PIR1,RCIF ;check for serial data
		goto got_data ;if we do, goto got_data!
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	delay_0

	movlw 0x00
	return

got_data ;move data in to W
	btfsc PIR1,RCIF
	movf RCREG,W
return

#if DEBUG
Delay	movlw	d'250'			;delay 250 ms (4 MHz clock)
	movwf	temp
d11	movlw	0xC7
	movwf	d1
	movlw	0x01
	movwf	d2
Delay_0
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	Delay_0

	decfsz	temp	,f
	goto	d11
	retlw	0x00
#endif



;
; -------------------------------------------------------------
; SEND CHARACTER IN W VIA RS232 AND WAIT UNTIL FINISHED SENDING
; -------------------------------------------------------------
;
send    
#if DEBUG
movwf TXREG             ; send data in W

TransWt bsf STATUS,RP0          ; RAM PAGE 1
WtHere  btfss TXSTA,TRMT        ; (1) transmission is complete if hi
        goto WtHere

        bcf STATUS,RP0          ; RAM PAGE 0
#endif
        return
;
; -------
; MESSAGE
; -------
;
message 
#if DEBUG
		movlw  '1'
        call send
        movlw  '6'
        call send
        movlw  'F'
        call send
        movlw  '6'
        call send
        movlw  '2'
        call send
        movlw  '8'
        call send
        movlw  ' '
        call send
        movlw  'a'
        call send
        movlw  'l'
        call send
        movlw  'i'
        call send
        movlw  'v'
        call send
        movlw  'e'
        call send
        movlw  0x0D ; CR
        call send
        movlw  0x0A ; LF
        call send
#endif
        return

        END

This code functioned perfectly, but ofcourse only on a PIC16F628A, i then converted it to the code below, but the problem was that instead of the green led turning on when it had recieved the alive message, the led that is only supposed to indicate a "right" signal goes on and stays on. This "right" led still functions as the led for a "right" signal as well, so it has a double function (wich is unwanted ofcourse).

This probebly happend because of my changes to the code, since i had to change all of the porta into portb and portb into portc. I also had to change the greenled to RC3 (it was originaly on portb), this should just work ofcourse but i most have missed one bit of code since the greenled shows on RB3 after recieving the "greeting" mesage from the router.

Code:
#define DEBUG 0
greenLED	equ b'00001000' ;128,RC3
redLED 		equ b'00010000' ;64, RC4
horn 		equ b'00100000' ;32, RC5
 
 
right 		equ b'00001000' ;8,  RB3
left 		equ b'00000100' ;4,  RB2
back 		equ b'00000010' ;2,  RB1
forward 	equ b'00000001' ;1   RB0
 
 
 
 
; 16F876 PWM example code
;
; Device 16F876
LIST p=16F876
include "P16F876.inc"
 
__CONFIG _BODEN_ON & _CP_OFF & _CPD_OFF & _PWRTE_ON & _WDT_OFF & _LVP_OFF & _HS_OSC
 
 
 
 
 
CBLOCK 0x20             ; Declare variable addresses starting at 0x20
        dataL
		in_char
	    temp
    	d1
		d2	
        ENDC
 
        ORG    0x000            ; Program starts at 0x000
;
; --------------------------------
; set ANALOG/DIGITAL INPUTS PORT A
; --------------------------------
;
		BANKSEL ADCON1
		movlw 0x06
		movwf ADCON1
		BANKSEL PORTA
;
; ----------------
; INITIALIZE PORTS
; ----------------
;
        movlw b'00000000'       ; set up portB
        movwf PORTB
 
        movlw b'01000000'       ; RC6(TX)=1 others are 0
        movwf PORTC
 
        bsf STATUS,RP0          ; RAM PAGE 1
 
        movlw 0x00
        movwf TRISB             ; portB all pins output
 
        movlw b'10000000'       ; RC7(RX)=input, others output
        movwf TRISC
 
; ------------------------------------
; set BAUD RATE TO COMMUNICATE WITH PC
; ------------------------------------
; Boot Baud Rate = 9600, No Parity, 1 Stop Bit
;
        movlw 0x19              ; 0x19=9600 bps (0x0C=19200 bps)
        movwf SPBRG
        movlw b'00100100'       ; brgh = high (2)
        movwf TXSTA             ; enable Async Transmission, set brgh
 
        bcf STATUS,RP0          ; RAM PAGE 0
 
        movlw b'10010000'       ; enable Async Reception
        movwf RCSTA
;
; ------------------------------------
; PROVIDE A setTLING TIME FOR START UP
; ------------------------------------
;
        clrf dataL
settle  decfsz dataL,F
        goto settle
 
        movf RCREG,W
        movf RCREG,W
        movf RCREG,W            ; flush receive buffer
;
; ---------
; MAIN LOOP
; ---------
;
		clrf PORTB
		movlw redLED
		movwf PORTC
 
        call message            ; prints out a message if DEBUG is 1
		call check_init ; wait for INIT message from WRT54GL
		bsf PORTC,3
loop    call receive_delay            ; wait for a char		
		call add_green				  ;set greenLED on
		call process_input			  ;make sure that forward and backward aren't both high! or that greenLED and redLED aren't both high! or that left and right aren't both high!
        call send               ; send the char
        goto loop
 
process_input
; Make sure that Forward & Backward cannot be ON at the same time
; Make sure that Left & Right cannot be ON at the same time
; Output result to PORTC
	MOVWF temp
	BTFSC temp,0 ;//Execute next line if temp,0 is HIGH
		BCF temp,1
    BTFSC temp,2 ;//Execute next line if temp,2 is HIGH
		BCF temp,3
    BTFSC temp,6 ;//Execute next line if temp,6 is HIGH
		BCF temp,7
	MOVF temp,0
    andlw b'00001111'
	movwf PORTB
	movf temp,0
	andlw b'11110000'
	movwf PORTC
	movf temp,0
	return
 
add_green
	movwf temp
	btfss temp,3  ;If greenLED is LOW execute next line
		bsf temp,3
	movf temp,0
	return
 
;
; -------------------------------------------
; RECEIVE CHARACTER FROM RS232 AND STORE IN W
; -------------------------------------------
; This routine does not return until a character is received.
;
receive btfss PIR1,RCIF         ; (5) check for received data
        goto receive
data_received
        movf RCREG,W            ; save received data in W
        return
 
 
check_init
; waits to receive 'jbpro' from the router meaning that the software is up and running
; after the message is received, the greenLED is turned on and microcontroller can drive the car
	call receive_delay
	sublw 'j'
	btfss STATUS, Z
	   goto check_init
	call receive_delay
	sublw 'b'
	btfss STATUS, Z
	   goto check_init
	call receive_delay
	sublw 'p'
	btfss STATUS, Z
	   goto check_init
	call receive_delay
	sublw 'r'
	btfss STATUS, Z
	   goto check_init
	call receive_delay
	sublw 'o'
	btfss STATUS, Z
	   goto check_init
 
#if DEBUG
;prints message and goes in to an endless loop of flashing greenLED
	call message
 
Loop	
;	movlw	greenLED
	movlw 0xff
	movwf	PORTB			;set all bits on
	call	Delay			;this waits for a while!
	movlw	0x00
	movwf	PORTB
	call	Delay
	goto	Loop			;go back and do it again
#endif
 
	return
 
 
receive_delay
			;299993 cycles
	movlw	0x5E
	movwf	d1
	movlw	0xEB
	movwf	d2
delay_0
	btfsc PIR1,RCIF ;check for serial data
		goto got_data ;if we do, goto got_data!
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	delay_0
 
	movlw 0x00
	return
 
got_data ;move data in to W
	btfsc PIR1,RCIF
	movf RCREG,W
	return
 
#if DEBUG
Delay	movlw	d'250'			;delay 250 ms (4 MHz clock)
	movwf	temp
d11	movlw	0xC7
	movwf	d1
	movlw	0x01
	movwf	d2
Delay_0
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	Delay_0
 
	decfsz	temp	,f
	goto	d11
	retlw	0x00
#endif
 
 
 
 
 
 
 
 
 
 
 
 
 
 
;
; -------------------------------------------------------------
; SEND CHARACTER IN W VIA RS232 AND WAIT UNTIL FINISHED SENDING
; -------------------------------------------------------------
;
send    
#if DEBUG
movwf TXREG             ; send data in W
 
TransWt bsf STATUS,RP0          ; RAM PAGE 1
WtHere  btfss TXSTA,TRMT        ; (1) transmission is complete if hi
        goto WtHere
 
        bcf STATUS,RP0          ; RAM PAGE 0
#endif
        return
;
; -------
; MESSAGE
; -------
;
message 
#if DEBUG
		movlw  '1'
        call send
        movlw  '6'
        call send
        movlw  'F'
        call send
        movlw  '6'
        call send
        movlw  '2'
        call send
        movlw  '8'
        call send
        movlw  ' '
        call send
        movlw  'a'
        call send
        movlw  'l'
        call send
        movlw  'i'
        call send
        movlw  'v'
        call send
        movlw  'e'
        call send
        movlw  0x0D ; CR
        call send
        movlw  0x0A ; LF
        call send
#endif
        return
 
        END

See my next post for the rest of the question, it was to long to post at once
 
Last edited:
With the help of the creator of the original code the following code was created:

Code:
#define DEBUG 0
greenLED	equ b'00001000' ;8,  RC3
redLED 		equ b'00010000' ;16, RC4
horn 		equ b'00100000' ;32, RC5
 
 
right 		equ b'00001000' ;8,  RB3
left 		equ b'00000100' ;4,  RB2
back 		equ b'00000010' ;2,  RB1
forward 	equ b'00000001' ;1   RB0
 
 
 
 
; 16F876 PWM example code
;
; Device 16F876
LIST p=16F876
include "P16F876.inc"
 
__CONFIG _BODEN_ON & _CP_OFF & _CPD_OFF & _PWRTE_ON & _WDT_OFF & _LVP_OFF & _HS_OSC
 
 
 
 
 
CBLOCK 0x20             ; Declare variable addresses starting at 0x20
        dataL
		in_char
	    temp
    	d1
		d2	
        ENDC
 
        ORG    0x000            ; Program starts at 0x000
;
; --------------------------------
; set ANALOG/DIGITAL INPUTS PORT A
; --------------------------------
;
		BANKSEL ADCON1
		movlw 0x06
		movwf ADCON1
		BANKSEL PORTA
;
; ----------------
; INITIALIZE PORTS
; ----------------
;
        movlw b'00000000'       ; set up portB
        movwf PORTB
 
        movlw b'01000000'       ; RC6(TX)=1 others are 0
        movwf PORTC
 
        bsf STATUS,RP0          ; RAM PAGE 1
 
        movlw 0x00
        movwf TRISB             ; portB all pins output
 
        movlw b'10000000'       ; RC7(RX)=input, others output
        movwf TRISC
 
; ------------------------------------
; set BAUD RATE TO COMMUNICATE WITH PC
; ------------------------------------
; Boot Baud Rate = 9600, No Parity, 1 Stop Bit
;
        movlw 0x19              ; 0x19=9600 bps (0x0C=19200 bps)
        movwf SPBRG
        movlw b'00100100'       ; brgh = high (2)
        movwf TXSTA             ; enable Async Transmission, set brgh
 
        bcf STATUS,RP0          ; RAM PAGE 0
 
        movlw b'10010000'       ; enable Async Reception
        movwf RCSTA
;
; ------------------------------------
; PROVIDE A setTLING TIME FOR START UP
; ------------------------------------
;
        clrf dataL
settle  decfsz dataL,F
        goto settle
 
        movf RCREG,W
        movf RCREG,W
        movf RCREG,W            ; flush receive buffer
;
; ---------
; MAIN LOOP
; ---------
;
		clrf PORTB
		movlw redLED
		movwf PORTC
 
        call message            ; prints out a message if DEBUG is 1
		call check_init ; wait for INIT message from WRT54GL
		bsf PORTC,3
loop    call receive_delay            ; wait for a char		
		call add_green				  ;set greenLED on
		call process_input			  ;make sure that forward and backward aren't both high! or that greenLED and redLED aren't both high! or that left and right aren't both high!
        call send               ; send the char
        goto loop
 
process_input
; Make sure that Forward & Backward cannot be ON at the same time
; Make sure that Left & Right cannot be ON at the same time
; Output result to PORTC
	MOVWF temp
	BTFSC temp,0 ;//Execute next line if temp,0 is HIGH
		BCF temp,1
    	BTFSC temp,2 ;//Execute next line if temp,2 is HIGH
		BCF temp,3
	MOVF temp,0
        andlw b'00001111'
	movwf PORTB
	return
 
add_green
	movlw greenLED
	movwf PORTC
	return
 
;
; -------------------------------------------
; RECEIVE CHARACTER FROM RS232 AND STORE IN W
; -------------------------------------------
; This routine does not return until a character is received.
;
receive btfss PIR1,RCIF         ; (5) check for received data
        goto receive
data_received
        movf RCREG,W            ; save received data in W
        return
 
 
check_init
; waits to receive 'jbpro' from the router meaning that the software is up and running
; after the message is received, the greenLED is turned on and microcontroller can drive the car
	call receive_delay
	sublw 'j'
	btfss STATUS, Z
	   goto check_init
	call receive_delay
	sublw 'b'
	btfss STATUS, Z
	   goto check_init
	call receive_delay
	sublw 'p'
	btfss STATUS, Z
	   goto check_init
	call receive_delay
	sublw 'r'
	btfss STATUS, Z
	   goto check_init
	call receive_delay
	sublw 'o'
	btfss STATUS, Z
	   goto check_init
 
#if DEBUG
;prints message and goes in to an endless loop of flashing greenLED
	call message
 
Loop	
;	movlw	greenLED
	movlw 0xff
	movwf	PORTB			;set all bits on
	call	Delay			;this waits for a while!
	movlw	0x00
	movwf	PORTB
	call	Delay
	goto	Loop			;go back and do it again
#endif
 
	return
 
 
receive_delay
			;299993 cycles
	movlw	0x5E
	movwf	d1
	movlw	0xEB
	movwf	d2
delay_0
	btfsc PIR1,RCIF ;check for serial data
		goto got_data ;if we do, goto got_data!
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	delay_0
 
	movlw 0x00
	return
 
got_data ;move data in to W
	btfsc PIR1,RCIF
	movf RCREG,W
	return
 
#if DEBUG
Delay	movlw	d'250'			;delay 250 ms (4 MHz clock)
	movwf	temp
d11	movlw	0xC7
	movwf	d1
	movlw	0x01
	movwf	d2
Delay_0
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	Delay_0
 
	decfsz	temp	,f
	goto	d11
	retlw	0x00
#endif
 
 
 
 
 
 
 
 
 
 
 
 
 
 
;
; -------------------------------------------------------------
; SEND CHARACTER IN W VIA RS232 AND WAIT UNTIL FINISHED SENDING
; -------------------------------------------------------------
;
send    
#if DEBUG
movwf TXREG             ; send data in W
 
TransWt bsf STATUS,RP0          ; RAM PAGE 1
WtHere  btfss TXSTA,TRMT        ; (1) transmission is complete if hi
        goto WtHere
 
        bcf STATUS,RP0          ; RAM PAGE 0
#endif
        return
;
; -------
; MESSAGE
; -------
;
message 
#if DEBUG
		movlw  '1'
        call send
        movlw  '6'
        call send
        movlw  'F'
        call send
        movlw  '6'
        call send
        movlw  '2'
        call send
        movlw  '8'
        call send
        movlw  ' '
        call send
        movlw  'a'
        call send
        movlw  'l'
        call send
        movlw  'i'
        call send
        movlw  'v'
        call send
        movlw  'e'
        call send
        movlw  0x0D ; CR
        call send
        movlw  0x0A ; LF
        call send
#endif
        return
 
        END

The red led and green led now work, but the microcontroller doesn't respond to any of the commands any more.

I dont have a clue as to what I might be doing wrong, so if someone could help me i would be verry thankfull.

(ps, i dont mind loosing the horn, green led and red led, wont be using them in the end anyways)


@nigel goodwin, I actually read your tutorial even before posting the startpost, they helped my a lot, but I still dont understand what's wrong. All I know is that it must be in the proces input section.
 
Try this code -

Code:
; 16F876 PWM example code
;
; Device 16F876
		list		p=16F876
		include 	"P16F876.inc"
 
		__CONFIG _BODEN_ON & _CP_OFF & _CPD_OFF & _PWRTE_ON & _WDT_OFF & _LVP_OFF & _HS_OSC
 
 
#define		DEBUG 		0
#define		greenLED	PORTC,3
#define		redLED 		PORTC,4
#define		horn 		PORTC,5
 
 
#define		right 		PORTB,3
#define		left 		PORTB,2
#define		back 		PORTB,1
#define		forward 	PORTB,0
 
 
		cblock 		0x20             ; Declare variable addresses starting at 0x20
       				dataL
				in_char
	    			temp
    				d1
				d2	
        	endc
 
       		org    		0x000            ; Program starts at 0x000
;
; --------------------------------
; set ANALOG/DIGITAL INPUTS PORT A
; --------------------------------
;
		banksel 	ADCON1
		movlw 		0x06
		movwf 		ADCON1
		banksel 	PORTA
;
; ----------------
; INITIALIZE PORTS
; ----------------
;
        	movlw 		b'00000000'       ; set up portB
       		movwf		PORTB
 	
 	       	movlw 		b'01000000'       ; RC6(TX)=1 others are 0
 	       	movwf 		PORTC
 	
 	       	banksel		TRISB	          ; RAM PAGE 1
 	
 	        movlw 		0x00
 	        movwf 		TRISB             ; portB all pins output
 	
 	        movlw		b'10000000'       ; RC7(RX)=input, others output
 	        movwf 		TRISC
 
; ------------------------------------
; set BAUD RATE TO COMMUNICATE WITH PC
; ------------------------------------
; Boot Baud Rate = 9600, No Parity, 1 Stop Bit
;
        	movlw 		0x19              ; 0x19=9600 bps (0x0C=19200 bps)
       		movwf 		SPBRG
        	movlw 		b'00100100'       ; brgh = high (2)
        	movwf 		TXSTA             ; enable Async Transmission, set brgh
 
        	banksel		RCSTA		  ; RAM PAGE 0
 
        	movlw 		b'10010000'       ; enable Async Reception
        	movwf 		RCSTA
;
; ------------------------------------
; PROVIDE A setTLING TIME FOR START UP
; ------------------------------------
;
        	clrf 		dataL
	  	decfsz 		dataL,F
        	goto 		$-1
 
        	movfw 		RCREG
       		movfw 		RCREG
        	movfw 		RCREG            ; flush receive buffer
;
; ---------
; MAIN LOOP
; ---------
;
		clrf 		PORTB
		bsf		redLED
 
        	call 		message         	; prints out a message if DEBUG is 1
		call 		check_init 		; wait for INIT message from WRT54GL
		bsf 		greenLED
loop    	call 		receive_delay            ; wait for a char		
		call 		add_green				  ;set greenLED on
		call 		process_input			  ;make sure that forward and backward aren't both high! or that greenLED and redLED aren't both high! or that left and right aren't both high!
        	call 		send               ; send the char
        	goto 		loop
 
process_input
; Make sure that Forward & Backward cannot be ON at the same time
; Make sure that Left & Right cannot be ON at the same time
; Output result to PORTC
		movwf 		temp
		btfsc 		temp,0 ;//Execute next line if temp,0 is HIGH
		bcf 		temp,1
   		btfsc 		temp,2 ;//Execute next line if temp,2 is HIGH
		bcf 		temp,3
    		btfsc 		temp,6 ;//Execute next line if temp,6 is HIGH
		bcf 		temp,7
		movfw 		temp
    		andlw 		b'00001111'
		movwf 		PORTB
		movfw 		temp
		andlw		b'11110000'
		movwf 		PORTC
		movfw 		temp
		return
 
add_green
		movwf 		temp
		btfss 		temp,3  	;If greenLED is LOW execute next line
		bsf 		temp,3
		movfw 		temp
		return
 
;
; -------------------------------------------
; RECEIVE CHARACTER FROM RS232 AND STORE IN W
; -------------------------------------------
; This routine does not return until a character is received.
;
receive 	btfss 		PIR1,RCIF         ; (5) check for received data
        	goto 		receive
data_received
        	movfw 		RCREG            ; save received data in W
        	return
 
 
check_init
; waits to receive 'jbpro' from the router meaning that the software is up and running
; after the message is received, the greenLED is turned on and microcontroller can drive the car
		call 		receive_delay
		sublw 		a'j'
		btfss 		STATUS, Z
	   	goto 		check_init

		call 		receive_delay
		sublw 		a'b'
		btfss 		STATUS, Z
	   	goto 		check_init

		call 		receive_delay
		sublw 		a'p'
		btfss 		STATUS, Z
	   	goto 		check_init
	
		call 		receive_delay
		sublw 		a'r'
		btfss 		STATUS, Z
	   	goto 		check_init
	
		call 		receive_delay
		sublw 		a'o'
		btfss 		STATUS, Z
	   	goto 		check_init
 
#if DEBUG
;prints message and goes in to an endless loop of flashing greenLED
		call message
 
Loop	
;		bsf		greenLED
		movlw 		0xff
		movwf		PORTB			;set all bits on
		call		Delay			;this waits for a while!
		movlw		0x00
		movwf		PORTB
		call		Delay
		goto		Loop			;go back and do it again
#endif
 
		return
 
 
receive_delay
							;299993 cycles
		movlw		0x5E
		movwf		d1
		movlw		0xEB
		movwf		d2
delay_0
		btfsc 		PIR1,RCIF ;check for serial data
		goto 		got_data ;if we do, goto got_data!
		decfsz		d1, f
		goto		$-1
		decfsz		d2, f
		goto		delay_0
 
		movlw 		0x00
		return
 
got_data ;move data in to W
		btfsc 		PIR1,RCIF
		movf 		RCREG,W
		return
 
#if DEBUG
Delay		movlw		d'250'			;delay 250 ms (4 MHz clock)
		movwf		temp
d11		movlw		0xC7
		movwf		d1
		movlw		0x01
		movwf		d2
Delay_0
		decfsz		d1, f
		goto		$-1
		decfsz		d2, f
		goto		Delay_0
 
		decfsz		temp,f
		goto		d11
		retlw		0x00
#endif
  
;
; -------------------------------------------------------------
; SEND CHARACTER IN W VIA RS232 AND WAIT UNTIL FINISHED SENDING
; -------------------------------------------------------------
;
send    
#if DEBUG
		movwf		TXREG             ; send data in W
 
TransWt 	bsf 		STATUS,RP0          ; RAM PAGE 1
	  	btfss 		TXSTA,TRMT        ; (1) transmission is complete if hi
        	goto 		$-1
 
        	bcf 		STATUS,RP0          ; RAM PAGE 0
#endif
        	return
;
; -------
; MESSAGE
; -------
;
message 
#if DEBUG
		movlw  		d'1'
       		call 		send
        	movlw  		d'6'
        	call 		send
        	movlw  		a'F'
        	call 		send
        	movlw  		d'6'
        	call 		send
        	movlw  		d'2'
        	call 		send
        	movlw  		d'8'
        	call 		send
        	movlw  		a' '
        	call		send
        	movlw  		a'a'
        	call 		send
        	movlw  		a'l'
        	call 		send
        	movlw  		a'i'
        	call		send
        	movlw  		a'v'
        	call 		send
        	movlw  		a'e'
        	call 		send
        	movlw  		0x0D ; CR
        	call 		send
        	movlw  		0x0A ; LF
        	call 		send
#endif
        	return
 
        	END
 
That code still has the same problem. When it has recieved the alive message from the router the green led goes on for a split second, then goes of and the led indicating the "right" direction goes on and stays on.

For some reasen the green led and the "right" led must have become the same in the code, and I think I know why:

The green led is on portC (or is supposed to be on portC)
The right led is on portB
But they are both on pin number 3, and the right led used to be on portb (in the original code). I think that somewhere portb isn't changed into portc, so instead of using RC3, the green led is using RB3.

This only happens after the alive message, so it must be in the main loop.

The writer of the original code has helped me fix this and wrote the following code:

Code:
#define DEBUG 0
greenLED	equ b'00001000' ;8,  RC3
redLED 		equ b'00010000' ;16, RC4
horn 		equ b'00100000' ;32, RC5
 
 
right 		equ b'00001000' ;8,  RB3
left 		equ b'00000100' ;4,  RB2
back 		equ b'00000010' ;2,  RB1
forward 	equ b'00000001' ;1   RB0
 
 
 
 
; 16F876 PWM example code
;
; Device 16F876
LIST p=16F876
include "P16F876.inc"
 
__CONFIG _BODEN_ON & _CP_OFF & _CPD_OFF & _PWRTE_ON & _WDT_OFF & _LVP_OFF & _HS_OSC
 
 
 
 
 
CBLOCK 0x20             ; Declare variable addresses starting at 0x20
        dataL
		in_char
	    temp
    	d1
		d2	
        ENDC
 
        ORG    0x000            ; Program starts at 0x000
;
; --------------------------------
; set ANALOG/DIGITAL INPUTS PORT A
; --------------------------------
;
		BANKSEL ADCON1
		movlw 0x06
		movwf ADCON1
		BANKSEL PORTA
;
; ----------------
; INITIALIZE PORTS
; ----------------
;
        movlw b'00000000'       ; set up portB
        movwf PORTB
 
        movlw b'01000000'       ; RC6(TX)=1 others are 0
        movwf PORTC
 
        bsf STATUS,RP0          ; RAM PAGE 1
 
        movlw 0x00
        movwf TRISB             ; portB all pins output
 
        movlw b'10000000'       ; RC7(RX)=input, others output
        movwf TRISC
 
; ------------------------------------
; set BAUD RATE TO COMMUNICATE WITH PC
; ------------------------------------
; Boot Baud Rate = 9600, No Parity, 1 Stop Bit
;
        movlw 0x19              ; 0x19=9600 bps (0x0C=19200 bps)
        movwf SPBRG
        movlw b'00100100'       ; brgh = high (2)
        movwf TXSTA             ; enable Async Transmission, set brgh
 
        bcf STATUS,RP0          ; RAM PAGE 0
 
        movlw b'10010000'       ; enable Async Reception
        movwf RCSTA
;
; ------------------------------------
; PROVIDE A setTLING TIME FOR START UP
; ------------------------------------
;
        clrf dataL
settle  decfsz dataL,F
        goto settle
 
        movf RCREG,W
        movf RCREG,W
        movf RCREG,W            ; flush receive buffer
;
; ---------
; MAIN LOOP
; ---------
;
		clrf PORTB
		movlw redLED
		movwf PORTC
 
        call message            ; prints out a message if DEBUG is 1
		call check_init ; wait for INIT message from WRT54GL
		bsf PORTC,3
loop    call receive_delay            ; wait for a char		
		call add_green				  ;set greenLED on
		call process_input			  ;make sure that forward and backward aren't both high! or that greenLED and redLED aren't both high! or that left and right aren't both high!
        call send               ; send the char
        goto loop
 
process_input
; Make sure that Forward & Backward cannot be ON at the same time
; Make sure that Left & Right cannot be ON at the same time
	MOVWF temp
	BTFSC temp,0 ;//Execute next line if temp,0 is HIGH
		BCF temp,1
    	BTFSC temp,2 ;//Execute next line if temp,2 is HIGH
		BCF temp,3
	MOVF temp,0
        andlw b'00001111'
	movwf PORTB
	return
 
add_green
	movlw greenLED
	movwf PORTC
	return
 
;
; -------------------------------------------
; RECEIVE CHARACTER FROM RS232 AND STORE IN W
; -------------------------------------------
; This routine does not return until a character is received.
;
receive btfss PIR1,RCIF         ; (5) check for received data
        goto receive
data_received
        movf RCREG,W            ; save received data in W
        return
 
 
check_init
; waits to receive 'jbpro' from the router meaning that the software is up and running
; after the message is received, the greenLED is turned on and microcontroller can drive the car
	call receive_delay
	sublw 'j'
	btfss STATUS, Z
	   goto check_init
	call receive_delay
	sublw 'b'
	btfss STATUS, Z
	   goto check_init
	call receive_delay
	sublw 'p'
	btfss STATUS, Z
	   goto check_init
	call receive_delay
	sublw 'r'
	btfss STATUS, Z
	   goto check_init
	call receive_delay
	sublw 'o'
	btfss STATUS, Z
	   goto check_init
 
#if DEBUG
;prints message and goes in to an endless loop of flashing greenLED
	call message
 
Loop	
;	movlw	greenLED
	movlw 0xff
	movwf	PORTB			;set all bits on
	call	Delay			;this waits for a while!
	movlw	0x00
	movwf	PORTB
	call	Delay
	goto	Loop			;go back and do it again
#endif
 
	return
 
 
receive_delay
			;299993 cycles
	movlw	0x5E
	movwf	d1
	movlw	0xEB
	movwf	d2
delay_0
	btfsc PIR1,RCIF ;check for serial data
		goto got_data ;if we do, goto got_data!
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	delay_0
 
	movlw 0x00
	return
 
got_data ;move data in to W
	btfsc PIR1,RCIF
	movf RCREG,W
	return
 
#if DEBUG
Delay	movlw	d'250'			;delay 250 ms (4 MHz clock)
	movwf	temp
d11	movlw	0xC7
	movwf	d1
	movlw	0x01
	movwf	d2
Delay_0
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	Delay_0
 
	decfsz	temp	,f
	goto	d11
	retlw	0x00
#endif
 
 
 
 
 
 
 
 
 
 
 
 
 
 
;
; -------------------------------------------------------------
; SEND CHARACTER IN W VIA RS232 AND WAIT UNTIL FINISHED SENDING
; -------------------------------------------------------------
;
send    
#if DEBUG
movwf TXREG             ; send data in W
 
TransWt bsf STATUS,RP0          ; RAM PAGE 1
WtHere  btfss TXSTA,TRMT        ; (1) transmission is complete if hi
        goto WtHere
 
        bcf STATUS,RP0          ; RAM PAGE 0
#endif
        return
;
; -------
; MESSAGE
; -------
;
message 
#if DEBUG
		movlw  '1'
        call send
        movlw  '6'
        call send
        movlw  'F'
        call send
        movlw  '6'
        call send
        movlw  '2'
        call send
        movlw  '8'
        call send
        movlw  ' '
        call send
        movlw  'a'
        call send
        movlw  'l'
        call send
        movlw  'i'
        call send
        movlw  'v'
        call send
        movlw  'e'
        call send
        movlw  0x0D ; CR
        call send
        movlw  0x0A ; LF
        call send
#endif
        return
 
        END

But this code doesn't function correctly:
The green led is now working fine, but the pic doesnt react to any commands i send to it anymore (right, left, back, forward)
 
Last edited:
Is there any possible way you can post up a detailed description of exactly what this code is supposed to do, what type of input you're feeding it as well as how it should react to each possible input?
 
Last edited:
Maybe I missed the boat but there no reaction code in it That I see

right equ b'00001000' ;8, RB3
left equ b'00000100' ;4, RB2
back equ b'00000010' ;2, RB1
forward equ b'00000001' ;1 RB0

There never used in that code any where but in the define
 
Last edited:
I thought so as well, but yet the green led shows on a wrong port so there must be something in the code, I can't find it either though.
 
Status
Not open for further replies.

Latest threads

Back
Top