bueno.seguimos implementando usarts por software.
ahora utilizare el 16F84 y usare sus interupciones.he intentado exponerlo con el comando code.pero salen las lineas desordenadas.
no se como hacerlo

;*****************************************www.ingeniopic.com***************************+******
; PROGRAMA : usart_16F84
; Funcion : recepcion de datos serie
;
;
; Revision : 1.0 12/12/2009 Programa para : PIC16F84
; CPU Clock : 4 MHz o 20Mhz Reloj instruccion :
; WDT : Deshabilitado Tipo de reloj : XT
; Code Prot : OFF
;*****************************************www.ingeniopic.com**********************************
;
;NOTAS: este programa esta preparado para interrumpir el funcionamiento del programa programa principal para atender
; una interrupcion por recepcion de datos provenientes de una usart.la velocidad de la usart podemos modificarla
; cambiando el valor del registro BAUDRATE.que esta un poco mas abajo de la etiqueta INICIO.cuanto mayor sea la velocidad.mayor sera el margen de error.
; el dato que recivamos por PB0 sera transmitido por PB1.
;
LIST P=16F84 ;Se indica el modo de procesador
RADIX HEX ;Sistema de numeracion hexadecimal
INCLUDE "P16F84.inc"
;registros internos
__CONFIG _XT_OSC & _CP_OFF & _WDT_OFF
ERRORLEVEL -302
CBLOCK 0x0C
CONTADOR
DATO
BAUDRATE
W_TEMP
STATUS_TEMP
PCLATH_TEMP
ENDC
PUSH MACRO ;macro para salvar registros antes de una llamada a interrupcion
movwf W_TEMP
swapf STATUS,W
movwf STATUS_TEMP
clrf STATUS
movfw PCLATH
movwf PCLATH_TEMP
clrf PCLATH
ENDM
POP MACRO ;macro para restaurar registros despues de una llamada a interrupcion
movfw PCLATH_TEMP
movwf PCLATH
swapf STATUS_TEMP,W
movwf STATUS
swapf W_TEMP,F
swapf W_TEMP,W
ENDM
#define BANK0 bcf STATUS,RP0
#define BANK1 bsf STATUS,RP0
;<<<<<<---------------------- VECTOR DE RESET ------------------------>>>>>>>
ORG 0x00 ;Inicio en el Vector de Reset
goto INICIO ;Va a la primera instruccion del programa
;<<<<<<---------------------- VECTOR DE INTEUPCIONES ------------------------>>>>>>>
ORG 0x04 ;Inicio en el Vector de Reset
goto INTERRUPCIONES ;Va a la primera instruccion del programa
;<<<<<<----------------- INICIO PROGRAMA PRINCIPAL ------------------->>>>>>>
INICIO BANK1
movlw b'10000000' ;activar interrupcion por cambio de estado a 0 de RB0
movwf OPTION_REG
movlw b'10010000' ;configura interrupcion por desbordaminto de TMR0 y por cambio de estado a 0 de RB0
movwf INTCON
movlw b'00010001' ;habilita interrupcion por cambio de estado en RB0/INT
movwf TRISB
BANK0
bsf PORTB,1 ;establecer la salida usart a 1
movlw d'15' ;valor para la velocidad de la usart
movwf BAUDRATE
;valores para el baudrate:para 4Mhz
;
;para divisor TMR0=000
;190=2400bps, 90=4800bps, 40=9600bps, 15=19200bps,
;
;para divisor TMR0=010
;97=1200bps,
;
;valores para el baudrate:para 20Mhz
;
;para divisor TMR0=000
;51=38400,31=57600.
;<<<<<<<------------------------------------------------PROGRAMA PRINCIPAL---------------------------------------->>>>>>>>>>>>>>
PRINCIPAL NOP
goto PRINCIPAL
;<<<<<<---------------------------------------------SUBPROGRAMA RECEPCION DE DATOS--------------------------
RECEPCION clrf CONTADOR ;borra el contador de bits
clrf TMR0 ;borra TMR0
movfw BAUDRATE ;carga valor del baudrate en w
subwf TMR0,w ;comprueva si ha llegado al valor o se pasa
btfss STATUS,C ;si es menos sigue comprovando
goto $-3
COMP1 clrf TMR0 ;borra TMR0
COMP2 movfw BAUDRATE ;carga valor del baudrate en w
subwf TMR0,w ;resta el contenido de TMR0 con el de w(comprovacion => )
btfss STATUS,C ;comprueva si ha llegado al valor o se pasa
goto COMP2 ;si es menos sigue comprovando
bcf PORTB,2
bsf PORTB,2
btfsc PORTB,0 ;comprueva el estado del pin de entrada
call UNO ;si es 1 salta a UNO
btfss PORTB,0 ;comprueva el estado del pin de entrada
call CERO ;si es 0 salta a CERO
incf CONTADOR,F ;incrementa el contador de bits
movlw 0x08 ;valor de bit a comprovar
xorwf CONTADOR,W ;hacer xor con CONTADOR
btfss STATUS,Z ;comprueva si es igual
goto COMP1 ;si no es igual sigue las comprobaciones
movfw DATO ;carga el dato recivido en w
return ;retorno de subprograma RECEPCION
UNO rrf DATO,F ;rota a la derecha una posicion
bsf DATO,7 ;pon a 1 el bit 7 del registro DATO
return ;retorna
CERO rrf DATO,F ;rota a la derecha una posicion
bcf DATO,7 ;pon a 0 el bit 7 del registro DATO
return ;retorna
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<SUBPROGRAMA DE ENVIO DE DATOS>>>>>>>>>>>>>>>>>
ENVIO bsf PORTB,1 ;establecer la salida a 1(evitar errores primer caracter)
ENVIO2 clrf CONTADOR ;borra el registro CONTADOR de bits
bcf PORTB,1 ;bit START
call RETARDO
ENV_1 btfsc DATO,0 ;comprueva bit 0 del registro DATO(comprovacion de bits a enviar)
call UNOS ;salta a UNOS si el bit leido es 1
btfss DATO,0 ;comprueva bit 0 del registro DATO(comprovacion de bits a enviar)
call CEROS ;salta a CEROS si el bit leido es 0
ENV_2 rrf DATO,F ;rota a la derecha el registro DATO
incf CONTADOR,F ;incrementa CONTADOR (registro contador de bits)
movlw 0x08 ;valor de bits a leer
xorwf CONTADOR,W ;comprueva si son 8
btfss STATUS,Z ;si no es 8 repite la comprovacion del siguiente bit
goto ENV_1 ;comprueva de nuevo
bsf PORTB,1 ;establecer a 1 la salida
return ;retorna
UNOS bsf PORTB,1 ;saca valor 1 por pin 1 de PORTB
call RETARDO ;tiempo de un bit
return ;retorna
CEROS bcf PORTB,1 ;saca valor 0 por pin 1 de PORTB
call RETARDO ;tiempo de un bit
return ;retorna
;**********************************************RETARDO***************************************
;
;
RETARDO clrf TMR0 ;borra el temporizador
COMP movfw BAUDRATE ;valor del retardo
subwf TMR0,w ;comprueva si ha llegado al valor o se pasa
btfss STATUS,C ;si es menos sigue comprovando
goto COMP
return ;si ha llegado retorna
;*********************************************INTERRUPCIONES******************************
INTERRUPCIONES PUSH ;guarda valores de registros
btfss INTCON,INTF ;comprueva interrupcion por cambio de PB0/INT
goto SALIR ;salir del programa
call RECEPCION ;programa de recepcion de datos
call ENVIO ;programa de envio de datos
SALIR bcf INTCON,INTF ;borra bandera señalizadora de interrupcion por cambio en PB0/INT
POP ;restaura valores de registros
retfie ;retorna y activa interrupciones
end ;fin