The Very Basic Serial Interface
A PIC 12F675 Microcontroller to Visual Basic Serial Interface

return to home page

One of the more useful PIC microcontroller utilities I have used involves connecting a PIC based circuit to a PC’s serial port.  Many of the new chips have UART/serial capability built in, but not all do.  Fortunately, not having the UART functionality in a particular chip is not a deterrent and a simple serial interface can be accomplished with a few lines of code.  I have used this interface program to download data from a PIC based altimeter circuit used in model rocketry and with a PC based electronic scale circuit to name just two.

Generally speaking there are two methods of programming a PIC to implement a serial interface; by using the real time clock and interrupt functionality or by using timing loops.  I have found that the timing loop method to be adequate for my needs and it has the advantage of being easy to understand and quite simple to work into a program.  

The program I have come to rely on for serial port communications was published in “PIC16Cxx Application Handbook 1.1” (no author was listed). It was published and distributed by Parallax Inc. with their PIC programmer and “starter” kit.  They no longer sell this package and all the utility programs were written in Parallax assembler, which I don’t think they sell or support anymore either.  Since I currently use Microchip’s assembler and development software, MPLAB  IDE, which is available as a free down load at and Microchip’s new 8 pin Flash PIC microcontroller, 12F675, it was necessary to perform some translation and modifications to the old utility.  Also, because the original interface was written for DOS Basic, I needed to translate the PC side of the interface into Visual Basic, which I now use as my primary PC programming language.

Please understand that the purpose of this article is not to provide a comprehensive instruction on PIC programming or Visual Basic.  There are volumes of books written on those subjects.  However, If you are at the beginning level with PIC chip programming and Visual Basic you should not have any trouble using this application. 

The code that follows was translated from Parallax assembler to Microchip assembler and then modified to be used as a subroutine “call” from the main program.  So, for instance if your PIC circuit is running, doing it’s thing, taking measurements, controlling motors, monitoring switches, etc., and it gets to the point where it needs to communicate back to the PC, then at this point it would call the serial transmit subroutine or serial receive subroutine and then jump back to whatever it needed to do.

The following code is the entire file (PICrs232.asm) for implementing the serial communication utility (figure 1).  There are no other “include files” or anything else needed that does not come with the MPLAB  IDE software and is written into the file.   It is written for the 12F675 processor, which has several additional registers that the earlier or more pin prolific processors don’t have.  Because the processor only has 8 pins and has analog to digital, comparator, digital I/O and “Flash” programming functionality built in, all of the pins have multiple functionality depending on the setup of the different registers.  Consequently, it is necessary to have a few lines of code in the initialization part of the program to “setup” the chip.  You can see this code under the “initialize” section of the program listing.

In order to make this a fully functional demonstration program I have included some “test” code under the program listing labeled “Main”.  The rest of the program is the two subroutines for the serial communication transmit and receive.   If you were going to use this in your circuit you would replace the code I have listed in the “Main” section with your code and just call the transmit and receive subroutines as needed.  Also, in the program I used pin 3 for transmit and pin 5 for receive.  You can change this to different pins if you like by changing the program (in the “Assign Constants Value” section). 

To TRANSMIT serial data move the data into the “xmt_byte” variable then call subroutine “xmit232”.  To RECEIVE call the subroutine “receive232” and the subroutine will return the received byte in the “rcv_byte” variable.  The test program is only 5 lines long and is listed under the “Main” section.  It simply receives data from the PC and then transmits it back to the PC.  If you get the same byte back at the PC that you sent then you know it is working.

One of the other nice things about the program, which you will notice when you look at the program listing, is that it can be used for direct connection to a PC (+5 volts=high, 0 volts=low) or by using a true RS-232 signaling connection ( +5 to+15 volts=low,-5 to -15 volts= high).   You will see this indicated by the comment statements next to the lines that need to be modified. The schematic shown and the program listing are for a direct connection.   If you wanted to use the standard RS-232 signaling protocol you would need to add a dual RS-232 transmitter/receiver chip like the Maxim 233 integrated circuit chip. In this case the RS-232 chip would connect directly to the PIC chip and the indicated lines of code changed in the program.  I have never had a problem with the simpler direct connection so you will probably never need to do this unless you anticipate a really long cable between your circuit and the PC.  Since this article is about the “very simple serial interface” we will stay focused on the one PIC chip and one resistor version.  Also, you can set the bits per second rate at 1200, 2400, 4800, 9600, and 19200 bits/second depending on the value assigned to “bit_K”.  The source code is written with bit_K set to a 2400 bits/sec rate, but you can change it if you need to.

