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.

32 Bit Serial IO Expander Firmware Check

Status
Not open for further replies.

freeskier89

New Member
Hey there, I am planning planning on building a serial (RS-232) to 32 bit parallel converter, where my application on the computer will send a 4 bytes sequentially out of the serial port through a MAX202 and then the into a PIC16F914. The PIC then shifts the first byte into PORTA, the second byte into PORTB, etc. RE0 is used as the serial input pin. Oh, and I am using the internal oscillator set at 4mhz, and not using the hardware usarts.

32-TIP105 PNP Darlingtons will be hooked up to each pin of Port A though D with a 1K resistor to drive a load that is probably about an amp or two.
This is my first asm project so I just was wondering if you someone could take a quick look over my firmware, and identify my bad practices, and where I could be more efficient with the code.

Thanks a lot!

ps: Did I do the delay timing right? I know its not exactly 104 or 52uS but the max it would drift over 8 bits would be 8uS or so, which would be fine.

Code:
;Device: PIC16F914
;Configuration Word: 0x3FF4

;<-----Initial Variables---->
BITCOUNTER 	EQU 20h
BUFFER 		EQU 21h 	;GP register used to temporarily hold a recieved byte from the serial port 
STATUS 		EQU 03h

RP0 EQU 5		;Bank Selection Bits
RP1 EQU 6 

ANSEL 	EQU 91h	;Port setup register references
LCDCON 	EQU 107h
OSCCON 	EQU 8Fh
CMCON0 	EQU 9Ch
STATUS	EQU 03h
PORTA 	EQU 05h
PORTB 	EQU 06h
PORTC 	EQU 07h
PORTD 	EQU 08h
PORTE 	EQU 09h
TRISA 	EQU 85h
TRISB 	EQU 86h
TRISC 	EQU 87h
TRISD 	EQU 88h
TRISE 	EQU 89h

;<----Port Setup---->;

BCF 	STATUS,RP0	;Goto Bank 0
BCF 	STATUS,RP1
MOVLW 	FFh 		;Set all ports A-D high
MOVWF 	PORTA
MOVWF 	PORTB
MOVWF 	PORTC
MOVWF 	PORTD
CLRF 	PORTE 		;Set port E low
BSF 	STATUS,RP0 	;Goto bank 1
MOVLW  	07h 		; '00000111'
MOVWF  	CMCON0		; Turn Comparators Off
CLRF 	ANSEL		; Configure pins of PortE as Digital IO

BCF OSCCON,4	;Configure the internal oscillator to run at 4mhz (RCF<2:0?> = '110')
BSF OSCCON,5
BSF OSCCON,6
		
CLRF 	TRISA		;Set all pins in port A though D as output
CLRF 	TRISB
CLRF 	TRISC
CLRF 	TRISD
MOVLW 	01h 		;Make RE0 an input and the rest output
MOVWF 	TRISE
BCF 	STATUS,RP0 	;Go to bank 2
BSF 	STATUS,RP1
CLRF 	LCDCON 		;Turn off LCD Control
BCF 	STATUS,RP1 	;Go back to bank 0

;<------Main Program Loop------>
MAIN 	BTFSC 	PORTE,0		; If there is a start bit present on RE0, proceed to to read the byte, else, check for a start bit again\
		GOTO	MAIN
		BCF 	PORTE,1		;Turn Error LED Off
		BSF 	PORTE,2		;Turn Data LED ON
		CALL 	READSERBYTEW
		MOVWF 	PORTA		
		CALL 	READSERBYTEW
		MOVWF 	PORTB
		CALL 	READSERBYTEW
		MOVWF 	PORTC		
		CALL 	READSERBYTEW
		MOVWF 	PORTD		
		BCF 	PORTE,2		;Turn Data LED OFF
		
			
