Hello Ben,
I need to daisy chain a certain number of pic16f84's and communicate serially with each other (repeaters).
I need two independente channels two communicate with each chip.
Since the pic's that have USART only have one than the only way out is to Bit Bang the serial comm's (or is it?).
I've searched the net for code and have come across a few but I'm having problems in incorporating the code into Flowcode.
Could you help with sample code or advise that can be incorperated into flow code.
Tx.
Regards
Pinto Dos Ramos
Bit Banging Serial Comm's
- Benj
- Matrix Staff
- Posts: 15312
- Joined: Mon Oct 16, 2006 10:48 am
- Location: Matrix TS Ltd
- Has thanked: 4803 times
- Been thanked: 4314 times
- Contact:
Hello Pinto
Can you not just use transistors to do the repeating and amplification?
For the bit banging you will need to do something like this. Remember that timing is fairly crutial.
for your required baud you will need to first collect a time period eg.
Baud 9600
Time period = 1 / 9600 = 104.16us
now you will need to devide this time period by 10 to allow for the individual bits of the signal.
Bit time = Time period / 10 = 10.416us
Now you need to set up a loop to either read or write the bits on the bus.
eg
Loop while count < 10
{
if count = 0
output start bit - always 0
if count > 0 && count < 9
{
output data bit 0 from a byte
shift the data byte (var = var >> 1)
}
if count = 9
output stop bit - always 1
delay approx 10.416us
}
A read of the incoming data would be similar to the write and would just involve waiting for the start bit and then reading in a bit at a time by shifting the incoming bits into a byte variable.
Can you not just use transistors to do the repeating and amplification?
For the bit banging you will need to do something like this. Remember that timing is fairly crutial.
for your required baud you will need to first collect a time period eg.
Baud 9600
Time period = 1 / 9600 = 104.16us
now you will need to devide this time period by 10 to allow for the individual bits of the signal.
Bit time = Time period / 10 = 10.416us
Now you need to set up a loop to either read or write the bits on the bus.
eg
Loop while count < 10
{
if count = 0
output start bit - always 0
if count > 0 && count < 9
{
output data bit 0 from a byte
shift the data byte (var = var >> 1)
}
if count = 9
output stop bit - always 1
delay approx 10.416us
}
A read of the incoming data would be similar to the write and would just involve waiting for the start bit and then reading in a bit at a time by shifting the incoming bits into a byte variable.
Regards Ben Rowland - MatrixTSL
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
-
- Flowcode v5 User
- Posts: 71
- Joined: Fri Nov 03, 2006 2:28 pm
- Location: RSA
- Been thanked: 1 time
Hello Ben,
Thanks for you reply.
I need to gather information from the repeater and send it other pic's.
If i have something like this code
Thanks for you reply.
I need to gather information from the repeater and send it other pic's.
If i have something like this code
Code: Select all
LIST p=16F628 ;tell assembler what chip we are using
include "P16F628.inc" ;include the defaults for the chip
ERRORLEVEL 0, -302 ;suppress bank selection messages
__config 0x3D18 ;sets the configuration settings (oscillator type etc.)
cblock 0x20 ;start of general purpose registers
count ;used in looping routines
count1 ;used in delay routine
counta ;used in delay routine
countb ;used in delay routine
templcd ;temp store for 4 bit mode
templcd2
lcdtmp
Xmit_Byte ;holds byte to xmit
Rcv_Byte ;holds received byte
Bit_Cntr ;bit counter for RS232
Delay_Count ;delay loop counter
endc
LCD_PORT Equ PORTA
LCD_TRIS Equ TRISA
LCD_RS Equ 0x04 ;LCD handshake lines
LCD_RW Equ 0x06
LCD_E Equ 0x07
SER_PORT Equ PORTB
SER_TRIS Equ TRISB
SER_IN Equ 0x07
SER_OUT Equ 0x06
org 0x0000
Start movlw 0x07
movwf CMCON ;turn comparators off (make it like a 16F84)
Initialise clrf count
clrf PORTA
clrf PORTB
call SER_INIT ;initialise serial port
call LCD_Init
Loop call Rcv_RS232
call LCD_Char
goto Loop
;Serial routines
SER_INIT
BSF STATUS, RP0 ;select bank 1
BCF SER_TRIS, SER_OUT ;set B6 as an output
BSF SER_TRIS, SER_IN ;set B7 as an input
BCF STATUS, RP0 ;select bank 0
BSF SER_PORT, SER_OUT ;set SER_OUT high
RETURN
XMIT_RS232 MOVWF Xmit_Byte ;move W to Xmit_Byte
MOVLW 0x08 ;set 8 bits out
MOVWF Bit_Cntr
BCF SER_PORT, SER_OUT
CALL Bit_Delay
Ser_Loop RRF Xmit_Byte , f ;send one bit
BTFSS STATUS , C
BCF SER_PORT, SER_OUT
BTFSC STATUS , C
BSF SER_PORT, SER_OUT
CALL Bit_Delay
DECFSZ Bit_Cntr , f ;test if all done
GOTO Ser_Loop
BSF SER_PORT, SER_OUT
CALL Bit_Delay
RETURN
Rcv_RS232 BTFSC SER_PORT, SER_IN ;wait for start bit
GOTO Rcv_RS232
CALL Start_Delay ;do half bit time delay
BTFSC SER_PORT, SER_IN ;check still in start bit
GOTO Rcv_RS232
MOVLW 0x08 ;set up to read 8 bits
MOVWF Bit_Cntr
CLRF Rcv_Byte
Next_RcvBit CALL Bit_Delay
BTFSS SER_PORT, SER_IN
BCF STATUS , C
BTFSC SER_PORT, SER_IN
BSF STATUS , C
RRF Rcv_Byte , f
DECFSZ Bit_Cntr , f ;test if all done
GOTO Next_RcvBit
CALL Bit_Delay
MOVF Rcv_Byte, W
RETURN
Start_Delay MOVLW 0x0C
MOVWF Delay_Count
Start_Wait NOP
DECFSZ Delay_Count , f
GOTO Start_Wait
RETURN
Bit_Delay MOVLW 0x18
MOVWF Delay_Count
Bit_Wait NOP
DECFSZ Delay_Count , f
GOTO Bit_Wait
RETURN
;LCD routines
;Initialise LCD
LCD_Init call LCD_Busy ;wait for LCD to settle
movlw 0x20 ;Set 4 bit mode
call LCD_Cmd
movlw 0x28 ;Set display shift
call LCD_Cmd
movlw 0x06 ;Set display character mode
call LCD_Cmd
movlw 0x0c ;Set display on/off and cursor command
call LCD_Cmd ;Set cursor off
call LCD_Clr ;clear display
retlw 0x00
; command set routine
LCD_Cmd movwf templcd
swapf templcd, w ;send upper nibble
andlw 0x0f ;clear upper 4 bits of W
movwf LCD_PORT
bcf LCD_PORT, LCD_RS ;RS line to 1
call Pulse_e ;Pulse the E line high
movf templcd, w ;send lower nibble
andlw 0x0f ;clear upper 4 bits of W
movwf LCD_PORT
bcf LCD_PORT, LCD_RS ;RS line to 1
call Pulse_e ;Pulse the E line high
call LCD_Busy
retlw 0x00
LCD_CharD addlw 0x30 ;add 0x30 to convert to ASCII
LCD_Char movwf templcd
swapf templcd, w ;send upper nibble
andlw 0x0f ;clear upper 4 bits of W
movwf LCD_PORT
bsf LCD_PORT, LCD_RS ;RS line to 1
call Pulse_e ;Pulse the E line high
movf templcd, w ;send lower nibble
andlw 0x0f ;clear upper 4 bits of W
movwf LCD_PORT
bsf LCD_PORT, LCD_RS ;RS line to 1
call Pulse_e ;Pulse the E line high
call LCD_Busy
retlw 0x00
LCD_Line1 movlw 0x80 ;move to 1st row, first column
call LCD_Cmd
retlw 0x00
LCD_Line2 movlw 0xc0 ;move to 2nd row, first column
call LCD_Cmd
retlw 0x00
LCD_Line1W addlw 0x80 ;move to 1st row, column W
call LCD_Cmd
retlw 0x00
LCD_Line2W addlw 0xc0 ;move to 2nd row, column W
call LCD_Cmd
retlw 0x00
LCD_CurOn movlw 0x0d ;Set display on/off and cursor command
call LCD_Cmd
retlw 0x00
LCD_CurOff movlw 0x0c ;Set display on/off and cursor command
call LCD_Cmd
retlw 0x00
LCD_Clr movlw 0x01 ;Clear display
call LCD_Cmd
retlw 0x00
Pulse_e bsf LCD_PORT, LCD_E
nop
bcf LCD_PORT, LCD_E
retlw 0x00
LCD_Busy
bsf STATUS, RP0 ;set bank 1
movlw 0x0f ;set Port for input
movwf LCD_TRIS
bcf STATUS, RP0 ;set bank 0
bcf LCD_PORT, LCD_RS ;set LCD for command mode
bsf LCD_PORT, LCD_RW ;setup to read busy flag
bsf LCD_PORT, LCD_E
swapf LCD_PORT, w ;read upper nibble (busy flag)
bcf LCD_PORT, LCD_E
movwf templcd2
bsf LCD_PORT, LCD_E ;dummy read of lower nibble
bcf LCD_PORT, LCD_E
btfsc templcd2, 7 ;check busy flag, high = busy
goto LCD_Busy ;if busy check again
bcf LCD_PORT, LCD_RW
bsf STATUS, RP0 ;set bank 1
movlw 0x00 ;set Port for output
movwf LCD_TRIS
bcf STATUS, RP0 ;set bank 0
return
;end of LCD routines
;Delay routines
Long_Delay
call Delay255
call Delay255
call Delay255
call Delay255
return
Delay255 movlw 0xff ;delay 255 mS
goto d0
Delay100 movlw d'100' ;delay 100mS
goto d0
Delay50 movlw d'50' ;delay 50mS
goto d0
Delay20 movlw d'20' ;delay 20mS
goto d0
Delay10 movlw d'10' ;delay 10mS
goto d0
Delay1 movlw d'1' ;delay 1mS
goto d0
Delay5 movlw 0x05 ;delay 5.000 ms (4 MHz clock)
d0 movwf count1
d1 movlw 0xC7
movwf counta
movlw 0x01
movwf countb
Delay_0 decfsz counta, f
goto $+2
decfsz countb, f
goto Delay_0
decfsz count1 ,f
goto d1
retlw 0x00
;end of Delay routines
end
I would like to implmente the serial section of the code into flow code with the aid of a C code icon or icons or Suplimentary code whatever is the suitable way.
The lcd routines will be standard flowcode rotines so they don't have to be incorporated in the C code icon.
Can you help.
Thanks
Pinto
- Benj
- Matrix Staff
- Posts: 15312
- Joined: Mon Oct 16, 2006 10:48 am
- Location: Matrix TS Ltd
- Has thanked: 4803 times
- Been thanked: 4314 times
- Contact:
Hello
You can call functions from the supplementary code by doing the following.
In the Suplementary code window first place your function prototypes.
eg
char addvars(char x, char y);
Then in the implementation window add the C code for the function.
eg
char addvars(char x, char y)
{
return (x + y);
}
You can then call this function from a C code icon using the command
addvars(FCV_NUM1, FCV_NUM2);
Flowcode variables need to have the prefix FCV_ when called via C.
Assembler can be integrated into the code by using asm{}.
More help can be found in the BoostC manual which is located in the BoostC directory of Flowcode.
You can call functions from the supplementary code by doing the following.
In the Suplementary code window first place your function prototypes.
eg
char addvars(char x, char y);
Then in the implementation window add the C code for the function.
eg
char addvars(char x, char y)
{
return (x + y);
}
You can then call this function from a C code icon using the command
addvars(FCV_NUM1, FCV_NUM2);
Flowcode variables need to have the prefix FCV_ when called via C.
Assembler can be integrated into the code by using asm{}.
More help can be found in the BoostC manual which is located in the BoostC directory of Flowcode.
Regards Ben Rowland - MatrixTSL
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
-
- Flowcode v5 User
- Posts: 71
- Joined: Fri Nov 03, 2006 2:28 pm
- Location: RSA
- Been thanked: 1 time
Hi Ben,
Thanks for your reply.
Im having dificulties in understanding the way that the C icons and the suplementary code works.
I think that the problem lies in the fact that I want to implment a full ASM progam into a C icon and obviousely this icons are designed to handle C code with secondary ASM statments. I Think?
The reason is that apparently if you want to bit bang serial comm's the C routines are very slow compared to ASM.
I've been strugling with this project for about 3 weeks now and to be frank I don't have a clue of what Im doing, but wi'll get there?
Thanks
Pinto
Thanks for your reply.
Im having dificulties in understanding the way that the C icons and the suplementary code works.
I think that the problem lies in the fact that I want to implment a full ASM progam into a C icon and obviousely this icons are designed to handle C code with secondary ASM statments. I Think?
The reason is that apparently if you want to bit bang serial comm's the C routines are very slow compared to ASM.
I've been strugling with this project for about 3 weeks now and to be frank I don't have a clue of what Im doing, but wi'll get there?
Thanks
Pinto