please dont rip this site

PIC Specific RS232 routine

12F683 9600 baud

Mike McLaren - K8LH (Westland, MI) says:

I just finished cleaning up an assembly lanugauge source file for a little 12F683 demo' program that shows one way (of probably many) to do reliable 9600 baud bit-banged serial I/O on this chip... It uses TMR2 generated 104-usec interrupts, as well as interrupt-on-change to detect the start bit, using the built-in 12F683 8-MHz INTOSC... Please feel free to use it if you think it may be useful...

	list p=12F683, b=8, c= 102, n=71, t=on, st=off, f=inhx32
;******************************************************************
;*								  *
;*  Filename: 12F683 Serial.asm					  *
;*    Author: Mike McLaren, K8LH   (k8lh@arrl.net)		  *
;*      Date: 27-Nov-04  (rev 22-Dec-04)			  *
;*								  *
;*   Test 'bit-banged' 9600 baud serial I/O Routines		  *
;*   Uses 12F683 INTOSC at 8-MHz				  *
;*								  *
;*								  *
;*								  *
;*     MPLab: 7.00    (tabs=8)					  *
;*     MPAsm: 3.90						  *
;*								  *
;******************************************************************

	#include	<p12f683.inc>
	errorlevel	-302

	__config	_FCMEN_OFF & _IESO_OFF & _BOD_OFF & _CPD_OFF & _CP_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTOSC
;
; file register variables
;
PROC232	equ	0x20		;RS-232 Process Latch
TXCNT	equ	0x21		;TX-232 bit count
TXVAR	equ	0x22		;TX-232 data byte
RXCNT	equ	0x23		;RX-232 bit count
RXVAR	equ	0x24		;RX-232 data byte

;
; PROC232 flag bits
;
RXFLAG	equ	0x00		;1=rx in progress
RXCHAR	equ	0x01		;1=rx char available
TXFLAG	equ	0x02		;1=tx in progress

; other constants

RXPIN	equ	0x03		;RS-232 RX (GP3)
TXPIN	equ	0x04		;RS-232 TX (GP4)
BAUDX	equ	.208		;208 for 9600 baud
;
; file locations used by ISR for saving and restoring the stack
;
W_ISR	equ	0x70		;ISR 'W'
S_ISR	equ	0x71		;ISR 'STATUS'
P_ISR	equ	0x72		;ISR 'PCLATH'
;
; other vars
;
PTRL	equ	0x78		;PRTSTR routine
PTRH	equ	0x79		;PRTSTR routine

; Hardware notes:
;
; <1> Using INTOSC 8-MHz, 500-nsec instruction cycle
; <2> Using GP3 for 9600 baud 'bit banged' serial input
; <3> Using GP4 for 9600 baud 'bit banged' serial output
; <4> RS-232 signals inverted with MAX232 or 2N7000 drivers
; <5> Using 2700 ohm pull-up resistor on GP3

;
;  This program simply prints a text string to Hyperterminal 
;  and echos typed characters back to Hyperterminal...
;
;  Setup Hyperterminal for 9600, 8, 1, none...  Use a MAX232 or
;  similar level shifting circuit (I use a pair of 2N7000s) for
;  connection between the 12F683 and PC...  
;

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

	org	0x0000

START	clrf	STATUS		;				  |B0
	movlw	b'00010000'	;tx pin in 'stop' condition	  |B0
	movwf	GPIO		;setup GPIO latch		  |B0
	goto	MAIN		;				  |B0

;******************************************************************
;*                                                             	  *
;*    Interrupt Service Routine	for 'bit-banged' Serial I/O	  *
;*                                                                *
;*    Interrupts are generated every 104-us by TMR2 for 9600	  *
;*    baud shift operations and by IOC (interrupt on change)	  *
;*    on the RX start bit leading edge on RX pin GP3...		  *
;*								  *
;*    On detecting the RX start bit leading edge, GP3 IOC is	  *
;*    turned off, RXFLAG is set to indicate rx-in-progress,	  *
;*    RXCNT bit count variable is set, and TMR2 is advanced	  *
;*    by 1/2 bit (52-usec)...  Note - advancing TMR2 could	  *
;*    potentially mess up a tx-in-progress, so, don't send &	  *
;*    receive at the same time...				  *
;*                                                                *
;******************************************************************

	org	0x0004
;
; save W and STATUS registers on entry
;
ISR	movwf	W_ISR		;save W-reg			  |B?
	swapf	STATUS,W	;doesn't change STATUS bits	  |B?
	movwf	S_ISR		;save STATUS reg		  |B?
	clrf	STATUS		;bank 0				  |B0
	movf	PCLATH,W	;get PCLATH			  |B0
	movwf	P_ISR		;save PCLATH			  |B0
