este programa de abajo es una ampliacion del anterior.
en este he agregado un subprograma que selecciona los datos de la hora y las coordenadas.y luego pasa por otro que convierte estos datos a decimales para pasarlos a los registros direccionados a partir de la direccion 0xA0.
ademas he puesto en el programa principal unas instrucciones para visualizar los datos de los segundos por el PORTB.
;*****************************************
; PROGRAMA : gps_usart.asm
; Funcion : guarda la trama GPS en memoria ram
; Serial port config: 38400 baudios,8 bits,paridad = none
;
; Revision : 1.0 23/8/2009 Programa para : PIC16F876A
; CPU Clock : 3.6864 MHz Reloj instruccion :
; WDT : Deshabilitado Tipo de reloj : XT
; Code Prot : OFF
;******************************************
;
;NOTAS:
; este programa almacena una trama complata de GPS en la direccion 0x20
; y pasa los datos de hora y coordenadas a partir de la direccion A0.
;
LIST P=16F876A ;Se indica el modo de procesador
RADIX HEX ;Sistema de numeracion hexadecimal
INCLUDE "P16f876A.inc" ;se incluye la definicion de los
;registros internos
__CONFIG _CP_OFF & _PWRTE_OFF & _WDT_OFF & _XT_OSC & _BODEN_OFF &_LVP_OFF &_CPD_OFF ;&_WRT_ENABLE_OFF
ERRORLEVEL -302
CBLOCK 0X20 ;BLOQUE DEL COMANDO A LEER
C1 ;'$'
C2 ;'G'
C3 ;'P'
C4 ;'G'
C5 ;'G'
C6 ;'A'
C7 ;','
ENDC
CBLOCK 0x70
W_TEMP
STATUS_TEMP
PCLATH_TEMP
TEMP_FSR
TEMP_DATO_H
TEMP_DATO_L
TEMP_NUMERICO
PRINCIPIO_RAM
CARACTER
ENDC
PUSH MACRO ;macro para salvar registros antes de una llamada a interrupcion
BANK0
movwf W_TEMP
swapf STATUS,W
movwf STATUS_TEMP
clrf STATUS
movfw PCLATH
movwf PCLATH_TEMP
clrf PCLATH
movfw FSR
movwf TEMP_FSR
ENDM
POP MACRO ;macro para restaurar registros despues de una llamada a interrupcion
BANK0
movfw PCLATH_TEMP
movwf PCLATH
swapf STATUS_TEMP,W
movwf STATUS
swapf W_TEMP,F
swapf W_TEMP,W
movfw TEMP_FSR
movwf FSR
ENDM
BANK0 MACRO ;seleccion del banco 0
BCF STATUS,RP0
BCF STATUS,RP1
ENDM
BANK1 MACRO ;seleccion del banco 1
BSF STATUS,RP0
BCF STATUS,RP1
ENDM
BANK2 MACRO ;seleccion del banco 2
BCF STATUS,RP0
BSF STATUS,RP1
ENDM
BANK3 MACRO ;seleccion del banco 3
BSF STATUS,RP0
BSF STATUS,RP1
ENDM
;<<<<<<<<<<<<<SELECCION DE LOS SECTORES DE LA MEMORIA DE PROGRAMA>>>>
;--------IMPORTANTE:
;ANTES DE UBICAR UNA TABLA DEL TIPO (ADDWF PCL,F)TENEMOS QUE INDICAR EL SECTOR DONDE SE UBICA ESE SUBPROGRAMA
;EJM.SI PONEMOS EL SUBPROGRAMA EN EL SECTOR A PARTIR DE LA DIR:100 .PONDREMOS LA LINEA SECTOR_100 ANTES DE LA TABLA DE DATOS
;
SECTOR_000 MACRO ;seleccion del sector 000
BCF PCLATH,0
BCF PCLATH,1
ENDM
SECTOR_100 MACRO ;seleccion del sector 100
BSF PCLATH,0
BCF PCLATH,1
ENDM
SECTOR_200 MACRO ;seleccion del sector 200
BCF PCLATH,0
BSF PCLATH,1
ENDM
SECTOR_300 MACRO ;seleccion del sector 300
BSF PCLATH,0
BSF PCLATH,1
ENDM
#define GIE_ON bsf INTCON,GIE ;activa interrupciones
#define GIE_OFF bcf INTCON,GIE ;desactiva interrupciones
;<<<<<<---------------------- VECTOR DE RESET ------------------------>>>>>>>
ORG 0x00 ;Inicio en el Vector de Reset
goto INICIO ;Va a la primera instruccion del programa
;<<<<<<--------------------VECTOR DE INTERRUPCION---------------------->>>>>>>
ORG 0x04
goto INTER ;Va al programa de interrupcion
;<<<<<<----------------- INICIO PROGRAMA PRINCIPAL ------------------->>>>>>>
INICIO BANK0
clrf PORTB ;borra salidas de PORTB antes de configurarlo como salida.
BANK1 ;selecciona banco 1
movlw .5 ;(.5 =38400 baudios crystal 3.6864 MHz)
movwf SPBRG
movlw b'00000110'
movwf ADCON1 ;PORTA entradas digitales
movlw b'00000110' ;Configuracion USART modo alta velocidad
movwf TXSTA
movlw b'11000000'
movwf TRISC ;configura pins TX y RX para la usart
movlw b'00100000' ;habilita interrupcion por recepcion de usart
movwf PIE1
movlw b'01000000' ;habilita interrupciones perifericas
movwf INTCON
clrf PORTB ;PORTB como salida
BANK0 ;selecciona banco 0 -------------
movlw b'10010000' ;Configuracion de la usart
movwf RCSTA ;para recepcion continua y habilitacion de la usart
movlw '$' ;registros para la cabezera NMEA(cambiarlos para otra cabecera)
movwf C1
movlw 'G'
movwf C2
movlw 'P'
movwf C3
movlw 'G'
movwf C4
movlw 'G'
movwf C5
movlw 'A'
movwf C6
movlw ','
movwf C7
GIE_ON ;habilita interrupciones generales
;<<<<<<<------------------------------------------------PROGRAMA PRINCIPAL---------------------------------------->>>>>>>>>>>>>>
PRINCIPAL BANK1
movlw 0xA2 ;direccion segundos decimales.
movwf FSR ;cargala en el registro FSR
movfw INDF ;recoje el dato dicha direccion
BANK0
movwf PORTB ;visualizalo en el PORTB
goto PRINCIPAL
;<<<<<<<<<<--------------METE EN UN BLOQUE DE RAM LOS COMANDOS RECIBIDOS------------>>>>>>>>>>>>>>>
LEEDATO BANK0 ;Cambio al banco 0
movlw 0x1f ;carga en w el valor 0x1F principio de RAM para introducir mensages recividos"
movwf FSR ;cargalo en el puntero de registro de proposito general
LEEDATO2 incf FSR,F ;incrementa la siguiente direccion de la ram
movfw INDF ;carga en W el valor direcionado en FSR
xorwf RCREG,W ;comparalo con el caracter recivido de la USART
btfss STATUS,Z ;si es el mismo continua con el programa
return ;en caso contrario empieza de nuevo
call ERR_USART ;salta a ERR_USART
movlw ',' ;carga en w el caracter ',' caracter posterior de cabezera
xorwf RCREG,W ;comparalo con el caracter recivido de la USART
btfss STATUS,Z ;si es el mismo salta
goto LEEDATO2
SIGUIENTE incf FSR,F ;incrementa FSR
movfw RCREG ;carga en W el caracter recivido
movwf INDF ;mete el caracter en la posicion de memoria que apunta FSR
movlw '*' ;carga valor '*' en w
xorwf RCREG,W ;comparalo con el valor recivido de la usart(caracter de fin trama)
btfsc STATUS,Z
return ;si es igual retorna(fin de captura de trama)
movlw 0x6F ;valor limite de RAM
xorwf FSR,W
btfsc STATUS,Z
return ;si se excede del valor anterior.retorna
call ERR_USART ;salta a ERR_USART
goto SIGUIENTE
;<<<<<<<<<<<<<<<<<<<<------SUBPROGRAMA PARA ESPERA DE CARACTER Y CORRECTOR DE ERRORES----->>>>>>>>>>>>>
ERR_USART btfss PIR1,RCIF ;espera al proximo caracter
goto ERR_USART
btfsc RCSTA,OERR
call BORR_ERR ;Error de Sobreescritura
btfsc RCSTA,FERR
call BORR_ERR ;Error de Trama
bcf PIR1,RCIF ;borra el flag de interrupcion por caracter recivido
return
BORR_ERR bcf RCSTA,CREN ;deshabilita recepcion usart
movf RCREG,w
movf RCREG,w
movf RCREG,w
bsf RCSTA,CREN ;habilita recepcion usart
return
;<<<<<<<--------------------------PROGRAMA PARA ALMACENAR A PARTIR DE LA DIRECION 0XA0 DE LA RAM,LOS DATOS IMPORTANTES DE LA TRAMA NMEA.--------
GRARAM movlw 0xA0 ;valor del principio de los registros a leer
movwf PRINCIPIO_RAM ;carga el valor en el registro puntero.
BANK0
movlw 0x27 ;valor del primer caracter de la ram a traducir
movwf TEMP_FSR ;cargalo en el registro temporal FSR
REP3 movfw TEMP_FSR
movwf FSR ;carga el puntero de ram
movfw FSR ;
xorlw 2D ;direccion comienzo a ignorar "direccion de comienzo de datos inservibles"
btfsc STATUS,Z
call SUMA5 ;cinco pociciones de memoria a ignorar
movfw FSR ;
xorlw 36 ;direccion comienzo a ignorar
btfsc STATUS,Z
call SUMA1 ;una pocicion de memoria a ignorar
movfw FSR ;
xorlw 3B ;direccion centenas de coordenada ecuador
btfsc STATUS,Z
call CENTENAS
movfw FSR ;
xorlw 43 ;direccion comienzo a ignorar
btfsc STATUS,Z
call SUMA1 ;una pocicion de memoria a ignorar
movfw FSR ;
xorlw 48 ;direccion comienzo a ignorar
btfsc STATUS,Z
return ;final del subprograma
movfw TEMP_FSR
movwf FSR ;carga el puntero de ram
movfw INDF ;recoge valor
movwf CARACTER
movfw CARACTER
call TRADUCE ;traduce el valor ascii a decimal
movwf TEMP_NUMERICO ;temporal de valor traducido.
movfw PRINCIPIO_RAM
movwf FSR
movfw TEMP_NUMERICO
movwf INDF
incf PRINCIPIO_RAM,F
BANK0
incf TEMP_FSR,F
REP4 incf TEMP_FSR,F
goto REP3
SUMA5 movlw 0x05 ;salto de 5 direcciones FSR
addwf TEMP_FSR,f
return
SUMA1 movlw 0x01 ;salto de 1 direccion FSR
addwf TEMP_FSR,f
return
SUMA2 movlw 0x02 ;salto de 2 direcciones FSR
addwf TEMP_FSR,f
return
CENTENAS movlw 0x3E
movwf FSR
clrf TEMP_DATO_H
movlw '0'
xorwf INDF,W
btfss STATUS,Z
incf TEMP_DATO_H,F
movlw 0x3F
movwf TEMP_FSR
BANK1
incf PRINCIPIO_RAM,F
BANK0
movlw 0xA7
movwf FSR
movfw TEMP_DATO_H
movwf INDF
return
;<<<<<<<<<<<-------------CONVERTIR VALORES HEX EN DECIMALES--------------->>>>>>>>>>>>>>>>>>>>>>>>>>>>>
TRADUCE movwf TEMP_DATO_H ;
movlw 0x30
subwf TEMP_DATO_H,F
swapf TEMP_DATO_H,F
incf FSR,F
movfw INDF
movwf TEMP_DATO_L
movlw 0x30
subwf TEMP_DATO_L,W
addwf TEMP_DATO_H,W
return
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<PROGRAMA DE GESTION DE INTERRUPCIONES>>>>>>>>>>>>>>>>>>>>>>
INTER PUSH ;salva el contenido de W,STATUS Y PCLATH
BANK0
call LEEDATO
call GRARAM
bcf PIR1,RCIF ;borra flag de interrupcion por recepcion de usart
call BORR_ERR
POP ;restaura el contenido de W,STATUS Y PCLATH
retfie
END