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 |
|
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 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 ;********************************************************************** 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
return to home page
Copyright ©,Jerry Baumeister
4/17/2005