;
; 27-Nov-04, test for GP3 (RXPIN) start bit leading edge
;
	btfss	INTCON,GPIF	;IOC "start bit" interrupt?	  |B0
	goto	ISR_TX		;no, branch			  |B0
	movf	GPIO,W		;yes, read GPIO			  |B0
	bcf	INTCON,GPIF	;clear IOC interrupt flag	  |B0
	bsf	PROC232,RXFLAG	;indicate RX in progress	  |B0
	movlw	d'10'		;10 bits (start + 8 data + stop)  |B0
	movwf	RXCNT		;initialize RX bit counter	  |B0
	movlw	BAUDX/2		;				  |B0
	movwf	TMR2		;inc TMR2 by 1/2 bit (52-usec)	  |B0
	goto	ISR_X		;turn off GP3 IOC & exit	  |B0

;
; 23-Nov-04, code to test bit-banged serial output...
; RS-232 code processed each 104-usec interrupt for 9,600 baud...
;
ISR_TX	btfss	PROC232,TXFLAG	;TX in progress?		  |B0
	goto	ISR_RX		;no, branch			  |B0
	movf	TXCNT,W		;get TX bit count		  |B0
	xorlw	b'00001011'	;start bit?			  |B0
	btfsc	STATUS,Z	;no, branch			  |B0
	goto	ISR_TX1		;yes, send start bit		  |B0
	rrf	TXVAR,f		;shift lsb into C		  |B0
	bsf	TXVAR,7		;set bit 7 for stop bits	  |B0
	btfsc	STATUS,C	;skip if C=0			  |B0
	bsf	GPIO,TXPIN	;set TX pin			  |B0
	btfss	STATUS,C	;skip if C=1			  |B0
ISR_TX1	bcf	GPIO,TXPIN	;clear TX pin			  |B0
	decf	TXCNT,f		;decrement bit counter		  |B0
	btfsc	STATUS,Z	;last bit?			  |B0
	bcf	PROC232,TXFLAG	;yes, indicate end of TX	  |B0
;
; 25-Nov-04, code to test bit-banged serial input...
;
ISR_RX	btfss	PROC232,RXFLAG	;RX in progress?		  |B0
	goto	ISR_XIT		;no, branch			  |B0
	bcf	STATUS,C	;assume bit=0			  |B0
	btfsc	GPIO,RXPIN	;is it a 0?			  |B0
	bsf	STATUS,C	;no, bit=1			  |B0
	rrf	RXVAR,f		;shift bit into RXVAR		  |B0
	decfsz	RXCNT,f		;all 10 bits?			  |B0
	goto	ISR_XIT		;no, branch			  |B0
	rlf	RXVAR,f		;yes, get rid of the stop bit	  |B0
	bcf	PROC232,RXFLAG	;clear RX-in-progress flag	  |B0
	bsf	PROC232,RXCHAR	;indicate character available	  |B0
ISR_X	bsf	STATUS,RP0	;select bank 1			  |B1
	movlw	b'00001000'	;mask for bit 3			  |B1
	xorwf	IOC,f		;toggle GP3 IOC			  |B1
	bcf	STATUS,RP0	;select bank 0			  |B0
;
ISR_XIT	bcf	PIR1,TMR2IF	;clear TMR2 irq flag		  |B0
	movf	P_ISR,W		;				  |B0
	movwf	PCLATH		;restore PCLATH			  |B0
	swapf	S_ISR,W		;				  |B0
	movwf	STATUS		;restore STATUS			  |B?
	swapf	W_ISR,f		;don't screw up STATUS		  |B?
	swapf	W_ISR,W		;restore W-reg			  |B?
	retfie			;return from interrupt		  |B?
;
;******************************************************************

















;******************************************************************
;
; Initialization
;
MAIN	movlw	b'00000111'	;				  |B0
	movwf	CMCON0		;digital I/O			  |B0
	bsf	STATUS,RP0	;bank 1				  |B1
	clrf	ANSEL		;digital I/O			  |B1
	movlw	b'01110001'	;				  |B1
	movwf	OSCCON		;8-mhz INTOSC system clock	  |B1
	movlw	b'00001000'	;GP3 input, all others output	  |B1
	movwf	TRISIO		;				  |B1
;
; 27-Nov-04, code for interrupt-on-change on GP3 (RXPIN) to detect
; RS-232 RX start bit
;
	movlw	b'00001000'	;				  |B1
	movwf	IOC		;set IOC for GP3 input		  |B1
;
; wait for INTOSC to become stable before doing anything else
;
STABLE	btfss	OSCCON,HTS	;oscillator stable?		  |B1
	goto	STABLE		;no, branch			  |B1
	bcf	STATUS,RP0	;bank 0				  |B0
;
;  clear RS-232 flags before turning on interrupts
;
	clrf	PROC232		;clear process latch variable	  |B0
