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 www.microchip.com 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 www.microchip.com.

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 Sax.net at http://www.sax.net.  There is also, a Free communications control called XMCommCRC written by Richard Grier and posted on his web site http://ourworld.compuserve.com/homepages/richard_grier/xmcomm.htm. 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
Loop
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

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 http://ourworld.compuserve.com/homepages/richard_grier/xmcomm.htm

Sax ActiveX Com Objects (Saxcomm)

 

 http://www.sax.net

PICkit1 8/14P Flash Starter Kit

http://www.Mouser.com

MPLAB IDE

http://www.microchip.com

An Introduction to MPLAB Integrated Development Environment

http://www.microchip.com

Microsoft Visual Basic

http://www.Ebay.com

PICrs232.asm  

PICrs232.asm

PIC 12F675

http://www.Mouser.com

¼ watt resister 22K ohm

http://www.Mouser.com

 

 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 <p12f675.inc>      ; processor specific variable definitions

errorlevel  -302              	; suppress message 302 from list file

__CONFIG   _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT  

; '__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		.102			; .206 = 1200 bits/sec (206)
; .102 = 2400 bits/sec (102)
; .50  = 4800 bits/sec (50)
; .24  = 9600 bits/sec (24)
; .10  =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
;**********************************************************************
Init
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)
movwf	OPTION_REG	
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	
Main
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

again
movlw	h'08'
movwf	bit_cntr

bsf	serial_out		;bsf for direct connection 
;bcf for standard connection 
call 	bit_delay
xmit
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
return

bit_delay
movlw	bit_K
movwf	delay_cntr
loop
nop
decfsz	delay_cntr,1
goto	loop
return

;******************* Receive RS-232 data *******************************
Receive232
nop
start_bit
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
receive
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
return

bit_delay_R
movlw	bit_K
movwf	delay_cntr
loop_R
nop
decfsz	delay_cntr,1
goto	loop_R
return

start_delay
movlw	half_bit
movwf	delay_cntr
loop_R2
nop
decfsz	delay_cntr,1
goto	loop_R2
return	

END           ; directive 'end of program'
Figure 2  Schematic

Figure 3 Visual Basic Form

return to home page

E-Mail to:
jerry_baumeister@msn.com

Copyright ©,Jerry Baumeister
4/17/2005 0 ;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 .102 ; .206 = 1200 bits/sec (206) ; .102 = 2400 bits/sec (102) ; .50 = 4800 bits/sec (50) ; .24 = 9600 bits/sec (24) ; .10 =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 ;********************************************************************** Init 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) movwf OPTION_REG 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 Main 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 again movlw h'08' movwf bit_cntr bsf serial_out ;bsf for direct connection ;bcf for standard connection call bit_delay xmit 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 return bit_delay movlw bit_K movwf delay_cntr loop nop decfsz delay_cntr,1 goto loop return ;******************* Receive RS-232 data ******************************* Receive232 nop start_bit 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 receive 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 return bit_delay_R movlw bit_K movwf delay_cntr loop_R nop decfsz delay_cntr,1 goto loop_R return start_delay movlw half_bit movwf delay_cntr loop_R2 nop decfsz delay_cntr,1 goto loop_R2 return END ; directive 'end of program'

Figure 2  Schematic

Figure 3 Visual Basic Form

return to home page

E-Mail to:
jerry_baumeister@msn.com

Copyright ©,Jerry Baumeister
4/17/2005