Serial Comm btwn PIC and Stamp
Okay guys.... back with another question, i am really lost here. I
am using the following code in MPLAB, on a PIC16F84, and trying to
read serial data from the serout command (serout 8, 16572, [noparse][[/noparse]"U"]) or
(serout 8, 188, [noparse][[/noparse]"U"]) from a BS2 with out a line driver or RS232
converter chip. Can anyone tell me why this isnt working? And maybe
what the difference between the serial data being driven or not
driven when coming out of the stamp (ie bit 15 of the baud
calculation). Thanks guys, much appreciated.
;=======serial.asm=========================================08/17/02==
;
list p=16f84
radix hex
#include <p16f84.inc>
;
;
;
; cpu equates (memory map)
temp equ 0x0C
rcvreg equ 0x0D
count equ 0x0E
count1 equ 0x0F
temp1 equ 0x10
;
;
; bit equates (constants)
;
;
;
org 0x000
;
start bsf STATUS, RP0
movlw b'000000001' ;make RA0 and input
movwf TRISA
movlw 0x00
movwf TRISB
bcf STATUS, RP0
;
movlw 0xFF
call send
call rcv4800
movf rcvreg, w
call send
again goto again
;
;
;
rcv4800 bcf INTCON,5 ;disable tmr0 interrupts
bcf INTCON,7 ;disable global interrupts
clrf TMR0 ;clear timer/counter
clrwdt ;clear wdt prep prescaler assign
bsf STATUS,RP0 ;to bank 1
movlw b'11011000' ;set up timer/counter
movwf OPTION_REG
bcf STATUS,RP0 ;back to page 0
movlw 0x08 ;init shift counter
movwf count1
sbit btfss PORTA,0 ;look for start bit
goto sbit ;
movlw 0x98 ;start bit received, half bit time
movwf TMR0 ;load and start timer/counter
bcf INTCON,2 ;clear tmr0 overflow flag
time1 btfss INTCON,2 ;timer overflow?
goto time1 ;no
btfsc PORTA,0 ;start bit still low?
goto sbit ;false start, go back
movlw 0x30 ;real, define N for timer
movwf TMR0 ;start timer/ctr - bit time
bcf INTCON,2 ;clear tmr0 overflow flag
time2 btfss INTCON,2 ;timer overflow?
goto time2 ;no
movlw 0x30 ;yes, define N for timer
movwf TMR0 ;start timer/ctr
bcf INTCON,2 ;clear tmr0 overflow flag
movf PORTA,w ;read port A
movwf temp1 ;store
rrf temp1,f ;rotate bit 0 into carry flag
rrf rcvreg,f ;rotate carry into rcvreg bit 7
decfsz count1,f ;shifted 8?
goto time2 ;no
stbit btfsc PORTA,0 ;look for stop bit
goto stbit ;
movlw 0x30 ;yes, define N for timer
movwf TMR0 ;start timer/ctr
time3 btfss INTCON,2 ;timer overflow?
goto time3 ;no
return ;yes, byte received
;
;
;
;With 74HC164 serial in parallel out shift register
;
send movwf temp ;make copy of byte
bsf PORTB, 2 ;clear shift register
bcf PORTB, 2
bsf PORTB, 2 ;reset shift register
bcf PORTB, 1
movlw 0x08 ;load 8 into counter
movwf count
testbit bcf PORTB, 0 ;clear bit
btfsc temp, 7 ;test MSB bit
bsf PORTB, 0 ;set bit
bsf PORTB, 1 ;clock in
bcf PORTB, 1
rlf temp, f ;shift number left
decfsz count, f ;decrement bit counter
goto testbit ;next bit
return ;done
;
;
;
end ;end program
;
;
; Oscillator: XT (standard 4Mhz crystal)
; Watchdog Timer: Off
; Power Up Timer: On
; Code Protect: Off
;====================================================================
am using the following code in MPLAB, on a PIC16F84, and trying to
read serial data from the serout command (serout 8, 16572, [noparse][[/noparse]"U"]) or
(serout 8, 188, [noparse][[/noparse]"U"]) from a BS2 with out a line driver or RS232
converter chip. Can anyone tell me why this isnt working? And maybe
what the difference between the serial data being driven or not
driven when coming out of the stamp (ie bit 15 of the baud
calculation). Thanks guys, much appreciated.
;=======serial.asm=========================================08/17/02==
;
list p=16f84
radix hex
#include <p16f84.inc>
;
;
;
; cpu equates (memory map)
temp equ 0x0C
rcvreg equ 0x0D
count equ 0x0E
count1 equ 0x0F
temp1 equ 0x10
;
;
; bit equates (constants)
;
;
;
org 0x000
;
start bsf STATUS, RP0
movlw b'000000001' ;make RA0 and input
movwf TRISA
movlw 0x00
movwf TRISB
bcf STATUS, RP0
;
movlw 0xFF
call send
call rcv4800
movf rcvreg, w
call send
again goto again
;
;
;
rcv4800 bcf INTCON,5 ;disable tmr0 interrupts
bcf INTCON,7 ;disable global interrupts
clrf TMR0 ;clear timer/counter
clrwdt ;clear wdt prep prescaler assign
bsf STATUS,RP0 ;to bank 1
movlw b'11011000' ;set up timer/counter
movwf OPTION_REG
bcf STATUS,RP0 ;back to page 0
movlw 0x08 ;init shift counter
movwf count1
sbit btfss PORTA,0 ;look for start bit
goto sbit ;
movlw 0x98 ;start bit received, half bit time
movwf TMR0 ;load and start timer/counter
bcf INTCON,2 ;clear tmr0 overflow flag
time1 btfss INTCON,2 ;timer overflow?
goto time1 ;no
btfsc PORTA,0 ;start bit still low?
goto sbit ;false start, go back
movlw 0x30 ;real, define N for timer
movwf TMR0 ;start timer/ctr - bit time
bcf INTCON,2 ;clear tmr0 overflow flag
time2 btfss INTCON,2 ;timer overflow?
goto time2 ;no
movlw 0x30 ;yes, define N for timer
movwf TMR0 ;start timer/ctr
bcf INTCON,2 ;clear tmr0 overflow flag
movf PORTA,w ;read port A
movwf temp1 ;store
rrf temp1,f ;rotate bit 0 into carry flag
rrf rcvreg,f ;rotate carry into rcvreg bit 7
decfsz count1,f ;shifted 8?
goto time2 ;no
stbit btfsc PORTA,0 ;look for stop bit
goto stbit ;
movlw 0x30 ;yes, define N for timer
movwf TMR0 ;start timer/ctr
time3 btfss INTCON,2 ;timer overflow?
goto time3 ;no
return ;yes, byte received
;
;
;
;With 74HC164 serial in parallel out shift register
;
send movwf temp ;make copy of byte
bsf PORTB, 2 ;clear shift register
bcf PORTB, 2
bsf PORTB, 2 ;reset shift register
bcf PORTB, 1
movlw 0x08 ;load 8 into counter
movwf count
testbit bcf PORTB, 0 ;clear bit
btfsc temp, 7 ;test MSB bit
bsf PORTB, 0 ;set bit
bsf PORTB, 1 ;clock in
bcf PORTB, 1
rlf temp, f ;shift number left
decfsz count, f ;decrement bit counter
goto testbit ;next bit
return ;done
;
;
;
end ;end program
;
;
; Oscillator: XT (standard 4Mhz crystal)
; Watchdog Timer: Off
; Power Up Timer: On
; Code Protect: Off
;====================================================================
Comments
__CONFIG directive is absent.
If you use baud value 188 (true), you're telling the Stamp to send
data like this:
baud rate is 4800
idle line is physical high
start bit is a physical low
a logical one is a physical high
stop bit is a physical high
If you use 16572 (inverted) instead, you're telling the Stamp to send
data this way:
baud rate is 4800
idle line is physical low
start bit is a physical high
a logical one is a physical low
stop bit is a physical low
Your Stamp and PIC can work either way so long as both are making
the same assumptions. Things don't look consistent to me in your
code as noted below.
> sbit btfss PORTA,0 ;look for start bit
> goto sbit ;
This looks for a physical high start bit (true logic).
> movlw 0x98 ;start bit received, half bit time
> movwf TMR0 ;load and start timer/counter
> bcf INTCON,2 ;clear tmr0 overflow flag
> time1 btfss INTCON,2 ;timer overflow?
> goto time1 ;no
> btfsc PORTA,0 ;start bit still low?
> goto sbit ;false start, go back
This expects the start bit to (still) be _low_, which conflicts with
the above.
> movlw 0x30 ;real, define N for timer
> movwf TMR0 ;start timer/ctr - bit time
> bcf INTCON,2 ;clear tmr0 overflow flag
> time2 btfss INTCON,2 ;timer overflow?
> goto time2 ;no
> movlw 0x30 ;yes, define N for timer
> movwf TMR0 ;start timer/ctr
> bcf INTCON,2 ;clear tmr0 overflow flag
> movf PORTA,w ;read port A
> movwf temp1 ;store
> rrf temp1,f ;rotate bit 0 into carry flag
> rrf rcvreg,f ;rotate carry into rcvreg bit 7
This assumes true logic, otherwise you'd have to invert the detected
physical logic levels.
> decfsz count1,f ;shifted 8?
> goto time2 ;no
> stbit btfsc PORTA,0 ;look for stop bit
> goto stbit ;
This expects the stop bit to be a physical low (inverted logic).
> movlw 0x30 ;yes, define N for timer
> movwf TMR0 ;start timer/ctr
> time3 btfss INTCON,2 ;timer overflow?
> goto time3 ;no
>
With regard to driven vs. open baud modes, I don't know how to
explain it any better than the manual.
Regards,
Steve