Bit Banging Serial Comm's

For Flowcode users to discuss projects, flowcharts, and any other issues related to Flowcode 2 and 3.

Moderators: Benj, Mods

Post Reply
PINTO
Flowcode v5 User
Posts: 71
Joined: Fri Nov 03, 2006 2:28 pm
Location: RSA
Been thanked: 1 time
Contact:

Bit Banging Serial Comm's

Post by PINTO »

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

User avatar
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:

Post by Benj »

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.

PINTO
Flowcode v5 User
Posts: 71
Joined: Fri Nov 03, 2006 2:28 pm
Location: RSA
Been thanked: 1 time
Contact:

Post by PINTO »

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

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

User avatar
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:

Post by Benj »

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.

PINTO
Flowcode v5 User
Posts: 71
Joined: Fri Nov 03, 2006 2:28 pm
Location: RSA
Been thanked: 1 time
Contact:

Post by PINTO »

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

Post Reply