I used MPLAB  IDE development environment (assembler) to develop and produce the HEX file.  Next I used the PIC Flash Starter programmer and software to program the chip.  If you use another programmer or development environment you may need to modify this procedure.  If you are not familiar with MPLAB  IDE, I would recommend you read microchips tutorial entitled “An Introduction to MPLAB Integrated Development Environment” available as a download from

The visual basic side of the program is a bit more problematic than it was with the old DOS basic.  For some reason not all Visual Basic packages included the communications tool (MSComm).  If your package includes the communications tool then you are good-to-go, but if it doesn’t you need to purchase one.    I understand that it comes with Visual Basic 6 but not the Visual Basic 6 learning edition.  I purchased a version of the control called PDQ from Crescent systems before they went out of business.  It might still be obtainable although I have not been able to find a source.  Luckily the creators of the original Microsoft communications control are still in business selling an updated and much expanded version called “Sax ActiveX Com Object”.  You can buy it from at  There is also, a Free communications control called XMCommCRC written by Richard Grier and posted on his web site If you use the Sax control you will need to change the “PDQ” to “Sax” everywhere you see it in the program and if you use the “XMCommCRC” control you will need to change the “PDQComm” to “XMCommCRC.

  If you need to install the tool … on the Visual Basic tool bar select Projects/components/controls and search for the communications control and select it with a check mark.

 You will need to open a project in Visual Basic and drop 3 text boxes, two command buttons and the Communications Control (PDQcomm, MSComm, SaxComm or XMCommCRC) on a Visual Basic form.  Add labels as shown in the diagram if you think you need them. (Figure 3)

Enter the following code in “Command 1” (replace “PDQ” with “MS” or “Sax” if using the Microsoft or Sax control or replace PDQComm with XMCommCRC if you are using the XMComm control) :

Private Sub Command1_Click() 

PDQComm1.CommPort = 1
PDQComm1.Settings = "2400,n,8,1"
PDQComm1.PortOpen = True
PDQComm1.InputLen = 1

PDQComm1.Output = Chr$(Text2.Text)

Do While PDQComm1.InBufferCount < 1
sHigh = PDQComm1.Input

Text1.Text = Asc(sHigh)
Text3.Text = sHigh

PDQComm1.PortOpen = False

End Sub


Enter the following code in Command 2:


Private Sub Command3_Click()


End Sub


Notice that the procedure is set for a 2400 bits/sec rate and communications Port #1(com1).  This rate needs to match the rate set in the PIC program and the communications port number needs to be the one you have the cable plugged in to.  Also, you will need to change PDQComm to MSComm or SaxComm or XMCommCRC if you are using the Microsoft communication control, the Sax control or the XMComm control respectively.

Next you will need to program the chip and wire up the circuit using the schematic shown in Figure 2.  Note that the PIC doesn’t require an external oscillator circuit in this application.  It uses the internal 4-megahertz oscillator.

That’s it.  It‘s that simple and from this very basic program you can build some extraordinarily nice designs and applications.

Hope this helps and saves you some time!

Parts and software:

XMCommCRC control

Sax ActiveX Com Objects (Saxcomm)

PICkit1 8/14P Flash Starter Kit


An Introduction to MPLAB Integrated Development Environment

Microsoft Visual Basic



PIC 12F675

¼ watt resister 22K ohm


 Figure 1 PIC 12F675 source code (PICrs232.asm)

;    Filename:	   PICrs232.asm
;    Date:   1-15-05 
;    File Version:    1 
;    Author: j baumeister 
;    Company: himself 
;    Files required 
;                    12F675.lkr 
;    Notes:  This is the basic RS 232 serial communication program    
;    It uses two subroutines, one for transmitting and one for        
;    receiving.  The "test" program listed under "Main" echoes back    
;    the byte that it receives                                            *
;    Pin 3 is the output. Pin 5 the input   It uses a visual basic    
;    program (vBasic_simple_Interface) running on a  the PC  to test the application 

list      p=12f675          	 ; list directive to define processor
#include <>      ; processor specific variable definitions

errorlevel  -302              	; suppress message 302 from list file


