Sei sulla pagina 1di 24

Dual RS232 communication routine for PIC16F77

Dual RS232 Communication Routine


with LCD display and two MAX232 for PIC16F77

Table of Contents [Toc]

Concept
Specifications
Project Resources
Available Microchip PIC Assembler Source Code

Concept [Toc] [Top]

Two independent RS232 interfaces, with display of received ASCII characters and corresponding decimal values on the dot matrix LCD.
ASCII values entered on one terminal window are transmitted by the first RS232 link to the controller, displayed on the LCD, and further
transmitted across the second RS232 link to the other terminal window. The microcontroller sends feedback of received characters back to
the issueing terminal window. When the PIC terminal is idle, it sends a status message '@' to both terminals every 2.75 seconds.

This program incorporates two independent RS232 interfaces, one hardware-based and one software-based. The HW-based RS232
interface uses the PIC-internal USART (and interrupts), configured to standard 9600 baud @ 4 MHz PIC clock. The SW-based RS232
interface is based on the module file m_rs096.asm, which performs interrupt-based RS232 reception on PortB0 (INTCON,INTF) at 9600
baud @ 4 MHz PIC clock.

The program shows the implementation and function of the modules m_bank.asm, m_wait.asm, m_lcd.asm, m_lcdv08.asm, and m_rs096.
asm on the PIC16F77.

Dot matrix LCD display


showing output after having received 'a' from the first RS232
terminal and 'b' from the second RS232 terminal. Every
character received is displayed in both ASCII and decimal
value, and then transmitted to the other RS232 terminal across
the second communication link. PIC16F77 test board with two MAX232
Test setup using onboard MAX232 and additional external
MAX232 to serve both RS232 links. The PIC controller now serves
two asynchronous RS232 connections, one in software mode using
interrupts and one using the hardware USART of the PIC16F77.

http://www.trash.net/~luethi/microchip/projects/rs232/dual_rs232/dual_rs232.html (1 of 3)13/02/2008 19:35:21


Dual RS232 communication routine for PIC16F77

Screen shot of the two HyperTerminal Programs


using the dual RS232 communication routine. The left window configured to ComPort 5 represents the first link, the right window
configured to ComPort 7 represents the second link. After power-up and welcome message, the message 'Hello World' was entered at the
left terminal window, then the message 'I say also hello' was transmitted using the right terminal window.

Specifications [Toc] [Top]

Processor: Microchip PIC 16F77


Clock Frequency: 4 MHz crystal
Throughput: 1 MIPS
RS232 Configuration: 9600 with BRGH = 1
RS232 Baud Rate: 9600 baud, 8 bit, no parity, 1 stopbit
Code Size of entire Program: approx. 733 instruction words
Acquisition Methodology: SW-based RS232: Interrupt-based RS232 data acquisition
HW-based RS232: Preemptive, interrupt-based RS232 data acquisition,
LCD display output and RS232 echo during normal operation
Required Hardware: two MAX 232 for two RS232 interfaces, dot matrix LCD display
Required Software: RS232 terminal software (or Excel 97 RS232 Debug Interface)

Project Resources [Toc] [Top]

http://www.trash.net/~luethi/microchip/projects/rs232/dual_rs232/dual_rs232.html (2 of 3)13/02/2008 19:35:21


Dual RS232 communication routine for PIC16F77

Available Microchip PIC Assembler Source Code [Toc] [Top]

Main File HEX Files

Download assembler source code: Download Hex File:


16F77dual.asm 16F77dual.hex

The above program needs additional include files (modules) to get successfully assembled: m_bank.asm, m_wait.asm, m_lcd.asm

For those, who are not familiar with interfacing a PIC to the RS232 using a MAX232: RS232-Interface.pdf (9.7 kB)

Download ASCII Character Map: ASCII-Map.pdf

Last updated: 16.01.2005

[Toc] [Top]

If you see only this page in your browser window,


click here
to get the entire site.

http://www.trash.net/~luethi/microchip/projects/rs232/dual_rs232/dual_rs232.html (3 of 3)13/02/2008 19:35:21


http://www.trash.net/~luethi/microchip/projects/rs232/dual_rs232/16F77dual.asm

;***************************************************************************
;
; Dual RS232 Software Interface for PIC 16F77 V1.00
; =================================================
;
; written by Peter Luethi, 15.01.2005, Urdorf, Switzerland
; http://www.electronic-engineering.ch
; last update: 16.01.2005
;
; V1.00: Initial release (16.01.2005)
;
; This code and accompanying files may be distributed freely and
; modified, provided this header with my name and this notice remain
; intact. Ownership rights remain with me.
; You may not sell this software without my approval.
;
; This software comes with no guarantee or warranty except for my
; good intentions. By using this code you agree to indemnify me from
; any liability that might arise from its use.
;
;
; SPECIFICATIONS:
; ===============
; Processor: Microchip PIC 16F77 (16C74A)
; Clock Frequency: 4.00 MHz (HS mode)
; Throughput: 1 MIPS
; RS232 Configuration: 9600 with BRGH = 1
; RS232 Baud Rate: 9600 baud, 8 bit, no parity, 1 stopbit
; Required Hardware: two MAX 232 for two RS232 interfaces,
; dot matrix LCD display
; Code Size of entire Program: approx. 733 instruction words
; Acquisition Methodology: SW-based RS232: Interrupt-based RS232
; data acquisition
; HW-based RS232: Preemptive,
; interrupt-based RS232 data acquisition
; with LCD display output and RS232 echo
; during normal operation
;
;
; ABSTRACT:
; =========
; Dual RS232 terminal: Two independent RS232 interfaces, with

