Tengo un problema, estoy manejando un pic 16F873, habilite el puerto A, como 4 entradas analogas (Variacion de 0 - 5VDC), realizo la conversion ADC y la envio por el puerto C, por los pines q habilitan el puerto Serial, pero cuando hago la conversion este no la hace correctamente siempre, por ejemplo si tengo 5V, el deberia mostrar 3FF, pero solo algunas veces muestra el valor correcto aunque mi señal analoga este fija. Este programa envio tres digitos hexa por cada entrada analoga, es decir que por el puerto C envia una rata de datos de esta forma 3FF2F12FF0FF, para que em puedan ayudar mejor este es el programa y no se donde esta la falla. Gracias!!!!
;Utilizando el PIC16F873
;Micro=PIc16F873;
;WDT=off;OSc=xt;PWRT=on
;DEFINICION DE REGISTROS Y BIST UTILIZADOS
status equ 03
ptoa equ 05
ptob equ 06
ptoc equ 07
pclath equ 0ah
intcon equ 0bh
pir1 equ 0ch
rcsta equ 18h
txreg equ 19h
rcreg equ 1ah
adresh equ 1eh
adcon0 equ 1fh
trisa equ 85h
trisb equ 86h
trisc equ 87h
txsta equ 98h
spbrg equ 99h
adres1 equ 9eh
adcon1 equ 9fh
rp0 equ 5
rp1 equ 6
irp equ 7
z equ 2
c equ 0
txif equ 4
rcif equ 5
go equ 2
loops equ 20h
loops2 equ 21h
nibble1 equ 22h
nibble2 equ 23h
nibble3 equ 24h
buffer equ 25h
filter1 equ 26h
filter2 equ 27h
filter3 equ 28h
veces equ 29h
LRC equ 2ah
;*********begin the program
org 00
goto inicio
retardo ;subrutina de retardo en milisegundos
movwf loops
top2 movlw d'110' ;numero de milisegundos
movwf loops2 ;cargado en el registro loops
top nop
nop
nop
nop
nop
nop
decfsz loops2 ;pregunta si termino 1mS
goto top
decfsz loops ;pregunta si termino cerrado
goto top2
return
;Rutina de conversion ADC a 10 bits
;devuelve dos datos
conver bsf status,rp0
movlw b'10000010' ;selecciono vref internos y 5 canales
movwf adcon1 ;8 bits en ADRESL y 2 bit en ADRESH
bcf status,rp0
nop
nop
nop
nop ;tiempo de adquisicion 7 uS
nop
nop
nop
bsf adcon0,go ;inicio de conversion
nop
nop
consu btfsc adcon0,go ;espera q termine de convertir
goto consu
nop
return
;Esta rutina toma 256 muestras y las promedia
filtro clrf filter1 ;para que el dato enviado de cada canal
clrf filter2 ;sera muy confiable
clrf filter3 ;intervalo entre muestras es de 1mS
clrf veces
repeat movlw d'1' ;retardo de un miliseg
call retardo ;toma de la muestra
call conver
bsf status,rp0 ;las muestras se suman y el resultado queda en tres bits
movf adres1,w ;filter1, filter2, filter3
bcf status,rp0
addwf filter3,1
btfss status,c ;Para completar el pormedio, luego de sumar 256 datos
goto filt2 ;
movlw d'1' ;de menor peso de las sumas
addwf filter2,1
goto filt2 ;
movlw d'1' ;de menor peso de las sumas
addwf filter1,1
filt2 movf adresh,w ;A la hota de tx datos solo toma en cuenta los dos bytes de mayor peso filter1 y filter2
addwf filter2,1 ;peso: filter1 y filter2
btfsc status,c
incf filter1
decfsz veces,1 ;Repite el ciclo de sumar muestras hasta que acabe
goto repeat ;de tomar las 256 veces
movf filter1,w ;debe pasar los dos bytes hexa
movwf nibble1 ;a los registros individuales para
movlw 30h ;ser TX
addwf nibble1 ;le suman 30
movf filter2,w ;para convertirlo en ASCII
movwf buffer ;antes de tx
andlw 0fh
movwf nibble3 ;contiene el digito menos significativo
movlw 0ah
subwf nibble3,0 ;Verifica si es una letra o un numero
movlw 37h
btfss status,c
movlw 30h ;ser TX
addwf nibble3 ;le suman 30
swapf buffer,0 ;antes de tx
andlw 0fh
movwf nibble2 ;contiene el digito menos significativo
movlw 0ah
subwf nibble2,0 ;Verifica si es una letra o un numero
movlw 37h
btfss status,c
movlw 30h ;ser TX
addwf nibble2 ;le suman 30
return
;Esta rutina envia serialmente los datos obtenidos en cada conversion
enviar movf nibble1,0 ;transmitiendo el digito hexa de mayor peso
; addwf LRC ;suma el dato a transmitir con el LRC
call trasmi ;para llevar el calculo de los datos enviados
movf nibble2,0 ;tx el segundo digito hexa
; addwf LRC ;suma el dato a transmitir con el LRC
call trasmi ;para llevar el calculo de los datos enviados
movf nibble3,0 ;tx el tercer digito hexa
; addwf LRC ;suma el dato a transmitir con el LRC
call trasmi ;para llevar el calculo de los datos enviados
; movlw A',' ;enviar el caracte "," para separa datos
; addwf LRC ;suma el dato a transmitir con el LRC
; call trasmi ;para llevar el calculo de los datos enviados
return
;Transmite cualquier caracter especial
trasmi btfss pir1,txif ;pregunta si el usart esta listo para transmitir
goto trasmi ;si no esta listo espera
movwf txreg
nop ;confirma si ya habia enviado el caracter especial
trasmi2 btfss pir1,txif ;si no espera a que termine de enviarlo
goto trasmi2 ;si no esta listo espera
return
;Esta es la rutina que transmite el caracter de chequeo LRC
lrctx comf LRC,1 ;complementa el contenido de LRC
incf LRC,0 ;Para q sea complemento de los dos le suma 1 LRC
andlw 0fh
movwf nibble3
movlw 0ah ;Nibble3 que contiene el digito menos significativo debe probarse para ver si es un
subwf nibble3,0 ;numero de 0 a 9o si es una letra
movlw 37h ;para hacer la conversion a codigo ascii
btfss status,c
movlw 30h
addwf nibble3
swapf buffer,0
andlw 0fh
movwf nibble2 ;El digito de mas peso tiene el mismo proceso que el anterior
movlw 0ah
subwf nibble2,0
movlw 37h
btfss status,c
movlw 30h
addwf nibble2
movf nibble2,0 ;Transmite el digito alto del LRC
call trasmi
movf nibble3,0 ;Transmite el digito bajo del LRC
call trasmi
return
;--------------- main program ------------------
inicio bsf status,rp0
movlw 0ffh
movwf trisa ;Puerto A entradas
movwf trisb ;Puerto B entradas
movlw b'10111111'
movwf trisc ;Puerto C entradas y pin TX salida
movlw b'00100110' ;programa USART asincrono para TX
movwf txsta ;alta rata de baudios
movlw d'25' ;configura temporizador a 4MHz
movwf spbrg ;9600 bps (8,n,1)
bcf status,rp0
bsf pir1,txif
bcf pir1,rcif
movlw b'10010000' ;habilita el puerto serial
movwf rcsta
; clrf LRC ;inicio en ceros el caracter de chaequeo de error
ciclo btfss pir1,rcif ;pregunta si el buffer de recepcion esta lleno
goto ciclo ;si esta vacio vuelve a esperar en ciclo
; movf rcreg,0 ;pasa el contenido del Buffer a w
; xorlw d'13' ;para verificar si es el caracter enviado del PC
; btfss status,z ;para comprobar hace una xor con el dato que llego con
; goto inicio ;el valor ASCII del caracter esperando que es el 13
; movlw A':' ;Inicia la trama con caracter
; call trasmi
movlw b'10000001' ;selecciona el canal 0, reloj de conv fosc/32
movwf adcon0 ;convertidor encendido
call filtro ;llama rutina de conversion AD
call enviar ;envia datos seriales
movlw b'10001001' ;selecciona el canal 1, reloj de conv fosc/32
movwf adcon0 ;convertidor encendido
call filtro ;llama rutina de conversion AD
call enviar ;envia datos seriales
movlw b'10010001' ;selecciona el canal 2, reloj de conv fosc/32
movwf adcon0 ;convertidor encendido
call filtro ;llama rutina de conversion AD
call enviar ;envia datos seriales
movlw b'10011001' ;selecciona el canal 3, reloj de conv fosc/32
movwf adcon0 ;convertidor encendido
call filtro ;llama rutina de conversion AD
call enviar ;envia datos seriales
; call lrctx ;transmite el caracter LRC calculado con los datos
; movlw d'13' ;Envia a caracter Carriage Return
; call trasmi
; movlw d'10' ;Envia caracter Line Feed
; call trasmi
goto inicio ;Vuelve a empezar el ciclo para esperar que le soliciten otro paquete de dato
end