; '__CONFIG' directive is used to embed configuration word within .asm file.
; The labels following the directive are located in the respective .inc file.
; See data sheet for additional information on configuration word settings.
; Reset Vector
ORG     0x000            		; processor reset vector
nop				; Inserted For ICD2 Use
goto    Init              		; go to beginning of program

;***** Assign Constants Value *************************************** 
#define	BANK1		banksel 0x80	;Select Bank1
#define	BANK0		banksel 0x00	;Select Bank0
#define serial_in		GPIO,2		;serial data in
#define serial_out		GPIO,4		;serial data out
#define	bit_K		h'DA'			; hex DA = 1200 bits/sec (218)
; hex 6b = 2400 bits/sec (107)
; hex 32 = 4800 bits/sec (50)
; hex 17 = 9600 bits/sec (23)
; hex 0A =19200 bits/sec (10)
#define half_bit		bit_K/2		

;****** Reserve Space for Variables (file registers) ********************
org		0x20	; start at memory location Hex 20
; assign 1, 8 bit byte of memory to each
count		res		1	; used to adjust the delay time
rcv_byte	res		1	; the received byte
delay_cntr	res		1	; counter for serial delay routine
bit_cntr	res		1	; number of transmitted bits
xmt_byte	res		1	; the transmitted byte
Display		res		1	; the variable that carries the byte to be 
; transmitted to the RS-232 subroutine for								; transmission
BANK1					;Switch to Bank1
call   	0x3FF      		; retrieve factory calibration value
movwf   OSCCAL	   		 ; update register with factory cal value 
movlw	B'11011111'		 ;set internal clock(bit5=0)
clrf	VRCON			;Vref Off (power off the comparator voltage, saves power)
clrf	ANSEL
movlw	B'11001101'		; pin 4,5,7 are inputs and pins 2,3,6 are outputs
movwf	TRISIO			;Tri-State pins 4,5,7 .... 2,3,& 6 are outputs
BANK0				;BANK 0
clrf	GPIO			;Clear Port
movlw	0x07		
movwf	CMCON		;Comparator Off
;  this is the "Main" program which in this example is set to receive and re-transmit
;  a byte sent from the computers serial port	
call	Receive232		; receive the byte sent from the computer
movf	rcv_byte,0		; move the received byte to W register
movwf	xmt_byte		; varable used by the xmit subroutine
; contains the byte to be transmitted
call	xmit232			; calls the transmit subroutine
goto	Main			; do it again
;********************************subroutines ***********************
xmit232					; RS-232C serial out.  the byte in file register
; xmt_bute will transmit

movlw	h'08'
movwf	bit_cntr

bsf	serial_out		;bsf for direct connection 
;bcf for standard connection 
call 	bit_delay
rrf	xmt_byte,1
btfsc	STATUS,0		;btfsc	STATUS,0  for direct connection			
;btfss	STATUS,0  for standard connection
bcf	serial_out	
btfss	STATUS,0		;btfss	STATUS,0  for direct connection	
;btfsc	STATUS,0  for standard connection
bsf	serial_out		
call	bit_delay
decfsz	bit_cntr,1
goto	xmit
bcf	serial_out		;bcf for direct connection
;bsf for standard connection
call	bit_delay

movlw	bit_K
movwf	delay_cntr
decfsz	delay_cntr,1
goto	loop

;******************* Receive RS-232 data *******************************
btfss	serial_in			;btfss if connected via 22K resistor
;btfsc if standard connection
goto	start_bit
call	start_delay
btfss	serial_in			;btfss if connect via 22k resistor
; btfsc if standard connection
goto	start_bit	
movlw	h'08'
movwf	bit_cntr
clrf	rcv_byte
call	bit_delay_R
btfsc	serial_in			;btfsc if connect via 22k resistor
;btfss if standard connection
bcf	STATUS,0
btfss	serial_in			;btfss if connect via 22k resistor
;btfsc if standard connection
bsf	STATUS,0		
rrf	rcv_byte,1
decfsz	bit_cntr,1
goto	receive
call 	bit_delay_R

movlw	bit_K
movwf	delay_cntr
decfsz	delay_cntr,1
goto	loop_R

movlw	half_bit
movwf	delay_cntr
decfsz	delay_cntr,1
goto	loop_R2

END           ; directive 'end of program'
Figure 2  Schematic

Figure 3 Visual Basic Form

return to home page

E-Mail to:

Copyright ©,Jerry Baumeister