http://www.trash.net/~luethi/microchip/projects/rs232/dual_rs232/16F77dual.asm (1 of 15)13/02/2008 19:36:34


http://www.trash.net/~luethi/microchip/projects/rs232/dual_rs232/16F77dual.asm

; display of received ASCII characters and corresponding decimal


; values on the dot matrix LCD. ASCII values entered on one terminal
; window are transmitted by the first RS232 link to the controller,
; displayed on the LCD, and further transmitted across the second
; RS232 link to the other terminal window.
; The microcontroller sends feedback of received characters back to
; the issueing terminal window. When the PIC terminal is idle, it
; sends a status message '@' to both terminals every 2.75 seconds.
;
;
; DESCRIPTION:
; ============
; Developed and tested on PIC16F77.
; This program incorporates two independent RS232 interfaces, one
; HW-based and one SW-based RS232 interface.
; The HW-based RS232 interface uses the PIC-internal USART (and
; interrupts), configured to standard 9600 baud @ 4 MHz PIC clock.
; The SW-based RS232 interface is based on the module file m_rs096.asm,
; which performs interrupt-based RS232 reception on PortB0 (INTCON,INTF)
; at 9600 baud @ 4 MHz PIC clock.
;
; This program handles all aspects of RS232
; Transmission (register TXD) and
; Reception (register RXD) through interrupts (PortB0 IRQ).
;
; Although it's not recommended to use BRGH = 1 with the 16C74A,
; I've tested the device on 9600 baud and it runs without any
; issues. Referring to the specification, the error using this
; selection in conjunction with a 4 MHz crystal is 0.16%. This is
; sufficient for error-free communication within this application.
;
; Program shows the implementation and function of the modules m_bank.asm,
; m_wait.asm, m_lcd.asm, m_lcdv08.asm, and m_rs096.asm on the PIC16F77
; or PIC16C74A.
;
;
; IMPLEMENTED FEATURES:
; =====================
; - Dual RS232: Two independent RS232 interfaces.
; - Bi-directional communication between microcontroller application
; and two remote RS232 clients by both, hardware- and software-based
; RS232 transmission.
; - Display of received character on dot matrix LCD.

http://www.trash.net/~luethi/microchip/projects/rs232/dual_rs232/16F77dual.asm (2 of 15)13/02/2008 19:36:34


http://www.trash.net/~luethi/microchip/projects/rs232/dual_rs232/16F77dual.asm

;
;***************************************************************************

;***** COMPILATION MESSAGES & WARNINGS *****

ERRORLEVEL -207 ; found label after column 1


ERRORLEVEL -302 ; register in operand not in bank 0

;***** PROCESSOR DECLARATION & CONFIGURATION *****

PROCESSOR 16F77
#include "p16f77.inc"

;PROCESSOR 16C74A
;#include "p16c74a.inc"

; embed configuration data within .asm file


__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC & _BODEN_ON

;***** MEMORY STRUCTURE *****

ORG 0x00 ; processor reset vector


goto MAIN ; main program

ORG 0x04 ; interrupt vector


goto ISR ; Interrupt Service Routine (ISR)

;***** PORT DECLARATION *****

#define TXport PORTA,0x00 ; RS232 output port, could be


#define TXtris TRISA,0x00 ; any active push/pull port

LCDtris equ TRISB ; LCD on portB


LCDport equ PORTB

;***** CONSTANT DECLARATION *****

CONSTANT BASE = 0x20 ; base address of user file registers


CONSTANT LCDWAIT = 0x01 ; clk in [0..5] MHz
CONSTANT LCDSPEED = 0x00 ; clk in [0..9] MHz

;***** REGISTER DECLARATION *****

http://www.trash.net/~luethi/microchip/projects/rs232/dual_rs232/16F77dual.asm (3 of 15)13/02/2008 19:36:34


http://www.trash.net/~luethi/microchip/projects/rs232/dual_rs232/16F77dual.asm

TEMP1 set BASE+d'0' ; Universal temporary register


TEMP2 set BASE+d'1' ; ATTENTION !!!
TEMP3 set BASE+d'2' ; They are used by various modules.
TEMP4 set BASE+d'3' ; If you use them, make sure not to use
TEMP5 set BASE+d'4' ; them concurrently !

FLAGreg equ BASE+d'5'


#define RSflagSW FLAGreg,0x00 ; SW-based RS232 data reception flag
#define RSflagHW FLAGreg,0x01 ; HW-based RS232 data reception flag
#define RX2flag FLAGreg,0x02 ; two RS232 bytes received (HW RS232)
#define LCDbusy FLAGreg,0x03 ; LCD busy flag declared within flag register
#define BCflag FLAGreg,0x04 ; blank checker for preceding zeros
#define LCDcflag FLAGreg,0x05 ; LCD command/data flag

LO equ BASE+d'6' ; binary to decimal output (8 bit)


LO_TEMP equ BASE+d'7'

