;**********************************************************************
;                                                                     *
;    Filename: e02b.asm                                               *    
;    Description: RS-232 communication (EUSART) with auto-baud        *
;    detection.                                                       *
;    Date: 19/09/2007                                                 *
;    File Version: 1.0                                                *
;    Web: www.eeng.biz                                                *
;                                                                     *
;    Assembler: MPASMWIN v5.11                                        *
;                                                                     *
;**********************************************************************
;                                                                     *
;    Notes:                                                           * 
;    1. This experiment requires the PIC16F887 experimental board     *
;    Visit http://www.eeng.biz/887.htm                                *
;    2. Automatic baud rate detection. When LED1 turns on, the user   *
;    must press 'U'(0x55) on the keyboard.The incoming character      * 
;    calibrates the Baud Rate Generator.	
;    After the calibration LED1 turns off, then received bytes are    *
;    sent back to the computer. Tested up to 19200 baud @ 4 MHz.      * 
;    3. Start bit = 1, Data bits = 8, Stop bits = 1,                  * 
;    Hardware control = none                                          *
;                                                                     *
;**********************************************************************


	list p=16f887			; list directive to define processor
	#include <p16f887.inc>		; processor specific variable definitions
	
	errorlevel -302    		; suppress message 302 from list file 


	; '__CONFIG' directive is used to embed configuration data within .asm file.

	__CONFIG    _CONFIG1, _LVP_OFF & _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & _MCLRE_ON & _PWRTE_ON & _WDT_OFF & _INTOSCIO & _DEBUG_OFF 
	__CONFIG    _CONFIG2, _WRT_OFF 


;***** DEFINITIONS
	
	#define	LED1 PORTB,5		; LED1
	#define LED2 PORTB,4		; LED2

	#define SWITCH PORTB,2		; switch

	; LCD
	#define LCD PORTC		; data PORT (4-bit interface)
	#define RS PORTA,7		; Register Select
	#define EN PORTA,6		; Enable


;***** VARIABLE DEFINITIONS

	cblock	0x020

		v1
		v2

	endc


;**********************************************************************


	ORG     0x000			; processor reset vector
  	nop
	goto    init			; go to beginning of program



	ORG     0x100              
init
	bcf	STATUS, RP0 		 
	bcf	STATUS, RP1 		 

	banksel	OSCCON
	; internal oscillator frequency = 4 MHz (default)
osctest 
  	btfss 	OSCCON, HTS 		; oscillator stable?
  	goto  	osctest	
	

	banksel PORTA			
	clrf	PORTA
	clrf	PORTB
	clrf 	PORTC
	clrf	PORTD
	clrf	PORTE
	
	banksel ANSEL;
	clrf	ANSELH  		; configure RB0/5 for digital I/O 
	movlw	b'00001101'		
	movwf	ANSEL			; configure RA0, RA2, RA3 as analog inputs

	banksel	TRISA
	movlw	b'00111111'
	movwf	TRISA			; set RA6, RA7 as outputs
	movlw	b'11001111'
	movwf	TRISB			; set RB4, RB5 as outputs
	movlw	b'11110000'
	movwf	TRISC			; set RC0/3 as outputs


	; EUSART module initialization

	; SPBRGH and SPBRG will be loaded automatically after calibration 

	; SYNC = 0, BRGH = 1, BRG16 = 1 
	; 16-bit baud rate generator, asyncronous
	banksel	TXSTA
	bcf	TXSTA, SYNC		
	banksel	BRGH
	bsf	TXSTA, BRGH
	banksel	BAUDCTL
	bsf	BAUDCTL, BRG16 

	banksel	RCSTA
	bsf	RCSTA, SPEN		; enable serial port (SPEN = 1)
	banksel	TXSTA
	bsf	TXSTA, TXEN		; enable transmission (TXEN = 1)
	banksel	RCSTA
	bsf	RCSTA, CREN		; enable reception (CREN = 1)

	call 	delay			; short delay
	
	bsf	LED1			; turn LED1 on	
	call	abd			; auto-baud detection
	bcf	LED1			; turn LED1 off
	
;**********************************************************************
main	
	call	recv			; receive data
	call	send			; send data back
	goto 	main

;**********************************************************************
recv   	
	btfss	PIR1, RCIF 	      	; check bit RXIF
	goto 	recv			
        movf	RCREG, W		; store value in W
        return

;**********************************************************************
send	
	btfss   PIR1, TXIF		; check bit TXIF
     	goto 	send			
     	movwf	TXREG			; load the value to be sent
        return

;**********************************************************************
delay
	; about 20 ms
	movlw	0x9E
	movwf	v1
	movlw	0x10
	movwf	v2
delay_0
	decfsz	v1, f
	goto	$+2
	decfsz	v2, f
	goto	delay_0

	return

;**********************************************************************
abd
	; auto-baud detection (tested up to 19200 baud @ 4 MHz)

	banksel	BAUDCTL
	bsf	BAUDCTL, ABDEN		; start the auto-baud calibration
	banksel PIR1
abd_0		 
	btfss	PIR1, RCIF		; check if calibration is finished
	goto 	abd_0			

	call 	delay			; short delay

	; subtract 1 from SPBRGH:SPBRG for maximum accuracy
  	banksel SPBRG
	movf    SPBRG, f              	; set Z if SPBRG = 0
  	btfsc   STATUS, Z 
   	decf   	SPBRGH, f		
  	decf    SPBRG, f		 
	
	banksel	RCREG
        movf	RCREG, W		; clear RCIF
	clrw				; discard data

	call 	delay			; short delay

	return



	END                       	; directive 'end of program'


