list p=16f876  ;micro
    #include <p16f876.inc>;include
    errorlevel -302  ;suprime error no banco 0
 
    __CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _XT_OSC & _WRT_ENABLE_OFF & _LVP_OFF & _DEBUG_OFF & _CPD_OFF
 
;----------------------------------------------------------------------------
;Constants
SPBRG_VAL  EQU  .25  ;configuracion 9600 baudios a 4Mhz
;----------------------------------------------------------------------------
;Bit Definitions
GotNewData  EQU  0  ;bit indica nuevo dato recibido
;----------------------------------------------------------------------------
;Variables
    CBLOCK  0x020
    Flags    ;byte indicador banderas
    ENDC
;----------------------------------------------------------------------------
;Macros para seleccion de banco
Bank0    MACRO    ;bank 0
    bcf  STATUS,RP0
    bcf  STATUS,RP1
    ENDM
Bank1    MACRO    ;bank 1
    bsf  STATUS,RP0
    bcf  STATUS,RP1
    ENDM
Bank2    MACRO    ;bank 2
    bcf  STATUS,RP0
    bsf  STATUS,RP1
    ENDM
Bank3    MACRO    ;bank 3
    bsf  STATUS,RP0
    bsf  STATUS,RP1
    ENDM
 
;----------------------------------------------------------------------------
    ORG     0x0000    
ResetCode:  
    clrf    PCLATH  ;selecciona pagina 0
      goto    Main  ;va a programa
    ORG  0x0004  ;vector interrupcionm
InterruptCode:;codigo isr
    retfie    ;retorno
;----------------------------------------------------------------------------
Main:  call  SetupSerial;inicializa serial y buffer
    Bank1
    clrf  TRISB;puerto b como salida del dato recibido
    clrf  TRISA;puerto a salida para mostrar si hay error
    bank1
MainLoop:  
    call  ReceiveSerial;recepcion dato
    btfsc  Flags,GotNewData;verifica si se recibe dato
    call  showandtransmit;si ha recibido va a emitir 
    bcf  Flags,GotNewData;indica dato no recibido
  ;codigo
 
    goto  MainLoop;bucle
showandtransmit
    clrf  PORTA;limpia a
    movwf  PORTB;muestra dato en b
    call  TransmitSerial;si ha recibido muestra 
                                                                              ;y emite el dato
 
 
;----------------------------------------------------------------------------
;Analiza el dato recibido y lo pasa a W.
 
ReceiveSerial:  Bank0
    btfss  PIR1,RCIF;analiza si se ha rebicido dato
    return    ;vuelve si no se ha recibido
 
    btfsc  RCSTA,OERR;analiza desbordamiento
    goto  ErrSerialOverr;si hay se va a rutina
    btfsc  RCSTA,FERR;analiza error frame
    goto  ErrSerialFrame;si hay se va a rutina
 
    movf  RCREG,W  ;se carga el dato en w
    bsf  Flags,GotNewData;pone a 1 indicador de 
                                                                          ;dato nuevo
    return
 
;error desbordamiento
ErrSerialOverr:  
    bcf  RCSTA,CREN;resetea la recepcion
    clrf PORTA;
    bsf PORTA,0;  indica error desbordamiento
    bsf  RCSTA,CREN;habilita la recepcion
    return
 
;error FERR
 
ErrSerialFrame:
    clrf PORTA;
    bsf PORTA,1;  ;indica error ferr
    return
 
;----------------------------------------------------------------------------
;Transmite el dato en W cuando el transmisor esta listo
 
TransmitSerial:  Bank0    ;select bank 0
    btfss  PIR1,TXIF;verifica si transmision ocupada
    goto  $-1  ;espera a transmisor 
                                                                              ;no ocupado
    movwf  TXREG  ;transmite el dato
    return
 
;----------------------------------------------------------------------------
;Set up serial port.
 
SetupSerial:  Bank1    
    movlw  0xc0  ;configura bits tx y rx
    iorwf  TRISC,F
    movlw  SPBRG_VAL;carga para baudios
    movwf  SPBRG
    movlw  0x24  ;habilita transmision y   
                                                                                ; velocidad alta
    movwf  TXSTA
    Bank0
    movlw  0x90  ;activa puerto serial y la recepcion
    movwf  RCSTA
    clrf  Flags  ;limpia banderas
    return
 
;----------------------------------------------------------------------------
 
    END