TXD equ BASE+d'8' ; TX-Data register (SW-based RS232)


RXD equ BASE+d'9' ; RX-Data register (SW-based RS232)

RXreg equ BASE+d'10' ; first RS232 RX-Data register


RXreg2 equ BASE+d'11' ; second RS232 RX-Data register
RXtemp equ BASE+d'12' ; intermediate data register for LCD output

W_TEMP equ BASE+d'13' ; context register (ISR)


STATUS_TEMP equ BASE+d'14' ; context register (ISR)
PCLATH_TEMP equ BASE+d'15' ; context register (ISR)
FSR_TEMP equ BASE+d'16' ; context register (ISR)

LOcnt equ BASE+d'17' ; low byte of 24 bit counter


MEDcnt equ BASE+d'18' ; medium byte of 24 bit counter
HIcnt equ BASE+d'19' ; high byte of 24 bit counter

;***** INCLUDE FILES *****

#include "..\..\m_bank.asm"
#include "..\..\m_wait.asm"
#include "..\..\m_rs096.asm" ; standard SW-based RS232
#include "..\..\m_lcd.asm" ; standard version (fixed delay)
;#include "..\..\m_lcd_bf.asm" ; fast, bi-directional version (busy flag)
#include "..\..\m_lcdv08.asm" ; 8 bit to decimal conversion for LCD

;***** MACROS *****

http://www.trash.net/~luethi/microchip/projects/rs232/dual_rs232/16F77dual.asm (4 of 15)13/02/2008 19:36:34


http://www.trash.net/~luethi/microchip/projects/rs232/dual_rs232/16F77dual.asm

RS232init2 macro ; for HW-based RS232 reception


BANK1 ; asynchronous USART assignment:
bsf TXSTA,BRGH ; BRGH = 1
movlw d'25' ; 9600 baud @ 4.00 MHz, BRGH = 1
movwf SPBRG
BANK0
bsf RCSTA,SPEN ; enable serial port
BANK1
bsf PIE1,RCIE ; enable serial reception interrupt
bsf TXSTA,TXEN ; enable serial transmission
BANK0
bsf INTCON,PEIE ; enable peripheral interrupts
bsf RCSTA,CREN ; enable continuous reception
endm

SEND2 macro send_char


movlw send_char
call _RSxmit
endm

SEND2w macro
call _RSxmit
endm

;***** SUB-ROUTINES *****

COUNTERinit ; *** Initialize 24 bit counter for status message wait interval ***
clrf LOcnt ; init counter
clrf MEDcnt ; init counter
movlw d'6'
movwf HIcnt ; init counter
RETURN

_RSxmit BANK1 ; for HW-based RS232 transmission


_RSbusy btfss TXSTA,TRMT ; check, if previous transmission
goto _RSbusy ; has been terminated
BANK0
movwf TXREG ; send next char
RETURN

RSservice ; *** RS232 echo & LCD display routine for received RS232 characters ***
; display on LCD

http://www.trash.net/~luethi/microchip/projects/rs232/dual_rs232/16F77dual.asm (5 of 15)13/02/2008 19:36:34


http://www.trash.net/~luethi/microchip/projects/rs232/dual_rs232/16F77dual.asm

LCD_DDAdr 0x07
movfw RXD
LCDw ; ascii character output on LCD
LCD_DDAdr 0x0D
movfw RXD
movwf LO
LCDval_08 ; numeric ascii value output
; send echo back to PC
SEND TAB
SEND 't'
SEND 'r'
SEND 'a'
SEND 'n'
SEND 's'
SEND 'm'
SEND 'i'
SEND 't'
SEND 't'
SEND 'e'
SEND 'd'
SEND ' '
movfw RXD ; get received RS232 data
SENDw ; transmit across RS232 line
movfw RXD ; get received RS232 data
SEND2w ; transmit across other RS232 line
SEND ' '
SEND 't'
SEND 'o'
SEND ' '
SEND 'l'
SEND 'i'
SEND 'n'
SEND 'k'
SEND ' '
SEND '2'
SEND CR ; Carriage Return
SEND LF ; Line Feed
; end of RS232 service (echo & display)
bcf RSflagSW ; reset RS232 data reception flag
bsf INTCON,INTE ; re-enable RB0/INT interrupt
RETURN

RSservice2 ; *** RS232 echo & LCD display routine for received RS232 characters ***

http://www.trash.net/~luethi/microchip/projects/rs232/dual_rs232/16F77dual.asm (6 of 15)13/02/2008 19:36:34


http://www.trash.net/~luethi/microchip/projects/rs232/dual_rs232/16F77dual.asm

; first byte in RXreg


movfw RXreg ; retrieve data
movwf RXtemp ; store data
call _RSdisp ; call output subroutine
btfss RX2flag ; check for second data byte received
goto RSdispEND
; second byte in RXreg2, i.e. RX2flag = 1
movfw RXreg2 ; retrieve data
movwf RXtemp ; store data
call _RSdisp ; call output subroutine
bcf RX2flag ; reset flag
btfss RCSTA,OERR ; check for RX overrun (overrun error bit)
goto RSdispEND
; buffer overrun, severe error, reset USART RX logic
bcf RCSTA,CREN ; reset USART RX logic, clear RCSTA,OERR
bcf RCSTA,FERR ; reset framing error bit
bsf RCSTA,CREN ; re-enable continuous reception
RSdispEND
bcf RSflagHW ; reset RS232 data reception flag
BANK1
bsf PIE1,RCIE ; re-enable USART reception interrupt
BANK0 ; (interrupt flag already cleared in ISR)
RETURN