READSERBYTEW
	MOVLW 	08h 		;Set a variable saying there are 8 more bits to read
	MOVWF 	BITCOUNTER
	CALL 	WAITHALFBIT ;Get on the center of the pulse
	STARTBYTE 	BTFSC 	PORTE,0  	;Make sure the start bit is still there
				GOTO 	STARTBYTE	;If it is not there wait until it is
				CLRF 	BUFFER		;Clear the buffer
	READBIT	CALL 	WAITBIT
			BTFSC 	PORTE,0
			BCF 	STATUS, 0  	;Set the Carry Bit in the Status Register so that a 0 is shifted into the buffer (Yes these are inverted from what you would expect. I am driving pnp transistors)
			BSF 	STATUS, 0	;Set the Carry Bit in the Status Register so that a 1 is shifted into the buffer
			RRF 	BUFFER, 1
			DECFSZ 	BITCOUNTER, 1
			GOTO 	READBIT
			CALL 	WAITBIT 	;Wait for the stop bit
			BTFSS 	PORTE, 0
			GOTO 	READERROR
			MOVFW 	BUFFER 		;Move the byte in the buffer to the W register
			RETURN
			READERROR	BSF PORTE, 1	;Turn error led on
				MOVLW	0xFF 			;If there is an error turn all of the pnp transistors off
				RETURN	

WAITBIT ;Set count variable location to an unoccupied general purpose register
	    ;Set the COUNT Variable to what is in the W register
								;1uS (call)
		MOVLW d'33'				;1uS
		MOVWF COUNT				;1uS
		LOOP	DECFSZ COUNT,1	;1uS x 33
				GOTO LOOP		;2uS x 33
		RETURN					;1uS			Total Delay: 102uS

WAITHALFBIT
								;1uS (call)
		MOVLW d'16'				;1uS
		MOVWF COUNT				;1uS
		LOOP	DECFSZ COUNT,1	;1uS x 16
				GOTO LOOP		;2uS x 16
		RETURN					;1uS      		Total Delay: 51uS

END
 
My first comment is WHY aren't you using the MicroChip include file?, it defines all the registers and names you need, plus it saves you typing them all in and potentially making a mistake.

Second, you're not defining the config word in the source code, this is seriously advisable - by MicroChip, and ME! (and anyone else who programs PIC's).

Third, check my PIC tutorials, which already do pretty well what you want, including software RS232.

Fourth, the technique of sending four bytes like this gives no indication of which byte is which, if anything happens that causes it to miss a byte (or a bit) then it will get out of sync, which is disasterous. You might consider sending MUCH more data, ASCII instead of binary, and some sort of byte to signify the start and end of the data.
 
Alright thanks Nigel, I will definitely take all of that into consideration. My main reason for doing the register bit the way it was was because I kind of wanted to get a feel of where the registers were, so i did it manually. Ill go ahead and add the include file. I have been looking through your RS232 tutorial, and it is sort of where I got the structure for sending the byte to the serial port. I would prefer to just use the structure for reference, rather than just copying and pasting the code. I really have found that I learn more that way :)

About receiving the 4 bytes, I will go a ahead and add some more data so that the pic can identify where in the data recieval process it is. The out of sync issue with the 4 bytes kind of came to me when coding it, but for some reason I did not think it would be too big of a deal. More I think about it, It would be a big deal :).

Thanks for the suggestions. Those are the types of things I was looking for :)
 
Alright I just was thinking about the structure of each byte being sent to the pic via the serial port. Do you think this below would be fine? I know it could probably be optimized and does not utelize ascii, but I do not need my device to do any superfast switching.

0: Port Select Bit 1 (00=portA, 01=portB,10=PortC,11=PortD)
1: Port Select Bit 2
2: Port Section Select (1: following bits go to PortN<7:4>, 0: following bits go to PortN<3:0>)
3: Data Bit 1
4: Data Bit 2
5: Data Bit 3
6: Data Bit 4
7: Undefined (Probably will go towards extra error checking)

This way, no matter when the byte is recieved, it knows where to go.
 
I would suggest a simple ASCII system, use four ASCII bytes for each port, and you could only send data to one port if you wanted? - so something like this:

A123 - sets port A to 123 decimal.
C255 - sets port C to 255 decimal.
B000 - sets port B to zero decimal.

You get the idea?, the software only has to check for ONE byte, and see if it's A, B, C or D, then it knows it's at the start of a valid following three bytes!. If it's NOT A, B, C or D, then the software knows it's not at a valid position, so goes back and reads a first byte again.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top