;
; configure TIMER2 for 104-usec interrupts (8-MHz clock)...
;
	clrf	TMR2		;clear TMR2 register		  |B0
	bsf	STATUS,RP0	;select Bank 1			  |B1
	bsf	INTCON,PEIE	;enable peripheral irqs		  |B1
	clrf	PIE1		;mask all peripheral irqs	  |B1
	bsf	PIE1,TMR2IE	;except for TMR2 irqs		  |B1
	bcf	STATUS,RP0	;select Bank 0			  |B0
	clrf	PIR1		;clear peripheral irq flags	  |B0
	movlw	b'00000000'	;pre 1, post 1:1		  |B0
	movwf	T2CON		;for 500-nsec ticks (8-mhz clock) |B0
	bsf	STATUS,RP0	;select Bank 1			  |B1
	movlw	BAUDX-1		;number of 500-nsec ticks	  |B1
	movwf	PR2		;104-usec interrupts		  |B1
	bcf	STATUS,RP0	;select Bank 0			  |B0
	bsf	INTCON,GIE	;enable global irqs		  |B0
	bsf	INTCON,GPIE	;enable interrupt-on-change irqs  |B0
	bsf	T2CON,TMR2ON	;start TMR2			  |B0

;******************************************************************
;
; Print a string
;
	movlw	low GREET	;Greeting string address lo	  |B0
	movwf	PTRL		;				  |B0
	movlw	high GREET	;Greeting string address hi	  |B0
	movwf	PTRH		;				  |B0
	call	PRTSTR		;print greeting string		  |B0
;
; Echo characters coming from Hyperterminal...
;
TEST	call	RX232		;receive character		  |B0
	call	TX232		;echo character			  |B0
	goto	TEST		;				  |B0

;******************************************************************
;******************************************************************
;
; TX232 - enter with character to be sent in W
;
TX232	btfsc	PROC232,TXFLAG	;TX in progress?		  |B0
	goto	TX232		;yes, branch and wait		  |B0
	movwf	TXVAR		;stuff character		  |B0
	movlw	b'00001011'	;				  |B0
	movwf	TXCNT		;set TX bit count		  |B0
	bsf	PROC232,TXFLAG	;initiate TX			  |B0
	return			;				  |B0

;******************************************************************
;
; RX232 - exit with received character in W
;
RX232	btfss	PROC232,RXCHAR	;character available flag?	  |B0
	goto	RX232		;no, loop			  |B0
	movf	RXVAR,W		;yes, get character		  |B0
	bcf	PROC232,RXCHAR	;clear flag			  |B0
	return			;				  |B0

;******************************************************************
;
PRTSTR	call	GETSTR		;Get a string character		  |B0
	andlw	b'11111111'	;				  |B0
	btfsc	STATUS,Z	;Last character?		  |B0
	return			;Yes, return			  |B0
	call	TX232		;Output char			  |B0
	incfsz	PTRL,F		;Increment pointer		  |B0
	goto	PRTSTR		;				  |B0
	incf	PTRH,F		;				  |B0
	goto	PRTSTR		;				  |B0

GETSTR	movf	PTRH,W		;				  |B0
	movwf	PCLATH		;				  |B0
	movf	PTRL,W		;				  |B0
	movwf	PCL		;				  |B0

GREET	dt	0x1b, 0x5b, a'H'		;home cursor
	dt	0x1b, 0x5b, a'J'		;clear screen
	dt	"K8LH 12F683 Serial Test Code v1.0"
	dt	0x0d, 0x0a, 0x0a, 0x00

	end


Questions:

See also:


file: /Techref/microchip/12F683-rs232-9600-mm.htm, 15KB, , updated: 2009/1/30 16:11, local time: 2020/3/30 00:58,
TOP NEW HELP FIND: 
34.239.172.52:LOG IN

 ©2020 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions?
Please DO link to this page! Digg it! / MAKE!

<A HREF="http://www.massmind.org/Techref/microchip/12F683-rs232-9600-mm.htm"> PIC 12F683 9600 RS232</A>

After you find an appropriate page, you are invited to your to this massmind site! (posts will be visible only to you before review) Just type in the box and press the Post button. (HTML welcomed, but not the <A tag: Instead, use the link box to link to another page. A tutorial is available Members can login to post directly, become page editors, and be credited for their posts.


Link? Put it here: 
if you want a response, please enter your email address: 
Attn spammers: All posts are reviewed before being made visible to anyone other than the poster.
Did you find what you needed?

 
Quick, and RELIABLE! RCL-1 RS232 Level Converter in a DB9 backshell only $25.00
Ashley Roll has put together a really nice little unit here. Leave off the MAX232 and keep these handy for the few times you need true RS232!
 

Welcome to www.massmind.org!

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  .