_RSdisp ; output subroutine for serial data received


; display on LCD
LCD_DDAdr 0x47
movfw RXtemp
LCDw ; ascii character output on LCD
LCD_DDAdr 0x4D
movfw RXtemp
movwf LO
LCDval_08 ; numeric ascii value output
; send echo back to PC
SEND2 TAB
SEND2 't'
SEND2 'r'
SEND2 'a'
SEND2 'n'
SEND2 's'
SEND2 'm'
SEND2 'i'
SEND2 't'

http://www.trash.net/~luethi/microchip/projects/rs232/dual_rs232/16F77dual.asm (7 of 15)13/02/2008 19:36:34


http://www.trash.net/~luethi/microchip/projects/rs232/dual_rs232/16F77dual.asm

SEND2 't'
SEND2 'e'
SEND2 'd'
SEND2 ' '
movfw RXtemp ; retrieve value
SEND2w ; transmit across RS232 line
movfw RXtemp ; retrieve value
SENDw ; transmit across other RS232 line
SEND2 ' '
SEND2 't'
SEND2 'o'
SEND2 ' '
SEND2 'l'
SEND2 'i'
SEND2 'n'
SEND2 'k'
SEND2 ' '
SEND2 '1'
SEND2 CR ; Carriage Return
SEND2 LF ; Line Feed
RETURN

;***** INTERRUPT SERVICE ROUTINE *****

ISR ;************************
;*** ISR CONTEXT SAVE ***
;************************

bcf INTCON,GIE ; disable all interrupts


btfsc INTCON,GIE ; assure interrupts are disabled
goto ISR
movwf W_TEMP ; context save: W
swapf STATUS,W ; context save: STATUS
movwf STATUS_TEMP ; context save
clrf STATUS ; bank 0, regardless of current bank
movfw PCLATH ; context save: PCLATH
movwf PCLATH_TEMP ; context save
clrf PCLATH ; page zero, regardless of current page
bcf STATUS,IRP ; return to bank 0
movfw FSR ; context save: FSR
movwf FSR_TEMP ; context save
;*** context save done ***

http://www.trash.net/~luethi/microchip/projects/rs232/dual_rs232/16F77dual.asm (8 of 15)13/02/2008 19:36:34


http://www.trash.net/~luethi/microchip/projects/rs232/dual_rs232/16F77dual.asm

;**************************
;*** ISR MAIN EXECUTION ***
;**************************

;*** determine origin of interrupt ***


btfsc INTCON,INTF ; check for RB0/INT interrupt
goto _ISR_RS232_SW ; if set, there was a keypad stroke

btfsc PIR1,RCIF ; check for USART interrupt


goto _ISR_RS232_HW ; if set, there was an USART interrupt

; catch-all
goto ISRend ; unexpected IRQ, terminate execution of ISR

;***************************************
;*** SW-BASED RS232 DATA ACQUISITION ***
;***************************************
_ISR_RS232_SW
; first, disable interrupt source
bcf INTCON,INTE ; disable RB0/INT interrupt
; second, acquire RS232 data
RECEIVE ; macro of RS232 software reception
bsf RSflagSW ; enable RS232 data reception flag
goto _ISR_RS232end ; terminate RS232 ISR properly

;***********************************
;*** CLEARING OF INTERRUPT FLAGS ***
;***********************************
; NOTE: Below, I only clear the interrupt flags! This does not
; necessarily mean, that the interrupts are already re-enabled.
; Basically, interrupt re-enabling is carried out at the end of
; the corresponding service routine in normal operation mode.
; The flag responsible for the current ISR call has to be cleared
; to prevent recursive ISR calls. Other interrupt flags, activated
; during execution of this ISR, will immediately be served upon
; termination of the current ISR run.
_ISR_RS232error
bsf INTCON,INTE ; after error, re-enable IRQ already here
_ISR_RS232end
bcf INTCON,INTF ; clear RB0/INT interrupt flag
goto ISRend ; terminate execution of ISR

http://www.trash.net/~luethi/microchip/projects/rs232/dual_rs232/16F77dual.asm (9 of 15)13/02/2008 19:36:34


http://www.trash.net/~luethi/microchip/projects/rs232/dual_rs232/16F77dual.asm

;***************************************
;*** HW-BASED RS232 DATA ACQUISITION ***
;***************************************
_ISR_RS232_HW
movfw RCREG ; get RS232 data (first RX FIFO entry)
movwf RXreg ; store first data byte
btfss PIR1,RCIF ; check flag for second RX FIFO entry
goto _ISR_RS232_HW_A ; no second byte received, branch
movfw RCREG ; get RS232 data (second RX FIFO entry)
movwf RXreg2 ; store second data byte
bsf RX2flag ; set flag to indicate second byte received
_ISR_RS232_HW_A
bsf RSflagHW ; enable RS232 data reception flag
BANK1 ; (for display routine)
bcf PIE1,RCIE ; disable USART reception interrupt
BANK0 ; (will be re-enabled in normal subroutine)
;goto _ISR_RS232end_HW ; exit ISR

