Hi, i am going to ask a rather stupid question but i really need to know if it is possible or not.
I have a PIC18F4520 which has only one UART port.
Is it possible to somehow add multiple UARTs only in software?
Maybe one connected to RS-485 IC and one connected to RS-232
Can you please give me the link to his tutorial. I didn't quite find it. I one i did find was simple RS-232 interface.
Also i am looking to do this in C language
Thanks though
Thank you very muchI will give the links a look and bother again if something turns up.
Bytheway, are you as experienced as your avatar (display image) ?
wow. very cool.
you must have done a lot of projects on these things that we are just beginning to learn.
main_loop
call clock_out
call clock_in_main
call clock_in_sec
goto main_loop
;Hacking a Rover 75
;This accepts the data strings from 2 sets of window switches
;and puts together a composite that fools the car into thinking that there is just one set
;FONT ALERT:- There is no L or l (lowercase L) (which can look like 1 (one)
;The data is at 1200 baud
;The data is sent 4 times
;It is sent when the signal changes or every second
;There are 26 bits of data
;10ab0cd0e0f1110gh0ij0e1k11
;a = front right down
;b = front right up
;c = front left down
;d = front left up
;e = disable rear window switches
;f = parity for bits a,b,c,d and e
;g = rear right down
;h = rear right up
;i = rear left down
;j = rear left up
;k = parity for bits g, h, i, j, e and 1
;The Output drivers invert the signals so the output driving commands are inverted
#include p12f629.inc
zero equ z
carry equ c
data_out_p equ 0x05
data_out equ 0x02
main_in_p equ 0x05
main_in equ 0x01
sec_in_p equ 0x05
sec_in equ 0x00
send_now_r equ 0x20
send_now equ 0x00 ;just a bit
sendbit_r equ 0x20
sendbit equ 0x01
parity_r equ 0x20
parity equ 0x02
send_fast_r equ 0x20
send_fast equ 0x03
clock_out_mode equ 0x21
time1s_msb equ 0x22
time1s_lsb equ 0x23
bit_out_count equ 0x24
clock_in_mode_main equ 0x25
clock_in_time_main equ 0x26
clock_in_mode_sec equ 0x27
clock_in_time_sec equ 0x28
data_out1 equ 0x30
data_out2 equ 0x31
data_out3 equ 0x32
data_shift_reg_1 equ 0x34
data_shift_reg_2 equ 0x35
data_shift_reg_3 equ 0x36
data_in_main_1 equ 0x38
data_in_main_2 equ 0x39
data_in_main_3 equ 0x3a
data_in_sec_1 equ 0x3c
data_in_sec_2 equ 0x3d
data_in_sec_3 equ 0x3e
data_main_1 equ 0x40
data_main_2 equ 0x41
data_main_3 equ 0x42
data_sec_1 equ 0x44
data_sec_2 equ 0x45
data_sec_3 equ 0x46
Initialise
bsf status, rp0
movlw b'11000100'
movwf option_reg
movlw b'00000011'
movwf gpio
bcf status, rp0
movlw 0x07
movwf cmcon
clrf clock_out_mode
clrf time1s_msb
clrf time1s_lsb
clrf bit_out_count
clrf data_out1
clrf data_out2
clrf data_out3
clrf data_main_1
clrf data_main_2
clrf data_main_3
clrf data_sec_1
clrf data_sec_2
clrf data_sec_3
;set up outputs and timers
;with a 19.6608 MHz crystal there are 4096
;instruction cycles for each data bit at
;1200 baud
;tmr0 msb toggles at 1200 Hz
;so tmr0 rolls over 600 Hz
;600*256*4*32=19660800 so prescale of 32 is needed
main_loop
call clock_out
call clock_in_main
call clock_in_sec
goto main_loop
clock_out
;clock_out_mode is 0 while waiting
;1 to 4 when sending
;Sending mode must wait until the stop bits have been sent before ending.
;Timer will be reset when it ends
movf clock_out_mode, w
btfss status, zero
goto sending
clrf bit_out_count
;load up new data, which doesn't need to be done each time, but it doesn't hurt
;data_main_1
;data_sec_1
;data_out1
movf data_main_1, w
iorwf data_sec_1, w
movwf data_out1
movf data_sec_2, w
andlw b'01111111' ;cut rear window disable bit out of secondary signal
iorwf data_main_2, w
movwf data_out2
movf data_sec_3, w
andlw b'11111011' ;cut rear window disable bit out of secondary signal
iorwf data_main_3, w
movwf data_out3
bcf data_out2, 5 ;clear parity bit of data_out2
movlw b'00100000' ;parity bit of data_out2
btfsc data_out1, 5
xorwf data_out2, f ;parity for bit a
btfsc data_out1, 4
xorwf data_out2, f ;parity for bit b
btfsc data_out1, 2
xorwf data_out2, f ;parity for bit c
btfsc data_out1, 1
xorwf data_out2, f ;parity for bit d
btfsc data_out2, 7
xorwf data_out2, f ;parity for bit e
bsf data_out3, 0 ;set parity bit of data_out3 ('cos of the 1 after the second e)
movlw b'00000001' ;parity bit of data_out2
btfsc data_out2, 0
xorwf data_out3, f ;parity for bit a
btfsc data_out3, 7
xorwf data_out3, f ;parity for bit b
btfsc data_out3, 5
xorwf data_out3, f ;parity for bit c
btfsc data_out3, 4
xorwf data_out3, f ;parity for bit d
btfsc data_out3, 2
xorwf data_out3, f ;parity for bit e
movf data_out1, w
movwf data_shift_reg_1
movf data_out2, w
movwf data_shift_reg_2
movf data_out3, w
movwf data_shift_reg_3
;10ab0cd0 e0f1110g h0ij0e1k 11
;a = front right down
;b = front right up
;c = front left down
;d = front left up
;e = disable rear window switches
;f = parity for bits a,b,c,d and e
;g = rear right down
;h = rear right up
;i = rear left down
;j = rear left up
;We need to change the repeat frequency if any of the main 8 bits are set
bcf send_fast_r, send_fast
movlw b'00110110' ;checking if bit a, b, c or d is there
andwf data_out1, w
btfss status, zero
bsf send_fast_r, send_fast
btfsc data_out2, 0 ;checking bit g
bsf send_fast_r, send_fast
movlw b'10110000' ;checking if bit h, i, or j is there
andwf data_out3, w
btfss status, zero
bsf send_fast_r, send_fast
;if the flag is set to send immediately,
;do so
btfss send_now_r, send_now
goto wait_1s
incf clock_out_mode, f ;which had to be zero to get here.
bcf send_now_r, send_now ;clear the bit that says it's time to send now
return
wait_1s
;increment time1s_lsb if its bit0 doesn't
;match bit7 of tmr0
btfss time1s_lsb, 0
goto lsb_clr
btfsc tmr0, 7
return
goto increment_time
lsb_clr
btfss tmr0, 7
return
increment_time
incf time1s_lsb, f
btfsc status, zero
incf time1s_msb, f
;the maximum gap between data
;bursts is 1200-(4x26)=1096
;or 4x256+72
;or 1200/5-(4x26)=136
;or 0x256+136
movlw d'0'
btfss send_fast_r, send_fast
movlw d'4'
subwf time1s_msb, w
btfss status, carry
return
btfss status, zero
goto time_done
movlw d'136'
btfss send_fast_r, send_fast
movlw d'72'
subwf time1s_lsb, w
btfss status, carry
return
time_done
incf clock_out_mode, f
return
sending
;This has to put out a bit every time the msb of tmr0 changes
;As the first bits are nulls (high) the first bit doesn't need to be syncronised
btfss sendbit_r, sendbit
goto sendbit_clear
btfsc tmr0, 7
return
goto change_sendbit
sendbit_clear
btfss tmr0, 7
return
change_sendbit
movlw 1<<sendbit
xorwf sendbit_r, f
;If the prog gets here it's time to output the next bit
btfsc data_shift_reg_1, 7
bcf data_out_p, data_out
btfss data_shift_reg_1, 7
bsf data_out_p, data_out
bsf status, carry ;'cos the last 2 bits are always 1
rlf data_shift_reg_3, f
rlf data_shift_reg_2, f
rlf data_shift_reg_1, f
incf bit_out_count, f
movlw d'26'
subwf bit_out_count, w
btfss status, zero
return
clrf bit_out_count
incf clock_out_mode, f
movf data_out1, w
movwf data_shift_reg_1
movf data_out2, w
movwf data_shift_reg_2
movf data_out3, w
movwf data_shift_reg_3
movlw d'5'
subwf clock_out_mode, w
btfsc status, zero
clrf clock_out_mode
clrf time1s_msb
clrf time1s_lsb
return
clock_in_main
;clock_in_mode_main
movf clock_in_mode_main, w
btfss status, zero
goto clock_in_main_running
btfsc main_in_p, main_in
return
;At this point the signal has just started
movf tmr0, w
addlw 0x40
movwf clock_in_time_main
bsf data_in_main_3, 0 ;first bit is always 1
incf clock_in_mode_main, f
return
clock_in_main_running
movf tmr0, w
subwf clock_in_time_main, w
andlw 0x80
btfsc status, zero
return ;see if time is big enough
movlw 0x80
addwf clock_in_time_main, f
incf clock_in_mode_main, f
movlw d'25'
subwf clock_in_mode_main, w
btfsc status, carry
goto main_data_done
bcf status, carry
btfsc main_in_p, main_in
bsf status, carry
rlf data_in_main_3, f
rlf data_in_main_2, f
rlf data_in_main_1, f
return
main_data_done
btfsc main_in_p, main_in
goto main_end_bit_ok
;something has to be done here to fail the result
clrf data_in_main_3
clrf data_in_main_2
clrf data_in_main_1
main_end_bit_ok
movlw d'26'
subwf clock_in_mode_main, w
btfss status, carry
return
clrf clock_in_mode_main
;data check
;data is of the form:- 10ab0cd0e0f1110gh0ij0e1k11
;the last 2 bits have been checked in real time
;so we must check the bytes are of the form:- 10xx0xx0 x0p1110x x0xx0x1p
movlw b'01001001' ;checking that first byte is of the form x0xx0xx0
andwf data_in_main_1, w
btfss status, zero
goto sec_data_fail ;this might be just a return
comf data_in_main_1, w ;checking that the first byte is of the form 1xxxxxxx
andlw b'10000000'
btfss status, zero
goto sec_data_fail ;this might be just a return
movlw b'01000010' ;checking that second byte is of the form x0xxxx0x
andwf data_in_main_2, w
btfss status, zero
goto sec_data_fail ;this might be just a return
comf data_in_main_2, w ;checking that the second byte is of the form xxx111xx
andlw b'00011100'
btfss status, zero
goto sec_data_fail ;this might be just a return
movlw b'01001000' ;checking that third byte is of the form x0xx0xxx
andwf data_in_main_3, w
btfss status, zero
goto sec_data_fail ;this might be just a return
comf data_in_main_3, w ;checking that the third byte is of the form xxxxxx1x
andlw b'00000010'
btfss status, zero
goto sec_data_fail ;this might be just a return
;10xx0xx0 x0p1110x x0xx0x1p
bcf parity_r, parity ;clear parity bit
movlw 1<<parity
btfsc data_in_main_1, 5
xorwf parity_r, f ;parity for bit a
btfsc data_in_main_1, 4
xorwf parity_r, f ;parity for bit b
btfsc data_in_main_1, 2
xorwf parity_r, f ;parity for bit c
btfsc data_in_main_1, 1
xorwf parity_r, f ;parity for bit d
btfsc data_in_main_2, 7
xorwf parity_r, f ;parity for bit e
btfsc data_in_main_2, 5
xorwf parity_r, f ;parity for bit f
btfsc parity_r, parity
goto data_fail ;this might be just a return
;10xx0xx0 x0p1110x x0xx0x1p
;10ab0cd0 e0f1110g h0ij0e1k 11
bsf parity_r, parity ;set parity bit, 'cos bit 2 is always 1, which has been already checked
movlw 1<<parity
btfsc data_in_main_2, 0
xorwf parity_r, f ;parity for bit g
btfsc data_in_main_3, 7
xorwf parity_r, f ;parity for bit h
btfsc data_in_main_3, 5
xorwf parity_r, f ;parity for bit i
btfsc data_in_main_3, 4
xorwf parity_r, f ;parity for bit j
btfsc data_in_main_3, 2
xorwf parity_r, f ;parity for bit e
btfsc data_in_main_3, 0
xorwf parity_r, f ;parity for bit k
btfsc parity_r, parity
goto data_fail ;this might be just a return
;The bit to send immediately is set if the data has changed
movf data_in_main_1, w
xorwf data_main_1, w
btfss status, zero
bsf send_now_r, send_now
movf data_in_main_2, w
xorwf data_main_2, w
btfss status, zero
bsf send_now_r, send_now
movf data_in_main_3, w
xorwf data_main_3, w
btfss status, zero
bsf send_now_r, send_now
;Now the data is considered good so we can copy it to where it gets used
movf data_in_main_1, w
movwf data_main_1
movf data_in_main_2, w
movwf data_main_2
movf data_in_main_3, w
movwf data_main_3
data_fail
return
clock_in_sec
;clock_in_mode_main
movf clock_in_mode_sec, w
btfss status, zero
goto clock_in_sec_running
btfsc sec_in_p, sec_in
return
;At this point the signal has just started
movf tmr0, w
addlw 0x40
movwf clock_in_time_sec
bsf data_in_sec_3, 0 ;first bit is always 1
incf clock_in_mode_sec, f
; bsf 5, 2
return
clock_in_sec_running
movf tmr0, w
subwf clock_in_time_sec, w
andlw 0x80
btfsc status, zero
return ;see if time is big enough
movlw 0x80
addwf clock_in_time_sec, f
incf clock_in_mode_sec, f
; btfsc clock_in_mode_sec, 0
; bsf 5, 2
; btfss clock_in_mode_sec, 0
; bcf 5, 2
movlw d'25'
subwf clock_in_mode_sec, w
btfsc status, carry
goto sec_data_done
bcf status, carry
btfsc sec_in_p, sec_in
bsf status, carry
rlf data_in_sec_3, f
rlf data_in_sec_2, f
rlf data_in_sec_1, f
return
sec_data_done
btfsc sec_in_p, sec_in
goto sec_end_bit_ok
;something has to be done here to fail the result
clrf data_in_sec_3
clrf data_in_sec_2
clrf data_in_sec_1
sec_end_bit_ok
movlw d'26'
subwf clock_in_mode_sec, w
btfss status, carry
return
clrf clock_in_mode_sec
;data check
;data is of the form:- 10ab0cd0e0f1110gh0ij0e1k11
;the last 2 bits have been checked in real time
;so we must check the bytes are of the form:- 10xx0xx0 x0p1110x x0xx0x1p
movlw b'01001001' ;checking that first byte is of the form x0xx0xx0
andwf data_in_sec_1, w
btfss status, zero
goto sec_data_fail ;this might be just a return
comf data_in_sec_1, w ;checking that the first byte is of the form 1xxxxxxx
andlw b'10000000'
btfss status, zero
goto sec_data_fail ;this might be just a return
movlw b'01000010' ;checking that second byte is of the form x0xxxx0x
andwf data_in_sec_2, w
btfss status, zero
goto sec_data_fail ;this might be just a return
comf data_in_sec_2, w ;checking that the second byte is of the form xxx111xx
andlw b'00011100'
btfss status, zero
goto sec_data_fail ;this might be just a return
movlw b'01001000' ;checking that third byte is of the form x0xx0xxx
andwf data_in_sec_3, w
btfss status, zero
goto sec_data_fail ;this might be just a return
comf data_in_sec_3, w ;checking that the third byte is of the form xxxxxx1x
andlw b'00000010'
btfss status, zero
goto sec_data_fail ;this might be just a return
;10xx0xx0 x0p1110x x0xx0x1p
bcf parity_r, parity ;clear parity bit
movlw 1<<parity
btfsc data_in_sec_1, 5
xorwf parity_r, f ;parity for bit a
btfsc data_in_sec_1, 4
xorwf parity_r, f ;parity for bit b
btfsc data_in_sec_1, 2
xorwf parity_r, f ;parity for bit c
btfsc data_in_sec_1, 1
xorwf parity_r, f ;parity for bit d
btfsc data_in_sec_2, 7
xorwf parity_r, f ;parity for bit e
btfsc data_in_sec_2, 5
xorwf parity_r, f ;parity for bit f
btfsc parity_r, parity
goto sec_data_fail ;this might be just a return
;10xx0xx0 x0p1110x x0xx0x1p
;10ab0cd0 e0f1110g h0ij0e1k 11
bsf parity_r, parity ;clear carry bit, 'cos bit 2 is always 1, which has been already checked
movlw 1<<parity
btfsc data_in_sec_2, 0
xorwf parity_r, f ;parity for bit g
btfsc data_in_sec_3, 7
xorwf parity_r, f ;parity for bit h
btfsc data_in_sec_3, 5
xorwf parity_r, f ;parity for bit i
btfsc data_in_sec_3, 4
xorwf parity_r, f ;parity for bit j
btfsc data_in_sec_3, 2
xorwf parity_r, f ;parity for bit e
btfsc data_in_sec_3, 0
xorwf parity_r, f ;parity for bit k
btfsc parity_r, parity
goto sec_data_fail ;this might be just a return
;The bit to send immediately is set if the data has changed
movf data_in_sec_1, w
xorwf data_sec_1, w
btfss status, zero
bsf send_now_r, send_now
movf data_in_sec_2, w
xorwf data_sec_2, w
btfss status, zero
bsf send_now_r, send_now
movf data_in_sec_3, w
xorwf data_sec_3, w
btfss status, zero
bsf send_now_r, send_now
;Now the data is considered good so we can copy it to where it gets used
movf data_in_sec_1, w
movwf data_sec_1
movf data_in_sec_2, w
movwf data_sec_2
movf data_in_sec_3, w
movwf data_sec_3
sec_data_fail
return
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?