Serial Communications

 

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:

TABLE 2: PIC16F84-to-PC SERIAL CIRCUIT

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

 

 

 

 

 

 

 

Detail.jpg (295247 bytes)

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.

    100_0007.JPG (613667 bytes) 100_0009.JPG (578172 bytes)

 


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.