_ISR_RS232end_HW
;bcf PIR1,RCIF ; cleared by hardware: USART RX interrupt flag
;goto ISRend ; terminate execution of ISR

;*****************************************
;*** ISR TERMINATION (CONTEXT RESTORE) ***
;*****************************************

ISRend movfw FSR_TEMP ; context restore


movwf FSR ; context restore
movfw PCLATH_TEMP ; context restore
movwf PCLATH ; context restore
swapf STATUS_TEMP,W ; context restore
movwf STATUS ; context restore
swapf W_TEMP,F ; context restore
swapf W_TEMP,W ; context restore
RETFIE ; enable global interrupt (INTCON,GIE)

;***** END OF INTERRUPT SERVICE ROUTINE *****

;************** MAIN **************

MAIN
clrf INTCON ; reset interrupts (disable all)

http://www.trash.net/~luethi/microchip/projects/rs232/dual_rs232/16F77dual.asm (10 of 15)13/02/2008 19:36:34


http://www.trash.net/~luethi/microchip/projects/rs232/dual_rs232/16F77dual.asm

LCDinit ; LCD initialization


RS232init ; RS232 initialization (SW-based RS232)
RS232init2 ; RS232 initialization (HW-based RS232)

;*** ENABLE INTERRUPTS ***


movlw b'11111000'
andwf INTCON,F ; clear all interrupt flags
clrf PIR1 ; clear all interrupt flags
clrf PIR2 ; clear all interrupt flags
bsf INTCON,GIE ; enable global interrupt

clrf FLAGreg ; initialize all flags

;*** START-UP MESSAGE to RS232 ***


; this is done by reading a look-up table
; define amount of table items for start-up message
#define tab_size1 d'92'
movlw tab_size1 ; store amount of table items in counter
movwf TEMP5
; transmit message
_ILOOP1 movlw HIGH WelcomeTable ; get correct page for PCLATH
movwf PCLATH ; prepare right page bits for table read
movfw TEMP5 ; get actual count-down value
sublw tab_size1 ; table offset: w = tab_size4 - TEMP6
call WelcomeTable ; call lookup table
movwf TEMP4
SENDw ; RS232 output (on SW-based RS232)
movfw TEMP4
SEND2w ; RS232 output (on HW-based RS232)
decfsz TEMP5,f ; decrement counter
goto _ILOOP1

LCDchar 'D'
LCDchar 'u'
LCDchar 'a'
LCDchar 'l'
LCDchar ' '
LCDchar 'R'
LCDchar 'S'
LCDchar '2'
LCDchar '3'
LCDchar '2'
LCDchar ' '

http://www.trash.net/~luethi/microchip/projects/rs232/dual_rs232/16F77dual.asm (11 of 15)13/02/2008 19:36:34


http://www.trash.net/~luethi/microchip/projects/rs232/dual_rs232/16F77dual.asm

LCDchar 'R'
LCDchar 'e'
LCDchar 'c'
LCDchar 'e'
LCDchar 'p'
LCDline 0x2
LCDchar 't'
LCDchar 'i'
LCDchar 'o'
LCDchar 'n'
LCDchar ' '
LCDchar 'o'
LCDchar 'n'
LCDchar ' '
LCDchar 'P'
LCDchar 'I'
LCDchar 'C'
LCDchar '1'
LCDchar '6'
LCDchar 'F'
LCDchar '7'
LCDchar '7'
WAITX 0x1A, b'00000111' ; wait some time

; finally, reset/clear LCD


LCDcmd LCDCLR
LCDchar 'R'
LCDchar 'X'
LCDchar '1'
LCDchar ' '
LCDchar 'C'
LCDchar 'h'
LCD_DDAdr 0x09 ; goto specific LCD position
LCDchar 'V'
LCDchar 'a'
LCDchar 'l'

LCDline 0x2 ; line 2 on LCD


LCDchar 'R'
LCDchar 'X'
LCDchar '2'
LCDchar ' '
LCDchar 'C'

http://www.trash.net/~luethi/microchip/projects/rs232/dual_rs232/16F77dual.asm (12 of 15)13/02/2008 19:36:34


http://www.trash.net/~luethi/microchip/projects/rs232/dual_rs232/16F77dual.asm

LCDchar 'h'
LCD_DDAdr 0x49 ; goto specific LCD position
LCDchar 'V'
LCDchar 'a'
LCDchar 'l'

; define amount of table items for start-up message


#define tab_size2 d'27'
movlw tab_size2 ; store amount of table items in counter
movwf TEMP5
; transmit message
_ILOOP2 movlw HIGH WelcomeTable ; get correct page for PCLATH
movwf PCLATH ; prepare right page bits for table read
movfw TEMP5 ; get actual count-down value
sublw tab_size2 ; table offset: w = tab_size4 - TEMP6
call ReadyTable ; call lookup table
movwf TEMP4
SENDw ; RS232 output (on SW-based RS232)
movfw TEMP4
SEND2w ; RS232 output (on HW-based RS232)
decfsz TEMP5,f ; decrement counter
goto _ILOOP2

call COUNTERinit ; initialize 24 bit counter

