Rutinas para comunicación Serie

Esta rutina utiliza las macros que se entregan en esta pagina de micro.

Esta disponible la version zip de este codigo aqui.

serie.asm

;------------------------------------------------------------------------------
; serie.asm
;
; Proyecto: www.micro1.com.ar
; Version:
; Inicialización:
; Actualización:
; Programador: Javier Rambaldo
; Observaciones: Rutinas de transmision y recepcion serie (RS232)
; sin usar un dispositivo USART.
; UTILIZA LAS MACROS macrospic.asm dela pagina www.micro1.com.ar
;------------------------------------------------------------------------------

LIST P=PIC16F84A, F=INHX8M, R=DEC
__CONFIG _XT_OSC

#include "macros.asm"


;------------------------------------------------------------------------------
; CONSTANTES
;------------------------------------------------------------------------------
; fclock = 10000000 (10Mhz)
; baudios = 19200
; ciclos = (fclock/4)/baudios [ciclos es el BitTime en ciclos de reloj]
;------------------------------------------------------------------------------
BAUD_TW equ 38 ; 16+3X = ciclos
BAUD_TS equ 41 ; 7+3X = ciclos
BAUD_RW equ 38 ; 16+3X = ciclos
BAUD_RS equ 61 ; 10+3X = (ciclos + ciclos/2)

;------------------------------------------------------------------------------
; VARIABLES
;------------------------------------------------------------------------------
rxData equ 0x10 ; datos recibido
txData equ 0x11 ; dato a transmitir
count equ 0x12 ;
delay equ 0x13 ;

;------------------------------------------------------------------------------
; BITS
;------------------------------------------------------------------------------
#define tx_bit RA0_bit
#define rx_bit RB0_bit

;------------------------------------------------------------------------------
; VECTOR DE RESET
;------------------------------------------------------------------------------
        ORG 0
        goto main_reset

;-----------------------------------------------
; TRANSMIT
; El codigo a transmitir debe estar en 'TxData'
;-----------------------------------------------
transmit
        copylf 9,count
        bcf tx_bit ; send start bit (bit-time=14+3X)
        nop ; ajusto para bit-time=16+3X
        nop ; "
sigbit  call DelayTW ; 7+3X
        decfsz count,f ; 1
        goto SendNextBit ; 2
        nop ; ajusto para bit-time=16+3X
        nop ; "
        nop ; "
        nop ; "
        nop ; "
        bsf tx_bit ; send stop bit (bit-time=16+3X)
        call DelayTS ; 7+3X
        retlw 0 ;
SendNextBit
        rrf txData,f ; 1
        btfss carry_bit ; 1+1
        goto SetLO ; 2
        nop ; 1
        bsf tx_bit ; 1 (bit-time=16+3X)
        goto sigbit ; 2
SetLO   bcf tx_bit ; 1
        goto sigbit ; 2

;
; DelayS y DelayW tandan 7+3X ciclos. La diferencia esta
; en la constante de carga.
;
DelayTS movlw BAUD_TS ; 1
        goto txsave ; 2
DelayTW movlw BAUD_TW ; 1
        goto txsave ; 2
txsave  movwf Delay ; 1
txL1    decfsz Delay,f ; 1+1
        goto txL1 ; 2
        retlw 0 ; 2


;-----------------------------------------------
; RECEIVE
; El codigo a recibido estará en 'RxData'
;-----------------------------------------------
receive
        clrf rxData ; 1
        copylf 8,Count ; 2
        call DelayRS ; 7+3X
        ; ====
        ; BitTime+BitTime/2 = 10+3X
rx_next
        nop ; 1 (ajusto para bittime=16+3x)
        nop ; 1 "
        bcf carry_bit ; 1
        rrf rxData,f ; 1 -> bittime=16+3x
        btfsc rx_bit ; 1
        bsf rxData,7 ; 1
        call DelayRW ; 7+3X
        djnz Count,rx_next ; 3
        return ;

DelayRS movlw BAUD_RS ; 1
        goto rxsave ; 2
DelayRW movlw BAUD_RW ; 1
        goto rxsave ; 2
rxsave  movwf Delay ; 1
rxL1    decfsz Delay,f ; 1+1
        goto rxL1 ; 2
        retlw 0 ; 2

;------------------------------------------------------------------------------
; MAIN
;------------------------------------------------------------------------------
main_reset:

;-----------------------------
; inicializacion de registros:
;-----------------------------
        bsf tx_bit ; preparo el STOP-BIT.
        BANK1
        CONF_PORTA b'11111110' ; solo RA0 es salida (tx_bit)
        CONF_PORTB b'00000001' ; solo RB0 es entrada (rx_bit)
        CONF_OPTION b'10000000' ; solo uso RB0/INT
        CONF_INTCON b'00010000' ; "
        BANK0
;-----------------------------

; este programa testea las rutinas de transmision y de recepcion
; todo caracter que ingresa por la entrada serie se retransmite
; por la salida serie.

; llego un start bit ?
startb  btfsc rx_bit ; espero que llegue un bit de start...
        goto startb
        call receive
        copyff rxData,txData
        call transmit
        goto startb

        end
;---------------------------------------------------------------
;---------------------------- FIN ------------------------------
;---------------------------------------------------------------