This Tutorial is a continuation of the Introduction to Pic Microcontroller Tutorial. Please refer to that for addtional information
The
PIC16F84 has no serial port but with some hardware and programming, PIC-to-PC serial
communication can be established. Typically the PC's serial port has a DB9 male connector.
The PC run a terminal program like Windows' Hyperterminal. The PIC can send or receive
8-bit values at prescribed intervals (baud rate). The PIC programs rcv1_1.asm and ser2_0.c demonstrate
the PIC receiving and sending bytes serially.
Hardware Circuit
The additional parts needed for establishing PIC16F84-to-PC serial communications are given in Table 2 below:
PART DESCRIPTION |
VENDOR |
PART |
PRICE (2002) |
QTY |
|
DB9 RIGHT ANGLE FEMALE CONNECTOR |
JAMECO |
104951 |
0.55 |
1 |
|
SERIAL CABLE MALE/FEMALE DB9 |
RADIO SHACK |
26-117B |
9.99 |
1 |
|
MAX233CPP RS-232 DRIVER/RECEIVER |
JAMECO |
106163 |
4.95 |
1 |
|
20-PIN WIRE WRAP SOCKET |
JAMECO |
169148 |
1.09 |
1 |
|
0.1 INCH HEADERS |
JAMECO |
160881 |
0.39 |
1 |
|
419 HOLE PROTOTYPING CIRCUIT BOARD |
RADIO SHACK |
276-150 |
1.19 |
1 |
|
|
|
|
|
|
|
serial042802a.pdf is the Acrobat file of the same schematic. You will need Adobe's free Acrobat reader to view it.
As you can see, I use the exact board from the previous tutorial but with a little modification. The changes are additional lines running from pin 3,4 from the Max233 to pin 18,17 of the PIC. And some more modification for the Max233. I don't have a right angle DB9 so I improvise a little and use wire to hold down the DB9 pin connector. But showing is a a better way to mount them using the right angle connector.
The photos below show the serial cable's male end plugging into the MAX233 circuit's female connector. The cable's other end would plug into your PC's serial port.
PIC ASM code
Note: download rcv1_1.asm
rather than cutting and pasting from below. The resulting HEX file rcv1_1.hex can be burned
into the PIC16F84.
; FILE: rcv1_1.asm
; AUTH: P.Oh
; DATE: 04/27/02 18:00 1.0 - WORKS
; 04/27/02 18:35 1.1
; DESC: 1.0: PC-to-PIC serial communications. LEDs display binary equivalent
; of key typed on PC
; 1.1: Same as 1.0 but eliminates need for switch
; REFS: rcv4800.asm in PIC'n Techniques p. 219
;--------------------------------------------------------------------------
list p=16f84
radix hex
;--------------------------------------------------------------------------
; CPU EQUATES
tmr0 equ 0x01 ; Timer/counter register
status equ 0x03 ; Status word register. See Easy PIC'n p. 145
portA equ 0x05 ; Port A register
portB equ 0x06 ; Port B register
intCon equ 0x0b ; Interrupt control register
rcvReg equ 0x0c ; General purpose register
count equ 0x0d ; General purpose register
temp equ 0x0e ; General purpose register
optReg equ 0x81 ; File register in Bank 1
trisA equ 0x85 ; File register in Bank 1. See Easy PIC'n p. 145
trisB equ 0x86 ; File register in Bank 1. See Easy PIC'n p. 145
;--------------------------------------------------------------------------
; BIT EQUATES
rp0 equ 5
;--------------------------------------------------------------------------
org 0x000
start bsf status, rp0 ; Switch to Bank 1. See Easy PIC'n p. 145
movlw b'00000101' ; A0, A2 are input and the rest are output
movwf trisA
movlw b'00000000' ; Port B: all output
movwf trisB
bcf status, rp0 ; Switch back to Bank 0
clrf portB
clrf rcvReg
; switch btfsc portA, 2 ; Is A2 equal 0? i.e. is switch closed?
; goto switch ; No, so keep checking
doThis call rcv4800 ; Yes, to serial in subroutine
movf rcvReg, w ; Get byte received
movwf portB ; Display byte on the 8 LEDs
circle goto doThis ; Done
;--------------------------------------------------------------------------
rcv4800 bcf intCon, 5 ; Disable tmr0 interrupts
bcf intCon, 7 ; Disable global interrupts
clrf tmr0 ; Clear timer/counter
clrwdt ; Clear wdt prep prescaler assign
bsf status, rp0 ; to page 1
movlw b'11011000' ; set up timer/counter
movwf optReg
bcf status, rp0 ; Back to page 1
movlw 0x08 ; Init shift counter
movwf count
sbit btfsc portA, 0 ; Look for start bit
goto sbit ; For Mark
movlw 0x98 ;
movwf tmr0 ; Load and start timer/counter
bcf intCon, 2 ; Clear tmr0 overflow flag
time1 btfss intCon, 2 ; Has the timer (bit 2) overflowed? Skip next line if 1
goto time1 ; No
btfsc portA, 0 ; Start bit still low?
goto sbit ; False start, go back
movlw 0x30 ; real, define N for timer
movwf tmr0 ; start timer/counter - bit time
bcf intCon, 2 ; Clear tmr0 overflow flag
time2 btfss intCon, 2 ; Timer overflow?
goto time2 ; No
movlw 0x30 ; Yes, define N for timer
movwf tmr0 ; Start timer/counter
bcf intCon, 2; ; Clear tmr0 overflow flah
movf portA, w ; Read port A
movwf temp ; Store
rrf temp, f ; Rotate bit 0 into carry flag
rrf rcvReg, f ; Rotate carry into rcvReg bit 7
decfsz count, f ; Shifted 8?
goto time2 ; No
time3 btfss intCon, 2 ; Timer overflow?
goto time3 ; No
return ; Yes, byte received
;-----------------------------------------------------------------------
end
;-----------------------------------------------------------------------
; At blast time, select:
; memory unprotected
; watchdog timer disabled
; standard crystal (4 MHz)
; power-up timer on
;=======================================================================
To code makes the PIC16F84 receive serially at 4800 baud, 8 bits, no parity and one stop bit (8N1). With your hardware setup and the PIC16F84 circuit powered up, launch the Windows Hyperterminal program on your PC. Configure Hyperterminal for the desired COM port at 4800 baud and 8N1. If you type the SHIFT and "A" keys, then only two LEDs should light. Recall that uppercase "A" is 65 decimal (01000001 binary).
Example 7: PIC-to-PC serial communication
In this example, the PIC16F84 is programmed to continuously send ASCII values ranging from 65 to 122 serially. This will display characters "A" to "z" on your Windows Hyperterminal. The PIC16F84 code below is written in CCS C. This compiler features functions to handle serial I/O, enabling must shorter programs to be written.
CCS C code
Note: download ser2_0.c
rather than cutting and pasting from below. The resulting HEX file ser2_0.hex can be burned
into the PIC16F84.
// FILE: SER2_0.C
// AUTH: P.OH
// DATE: 04/27/02 22:45 - 1.0 works
// 04/28/02 23:50 - 2.0 started
// VERS: 1.0 - Attempts serial com between PC and PIC
// 2.0 - PIC sends message to PC serially
#include <16F84.H>
#define RS232_XMIT PIN_A1
#define RS232_RCV PIN_A0 // PIC line which receives PC transmission
#use delay(clock=4000000) // 4 MHz OSC
#use rs232(baud=9600, xmit=RS232_XMIT, rcv=RS232_RCV)
main() {
int i;
while(1) {
i = 65; // Recall ASCII 'A' is 65
do {
putc(i);
delay_ms(1000); // send characters every 1 sec
i++;
} while (i<=122); // Recall ASCII 'z' is 122
}
} // end of main
The above CCS C program operates at 9600 baud. Powering up the PIC16F84 circuit and launching Hyperterminal at 8N1 9600 baud, you'll see the alphabet being displayed. Note: The PIC16F84's RA1 line serially transmits (TD) and connects to the MAX233's T1IN (pin 2). Because of the straight-through serial cable, this ultimately connects to the PC's RD (pin 2 on DB9 male or female).
Becarefull: the Baud Rate for the receiving program is different than the sending program
I recommend you to learn the C compiler. It's much faster and easier to understand when you have to go back to your code. .
Future expansion:
Connect the pic to a 7 segment display or an LCD and have the pic display ASCII characters on the display sent by the computer.