;******************************
_MLOOP ; first software-based RS232 link (no USART, just IRQs)
btfsc RSflagSW ; check RS232 data reception flag
call COUNTERinit ; reset 24 bit counter
btfsc RSflagSW ; check RS232 data reception flag
call RSservice ; if set, call RS232 echo & LCD display routine

; second hardware-based RS232 link (USART & IRQs)


btfsc RSflagHW ; check RS232 data reception flag
call COUNTERinit ; reset 24 bit counter
btfsc RSflagHW ; check RS232 data reception flag
call RSservice2 ; if set, call RS232 echo & LCD display routine

; status message wait counter for idle transmission (approx. 2.75 s)


decfsz LOcnt,f ; decrement low byte of 24 bit counter
goto _MLOOP ; loop
decfsz MEDcnt,f ; decrement medium byte of 24 bit counter
goto _MLOOP ; loop

http://www.trash.net/~luethi/microchip/projects/rs232/dual_rs232/16F77dual.asm (13 of 15)13/02/2008 19:36:34


http://www.trash.net/~luethi/microchip/projects/rs232/dual_rs232/16F77dual.asm

decfsz HIcnt,f ; decrement high byte of 24 bit counter


goto _MLOOP ; loop

; now, all bytes of 24 bit counter are zero,


; i.e. RS232 has been idle for approx. 2.75 s,
; therefore, transmit now status message...

; send status message


SEND '@' ; to SW-based RS232
SEND CR
SEND LF
SEND2 '@' ; to HW-based RS232
SEND2 CR
SEND2 LF
call COUNTERinit ; initialize 24 bit counter
goto _MLOOP ; loop forever
;******************************

;ORG 0x260 ; if necessary, move look-up tables

WelcomeTable
addwf PCL,F ; add offset to table base pointer
retlw CR
retlw LF
DT "Dual RS232 Reception"
retlw CR
retlw LF
DT "===================="
retlw CR
retlw LF
DT "Microchip PIC16F77 connected and stand-by..." ; create table
retlw CR
WTableEND retlw LF
IF (HIGH (WelcomeTable) != HIGH (WTableEND))
ERROR "WelcomeTable hits page boundary!"
ENDIF

;ORG 0x260 ; if necessary, move look-up tables

ReadyTable
addwf PCL,F ; add offset to table base pointer
DT "ready for transmission..." ; create table
retlw CR

http://www.trash.net/~luethi/microchip/projects/rs232/dual_rs232/16F77dual.asm (14 of 15)13/02/2008 19:36:34


http://www.trash.net/~luethi/microchip/projects/rs232/dual_rs232/16F77dual.asm

RTableEND retlw LF
IF (HIGH (ReadyTable) != HIGH (RTableEND))
ERROR "ReadyTable hits page boundary!"
ENDIF

END

http://www.trash.net/~luethi/microchip/projects/rs232/dual_rs232/16F77dual.asm (15 of 15)13/02/2008 19:36:34


http://www.trash.net/~luethi/microchip/projects/rs232/dual_rs232/16F77dual.hex

:020000040000FA
:0200000059297C
:080008001A29A00081018316F2
:100010000313C03081050800A0008101831603137B
:10002000C030810501308104831203130B110B1DB5
:100030001728A00B16280800A80005100830A000FB
:100040002D2028180514281C0510A80C2D20A00B05
:10005000212805142D202D2008001D30A100332853
:100060000830A1003328A10B33280800A90140293A
:10007000A200E1308605220D1E3986040800861391
:10008000422886170613A3002308230E38204F208A
:10009000230838204F20E130860586130800013000
:1000A0000C208616861201300C2008002608A700B6
:1000B00025126430A100672041200A30A10067208A
:1000C00041200130A1002516672041200800A00131
:1000D00021082702031C7128A00A2108A70225165F
:1000E000692830302007251E20300800B101B201F8
:1000F0000630B300080083160313981C7D28831272
:1001000003139900080087303F20290841208D30D3
:100110003F202908A600562009301C2074301C20DE
:1001200072301C2061301C206E301C2073301C206B
:100130006D301C2069301C2074301C2074301C2051
:1001400065301C2064301C2020301C2029081C2015
:1001500029087B2020301C2074301C206F301C208C
:1001600020301C206C301C2069301C206E301C207C
:100170006B301C2020301C2032301C200D301C2005
:100180000A301C2025100B1608002A08AC00DA20C3
:10019000251DD3282B08AC00DA202511981CD32864
:1001A000181218111816A510831603138C16831233
:1001B00003130800C7303F202C084120CD303F20DA
:1001C0002C08A600562009307B2074307B2072302A
:1001D0007B2061307B206E307B2073307B206D3044
:1001E0007B2069307B2074307B2074307B2065302D
:1001F0007B2064307B2020307B202C087B202C0847
:100200001C2020307B2074307B206F307B202030FE
:100210007B206C307B2069307B206E307B206B3004
:100220007B2020307B2031307B200D307B200A303A
:100230007B2008008B138B1B1A29AD00030EAE0028
:1002400083010A08AF008A0183130408B0008B18E9
:100250002C298C1A432950290B12302006183628D5
:100260000830A0002D200618A917061CA913200B82
:10027000A90CA00B32292D20061C36282514412953

http://www.trash.net/~luethi/microchip/projects/rs232/dual_rs232/16F77dual.hex (1 of 3)13/02/2008 19:37:05


http://www.trash.net/~luethi/microchip/projects/rs232/dual_rs232/16F77dual.hex

:100280000B168B1050291A08AA008C1E4A291A082E
:10029000AB002515A514831603138C1283120313C8
:1002A000300884002F088A002E0E8300AD0E2D0E1C
:1002B00009008B0183160313013086058312031393
:1002C000861206138613E130860504300C200330B5
:1002D00038204F2001300C20083038204F200130CA
:1002E0000C20023038204F2001300C2028303F20D5
:1002F0000C303F2001303F2008300C2083160313C0
:100300000510061401138312031305148B100B162A
:100310008B178316031318151930990083120313D2
:100320009817831603138C169816831203130B1752
:100330001816F8308B058C018D018B17A5015C30E8
:10034000A40002308A0024085C3C4822A3001C2040
:1003500023087B20A40BA129443041207530412083
:10036000613041206C30412020304120523041200A
:10037000533041203230412033304120323041204F
:1003800020304120523041206530412063304120EF
:100390006530412070304120C0303F207430412012
:1003A000693041206F3041206E30412020304120A3
:1003B0006F3041206E3041202030412050304120AC
:1003C00049304120433041203130412036304120F6
:1003D0004630412037304120373041201A30052047
:1003E0000730132001303F20523041205830412047
:1003F00031304120203041204330412068304120BD
:1004000089303F2056304120613041206C304120FE
:10041000C0303F20523041205830412032304120FE
:10042000203041204330412068304120C9303F20F6
:1004300056304120613041206C3041201B30A400F7
:1004400002308A0024081B3CA522A3001C2023089C
:100450007B20A40B202A76202518762025188320BF
:10046000A5187620A518C520B10B2C2AB20B2C2A72
:10047000B30B2C2A40301C200D301C200A301C20CD
:1004800040307B200D307B200A307B2076202C2AC8
:1004900082070D340A344434753461346C342034AA
:1004A0005234533432343334323420345234653499
:1004B000633465347034743469346F346E340D349D
:1004C0000A343D343D343D343D343D343D343D34D7
:1004D0003D343D343D343D343D343D343D343D3494
:1004E0003D343D343D343D343D340D340A344D34D7
:1004F0006934633472346F3463346834693470340B
:10050000203450344934433431343634463437346B
:100510003734203463346F346E346E34653463346E
:10052000743465346434203461346E34643420347B

http://www.trash.net/~luethi/microchip/projects/rs232/dual_rs232/16F77dual.hex (2 of 3)13/02/2008 19:37:05


http://www.trash.net/~luethi/microchip/projects/rs232/dual_rs232/16F77dual.hex

:100530007334743461346E3464342D3462347934F9
:100540002E342E342E340D340A348207723465343E
:10055000613464347934203466346F347234203436
:100560007434723461346E3473346D34693473347A
:10057000733469346F346E342E342E342E340D348B
:020580000A343B
:02400E00F23F7F
:00000001FF

http://www.trash.net/~luethi/microchip/projects/rs232/dual_rs232/16F77dual.hex (3 of 3)13/02/2008 19:37:05


1 2 3 4

PIC16F84 MAX232
D (Direction seen from controller) D
VDD
VDD
R1 XT1 VSS
C4
16k C3
4.000 MHz 10u
C1 C2 10u
S1 10p VDD 10p

16
2
6
SW-PB VSS VSS

14
U1
C5 13 12

V+

VCC
V-
IC_PIC1 RS232 TXD R1 IN R1 OUT PIC RXD
RS232 8 9 5V
16 15 RS232 DTR R2 IN R2 OUT 5V DTR

VDD
VSS 4n7 OSC1/CLKIN OSC2/CLKOUT 11 14
4 7 PIC TXD T1 IN T1 OUT RS232 RXD
MCLR RB1 5V 10 7 RS232
17 8 5V DSR T2 IN T2 OUT RS232 DSR
C PIC TXD RA0 RB2 1 4 C

GND
18 9 C1+ C2+
RA1 RB3 3 5
5V DSR 1 10 C1 - C2 -
RA2 RB4
2 11
RA3 RB5 C6 MAX232CPE(16) C7
5V DTR 3 12
RA4/T0CKI RB6 10u 10u
VSS

15
6 13
PIC RXD RB0/INT RB7
PIC16F84-04/P(18)
5

VSS
VDD
VDD VSS
VDD
C8
DSR and DTR signals are not used in
100n
B VSS RS232 my RS232 routines, but are drawn for
completion. These signals are necessary C9
B
VSS
(Direction seen from host) for hardware handshaking, whilst my 100n
routines perform no handshaking. The
RS232 DTR MAX232 has two output and two input VSS
RS232 TXD VSS channels, specified to transmit up to 120
kbps depending on the type used.
RS232 RXD
RS232 DSR
1
6
2
7
3
8
4
9
5

Title
PIC-RS232 Interface using MAX232
A A
Written by Date
SUB1 20-Aug-2003
Peter Luethi
DB9 Revision Page
Dietikon, Switzerland 1.01 1 of 1

1 2 3 4
ASCII Character Map
32 00100000 20 90 Z 01011010 5A
33 ! 00100001 21 91 [ 01011011 5B
34 " 00100010 22 92 \ 01011100 5C
35 # 00100011 23 93 ] 01011101 5D
36 $ 00100100 24 94 ^ 01011110 5E
37 % 00100101 25 95 _ 01011111 5F
38 & 00100110 26 96 ` 01100000 60
39 ' 00100111 27 97 a 01100001 61
40 ( 00101000 28 98 b 01100010 62
41 ) 00101001 29 99 c 01100011 63
42 * 00101010 2A 100 d 01100100 64
43 + 00101011 2B 101 e 01100101 65
44 , 00101100 2C 102 f 01100110 66
45 - 00101101 2D 103 g 01100111 67
46 . 00101110 2E 104 h 01101000 68
47 / 00101111 2F 105 i 01101001 69
48 0 00110000 30 106 j 01101010 6A
49 1 00110001 31 107 k 01101011 6B
50 2 00110010 32 108 l 01101100 6C
51 3 00110011 33 109 m 01101101 6D
52 4 00110100 34 110 n 01101110 6E
53 5 00110101 35 111 o 01101111 6F
54 6 00110110 36 112 p 01110000 70
55 7 00110111 37 113 q 01110001 71
56 8 00111000 38 114 r 01110010 72
57 9 00111001 39 115 s 01110011 73
58 : 00111010 3A 116 t 01110100 74
59 ; 00111011 3B 117 u 01110101 75
60 < 00111100 3C 118 v 01110110 76
61 = 00111101 3D 119 w 01110111 77
62 > 00111110 3E 120 x 01111000 78
63 ? 00111111 3F 121 y 01111001 79
64 @ 01000000 40 122 z 01111010 7A
65 A 01000001 41 123 { 01111011 7B
66 B 01000010 42 124 | 01111100 7C
67 C 01000011 43 125 } 01111101 7D
68 D 01000100 44 126 ~ 01111110 7E
69 E 01000101 45 127 01111111 7F
70 F 01000110 46 128 10000000 80
71 G 01000111 47 129 10000001 81
72 H 01001000 48 130 10000010 82
73 I 01001001 49 131 10000011 83
74 J 01001010 4A 132 10000100 84
75 K 01001011 4B 133 10000101 85
76 L 01001100 4C 134 10000110 86
77 M 01001101 4D 135 10000111 87
78 N 01001110 4E 136 10001000 88
79 O 01001111 4F 137 10001001 89
80 P 01010000 50 138 10001010 8A
81 Q 01010001 51 139 10001011 8B
82 R 01010010 52 140 10001100 8C
83 S 01010011 53 141 10001101 8D
84 T 01010100 54 142 10001110 8E
85 U 01010101 55 143 10001111 8F
86 V 01010110 56 144 10010000 90
87 W 01010111 57 145 10010001 91
88 X 01011000 58 146 10010010 92
89 Y 01011001 59 147 10010011 93
148 10010100 94 202 11001010 CA
149 10010101 95 203 11001011 CB
150 10010110 96 204 11001100 CC
151 10010111 97 205 11001101 CD
152 10011000 98 206 11001110 CE
153 10011001 99 207 11001111 CF
154 10011010 9A 208 11010000 D0
155 10011011 9B 209 11010001 D1
156 10011100 9C 210 11010010 D2
157 10011101 9D 211 11010011 D3
158 10011110 9E 212 11010100 D4
159 10011111 9F 213 11010101 D5
160 10100000 A0 214 11010110 D6
161 10100001 A1 215 11010111 D7
162 10100010 A2 216 11011000 D8
163 10100011 A3 217 11011001 D9
164 10100100 A4 218 11011010 DA
165 10100101 A5 219 11011011 DB
166 10100110 A6 220 11011100 DC
167 10100111 A7 221 11011101 DD
168 10101000 A8 222 11011110 DE
169 10101001 A9 223 11011111 DF
170 10101010 AA 224 11100000 E0
171 10101011 AB 225 11100001 E1
172 10101100 AC 226 11100010 E2
173 - 10101101 AD 227 11100011 E3
174 10101110 AE 228 11100100 E4
175 10101111 AF 229 11100101 E5
176 10110000 B0 230 11100110 E6
177 10110001 B1 231 11100111 E7
178 10110010 B2 232 11101000 E8
179 10110011 B3 233 11101001 E9
180 10110100 B4 234 11101010 EA
181 10110101 B5 235 11101011 EB
182 10110110 B6 236 11101100 EC
183 10110111 B7 237 11101101 ED
184 10111000 B8 238 11101110 EE
185 10111001 B9 239 11101111 EF
186 10111010 BA 240 11110000 F0
187 10111011 BB 241 11110001 F1
188 10111100 BC 242 11110010 F2
189 10111101 BD 243 11110011 F3
190 10111110 BE 244 11110100 F4
191 10111111 BF 245 11110101 F5
192 11000000 C0 246 11110110 F6
193 11000001 C1 247 11110111 F7
194 11000010 C2 248 11111000 F8
195 11000011 C3 249 11111001 F9
196 11000100 C4 250 11111010 FA
197 11000101 C5 251 11111011 FB
198 11000110 C6 252 11111100 FC
199 11000111 C7 253 11111101 FD
200 11001000 C8 254 11111110 FE
201 11001001 C9 255 11111111 FF

Potrebbero piacerti anche