Programa de conversión A/D con Pic 16f877/A

Saludos a todos.

Vengo de nuevo a matar un poco más mi ignorancia acerca de los pic y assembler.

Bueno, sucede que quería hacer un programa que me hiciera la conversión de analógico a digital del pin RA0 del 16f877; en fin, lo hice siguiendo los pasos de la hoja de datos, pero no veo ningún resultado en ADRESH:ADRESL, los dos siempre están en cero. Bueno, tal vez estoy haciendo mal la simulación en MPLAB, porque no sé como hacer una simulación de una entrada analógica. Sin embargo, el MPLAB no me da ningún mensaje de error. Pero hay algo que no está funcionando bien con el programa que hice.

En dicho programa tengo una rutina llamada conversión, la cual e:

Conversión
btfsc adcon0,2
goto Conversión
call delay_2Tad
goto Principal

Sucede que el bit 2 del registro adcon0 se pone en cero cuando estoy en la linea 'goto Conversión' y presiono F7 para el step into, pero aquí el programa no funciona a como debería. Al presionar F7 no se me ejecuta la instrucción 'goto Conversión', sino que el programa hace un salto a la linea numero 5 de la rutina Principal, y de ahí vuelve a comenzar el programa. Bueno, ese salto lo hace después de algunas evaluaciones de la instrucción btfsc, a como debería. La lógica de la secuencia es que al estar en la linea de 'goto Conversión' y al presionar F7, el programa debería hacer otra evaluación del bit 2 del registro adcon0 y luego saltar a la linea call delay_2Tad, pero no lo hace. Realmente no sé lo que esté mal. Aquí pongo todo el programa para que lo chequeen, y si hay algún comentario o sugerencia, se los agradeceré.


Código:
list p=16f877
processor "16f877.inc"

;***Comienzo a definir variables***

estado	equ	0x03
trisA	equ	0x85
trisB	equ	0x86
portA	equ	0x05
portB	equ	0x06
adresh	equ	0x1e
adresl	equ	0x9e
adcon0	equ	0x1f
adcon1	equ	0x9f

;***Configuración del módulo A/D
;y puertos de entrada y salida***

Inicio
		movlw	b'00100000'
		movwf	estado
		movlw	0x03	 	 ;Cargo W=b'00011' 
		movwf	trisA		 ;y lo paso a trisA.
		movlw	0xff	 	 ;Cargo W=b'11111111'
		movwf	trisB	 	 ;y lo paso a trisB.
	 	movlw	b'10000100'	 ;Cargo W=b'0100' y lo paso a adcon1
		movwf	adcon1	     ;para configurar las entradas analógicas.
		
Principal
		bcf		estado,5 	 ;Acceso al banco0.
		movlw	b'01000001'	 ;Selecciono el canal de entrada
		movwf	adcon0		 ;y el clk de conversión para el A/D.
		bcf		0ch,6		 ;Pongo a cero el bit ADIF de PIR1.
		bsf		0bh,7		 ;Activo los bit GIE
		bsf		0bh,6		 ;y PEIE del registro INTCON.
		bsf		estado,5	 ;Acceso al banco1.
		bsf		8ch,6		 ;Activo el bit ADIE del registro PIE1.
		bcf		estado,5	 ;Acceso al banco0.
		call	Espera
		bsf		adcon0,2
		
Conversión
		btfsc	adcon0,2
		goto Conversión
		call delay_2Tad
		goto Principal

Espera
		movlw	0x1f
		movwf	20h
		loop
			decfsz	20h,1
			goto loop
		return

delay_2Tad
		movlw	0x15
		movwf	20h
		loop1
			decfsz	20h,1
			goto loop1
		return
end


PD: El tirsB y el portB realmente no hacen ninguna función en el programa, ignorenlos.
 
no me atrevi a leer tu codigo, pero igual me tarde en programarlo, puede ser un registro mal progtramado etc, yo lo que hice fue probarlo directamente, y lo hice mediante una tableta electronica, hice las conexiones y en el pin de conversion coloque un potenciometro, y puse los registros de conversion que los despleagara en el puerto B del 16f88. en realidad es lo mismo para todos los micros, lo que pasa es que hay que saber leerlos.
 
hola

no lei todo tu programa, pero si esta saltando a la direccion 5 a lo mejor es que se esta generando una interrupcion en ese momento, o activaste la interrupcion por conversor a/d, una forma fás facil es acerla en pic basic, es tro lenguaje de programacion parecido al C, es bastatnte facil aprender, y para la conversion solo utilizas un comando que ADCIN y luego los parametros como cual canal, entre otyros , eso es facilmente reconocible en la ayuda

ah otra cosa porque no lo simulas en Proteus, ahi si se puede simularla conversion conectando un potenciometro le cargas el .hex de tu programa y listo, fnciona a la perfeccion..

Jairo
 
Hola a todos.

Agradezco los comentarios y sugerencias de Carlosxyz y Jairo.
Ya me dí cuenta de la razón de ese salto a la línea 5 de la rutina Principal. Lo que pasa es que la conversión A/D, al ser completada, genera una interrupción; y cada vez que se genera una interrupción el pic hace que el programa vaya a la dirección 0x04, la cual es la linea 5 de la rutina Principal.

Esta es la modificación que le hice al programa:

Código:
********************************************************************************

list p=16f877
processor "16f877.inc"

;***Comienzo a definir variables***

status	equ	0x03
trisA	equ	0x85
trisB	equ	0x86
portA	equ	0x05
portB	equ	0x06
adresh	equ	0x1e
adresl	equ	0x9e
adcon0	equ	0x1f
adcon1	equ	0x9f

;***Configuración del módulo A/D
;y puertos de entrada y salida***

org	0x00
		goto	Inicio
org 0x04
		call 	delay_2Tad
		bcf		0ch,6
		retfie
	

Inicio	
		movlw	b'00100000'
		movwf	status
		movlw	0x03	 	 ;Cargo W=b'00011' 
		movwf	trisA		 ;y lo paso a trisA.
		movlw	0xff	 	 ;Cargo W=b'11111111'
		movwf	trisB	 	 ;y lo paso a trisB.
	 	movlw	b'10000100'	 ;Cargo W=b'0100' y lo paso a adcon1
		movwf	adcon1	     ;para configurar las entradas analógicas.
	
Principal
		bcf		status,5 	 ;Acceso al banco0.
		movlw	b'01000001'	 ;Selecciono el canal de entrada
		movwf	adcon0		 ;y el clk de conversión para el A/D.
		bcf		0ch,6		 ;Pongo a cero el bit ADIF de PIR1.
		bsf		0bh,7		 ;Activo los bit GIE
		bsf		0bh,6		 ;y PEIE del registro INTCON.
		bsf		status,5	 ;Acceso al banco1.
		bsf		8ch,6		 ;Activo el bit ADIE del registro PIE1.
		bcf		status,5	 ;Acceso al banco0.
		call	Espera
		bsf		adcon0,2
		
Conversion
		btfsc	adcon0,2
		goto	Conversion
		goto 	Principal

Espera
		movlw	0x1f
		movwf	20h
		loop
			decfsz	20h,1
			goto loop
		return

delay_2Tad
		movlw	0x15
		movwf	20h
		loop1
			decfsz	20h,1
			goto loop1
		return
end
		
********************************************************************************
Buen día.
 
Última edición por un moderador:
Hola amigos soy nuevo en este foro, saben tengo un problema estoy construyendo un termometro digital, el material que adquiri para esto es un pic 16f877a y un lm35, de lcd tengo una de 16x2, el problema es que quiero usar lenguaje c para hacer esto, ya antes lo habia hecho lo de imprimir con una lcd pero con un 16f84, pero en este 16f877a simplemente no puedo lo he intentado al menos con los puertos b,c,d y pss nada que sale aqui pongo el codigo que estoy usando para este fin espero alguien sepa que me esta fallando y me puedan ayudar, solo quiero mostrar el mensaje en lcd el conversor analogico ya funciona solo necesito saber como imprimir, saludos...

Código:
#include <16f877.h>
#use delay (clock=40000000) //Modo del oscilador
#fuses XT,NOWDT,NOPROTECT,BROWNOUT,NOLVP,PUT 
#include <lcd.c>
void main()
{ 
  lcd_putc("inicializando...");
  delay_ms(2000);
  lcd_putc("Temperatura : ");
  delay_ms(2000);
}
 
Última edición por un moderador:
JuantoHdez, debes de tener en cuenta q las direcciones de memoria de un PIC16F84 son muy diferentes a las del 16F877A, si observas el data sheet de cada uno te das cuenta que el PIC16F84 empieza en 0xC, y el del PIC16F877A en 0x20..... observa eso (a mi me paso)

espero te sirva
 
tome el ejercicio de hacer oscilar un led de una pagina pero no me acuerdo cual era la pagina (funciona) luego trate de regular la frecuancia de ocilacion de un led con un potenciometo de 100k (la pata del medio a ra0 y una pata a negativo y la otra a vcc) pero no me funciono T_T

aki dejo el codigo para ke lo vean.

Código:
LIST p=16F877

status equ 03h
trisa equ 85h
porta equ 05h
trisb equ 86h
portb equ 06h
intcon equ 0bh
pir1 equ 0ch
pie1 equ 8ch
adresh equ 1eh
adresl equ 9eh
adcon0 equ 1fh
adcon1 equ 9fh
CUENTA1 equ 20h ;Las variables que usemos siempre a
CUENTA2 equ 21h ;partir de la direccion 20h
cuenta3 equ 22h
cuenta equ 23h

#define banco0 bcf status,5
#define banco1 bsf status,5

F EQU 1
w EQU 0


ORG 00h
goto inicio
org 04h
call delay_2Tad
bcf pir1,6
retfie

inicio banco0
bsf intcon,7
bsf intcon,6
bsf pir1,6
banco1
bsf pie1,6
bsf adcon1,7
banco0
bsf adcon0,2


Conversion btfsc adcon0,2
goto Conversion
movf adresl,0
movwf CUENTA2




movlw 0ffH ;Pone a "1" RB0 (enciende)
movwf portb
CALL DELAY ;Llama a la subrutina de retardo
movlw 00H ;Cuando vuelve del retardo pone
movwf portb ;a "0" RB0 (apaga)
CALL DELAY ;llama a la subrutina de retardo
GOTO inicio ;cuando vuelve del retardo
;ejecuta el GOTO


;= DELAY: Subrutina de retardo
;= Modifica los siguientes registros:
;= CUENTA1
;= CUENTA2
;= ACUMULADOR
;= STATUS


DELAY MOVLW 0FFH ;Carga el acumulador con el valor
;10H (16 en decimal)
MOVWF CUENTA1 ;Mueve el contenido del acumulador
;a CUENTA1
ACA1 MOVLW 100H ;Carga el acumulador con el valor FFH
MOVWF CUENTA2 ;Mueve el contenido del acumulador
;a CUENTA2
ACA DECFSZ CUENTA2,F ;Decrementa CUENTA2, guarda el resultado
;en f, y si es cero se salta la siguiente
;instrucción
GOTO ACA ;vuelve a decrementar mientras
;CUENTA2 no sea cero
DECFSZ CUENTA1,F ;Se decrementa CUENTA1 cada vez que
;CUENTA2 llega a cero
GOTO ACA1 ;mientras CUENTA1 no llegue a cero recarga
;CUENTA2 y repite el proceso
RETURN ;retorna al programa principal


;= FIN DE LA SUBRUTINA DELAY

espera movlw 0x1f
movwf cuenta3
loop decfsz cuenta3,1
goto loop
return

delay_2Tad movlw 0x15
movwf cuenta3
loop1 decfsz cuenta3,1
goto loop1
return

END ;Fin del programa

trate de acomodarlo lo mejor ke pude
 
Última edición por un moderador:
Que tal, trabajo en el bien conocido termómetro digital con el LM35. Yo programo en Pic Basic Pro. El problema es que el lm35 marca .270 V y me muestra 22 grados en el LCD. Dejo el programa:

Código:
'****************************************************************
'*  Name    : SENSOR DE TEMPERATURA                             *
'*  Author  : [Ing. Iván Alejandro Rodríguez Ambríz]            *
'*  Notice  : Copyright (c) 2007 [select VIEW...EDITOR OPTIONS] *
'*          : All Rights Reserved                               *
'*  Date    : 17/07/2008                                        *
'*  Version : 1.0                                               *
'*  Notes   :                                                   *
'*          :                                                   *
'****************************************************************
DEFINE ADC_BITS 8         'Activa el ADC de 8 bits
TRISA = 255                     ' Fija todos los pines del puerto A como entradas
ADCON1 = %00001110              ' Config. PORTA. 6bits de menor peso y AN0 entrada analógica, 'el resto son entradas digitales
ADCON0=  %10000001            'Fosc/32,ch0 y ADC en marcha

MUL VAR BYTE

define osc 4 
DEFINE LCD_DREG PORTB                ' LCD Data port
DEFINE LCD_DBIT 0                          ' starting Data bit (0 or 4) if 4-bit bus
DEFINE LCD_RSREG PORTD              ' LCD Register Select port
DEFINE LCD_RSBIT 7                        ' LCD Register Select bit
DEFINE LCD_EREG PORTD                ' LCD Enable port
DEFINE LCD_EBIT 6                          ' LCD Enable bit
DEFINE LCD_BITS 8                          ' LCD bus size (4 or 8 bits
DEFINE LCD_LINES 2                        ' Number of lines on LCD
DEFINE LCD_COMMANDUS 2000
DEFINE LCD_DATAUS 50

ANALOGICO var BYTE
 

LCDOUT  $FE,1   
PAUSE   200

LCDOUT "IVAN AMBRIZ CO"
LCDOUT $FE,$C0,"PIC 16F877A"
PAUSE 300

INICIO:          
       ADCIN 0, analogico                'Lee el CH0 y lo asigna a analogico
       MUL=ANALOGICO*2              'Deduje la multiplicación a prueba y error, pero no se porque 'la conversion directa me da la mitad del valor real
     
      LCDOUT  $FE,1,"TEMPERATURA:", DEC MUL
           
       LCDOUT $FE,$C0,"'C: "
       
       pause 100

goto inicio 


'**********************************************************************

Lo que no me queda claro es, por ejemplo si mi entrada analógica es 270 mV, cómo se me muestra en el display? que es el caso y me da 11, con la multiplicacion 22.

Adjunto la simulación en PROTEUS, ahi si da los 28 grados correspondientes

Gracias.
Gracias por su ayuda.
 

Adjuntos

  • sensor_491.rar
    16.1 KB · Visitas: 1,913
Última edición por un moderador:
hola, amigos soy nuevo en esto y tengo una pregunta muy relacionada con el conversor anologico digital del pic 16f877a, lo q pasa esque estoy realizando un trabajo sobre un termometro digital. hice un codigo en lenguaje ensamblador y pues si me realiza la conversion pero tengo dos pregunta he incovenientes
-el primer inconveniente es que si yo quiero justificarlo a la derecha colocando un 1 en el bit adfm del registro adcon1, al hacer la simulacion en el isis, no me realiza la conversion analogica digital y en la mayoria de los bits me aparecen como ceros
-el segundo incoveniente es que si yo quiero hacer la conversion analogica digital cada 10ms aprox por ejemplo utilizando el lm35, no me la realiza inclusive tomando los 10 bits, este es mi codigo

Código:
list p=16f877A
		#include P16f877A.inc
		org 0x05

inicio
		bcf STATUS,RP0
		bcf STATUS,RP1
		movlw 0x41
		movwf ADCON0
		bsf STATUS,RP0
		bcf STATUS,RP1
		clrf TRISA
		clrf TRISB
		clrf TRISC
		movlw 0x07
		movwf OPTION_REG
		movlw 0x0E
		movwf ADCON1
		bsf TRISA,0
		bcf STATUS,RP0
		bcf STATUS,RP1
		clrf PORTC
		clrf PORTB
bucle
		btfss INTCON,2
		goto bucle
		bcf INTCON,2
		bsf ADCON0,2
espera
		btfsc ADCON0,2
		goto espera
		movf ADRESH,W
		;movf ADRESH,W
		movwf PORTB
		movf ADRESL,W
		movwf PORTC
		goto bucle
     	END
muchas gracias por su atensión y su ayuda
 
Última edición por un moderador:
Hola darwin, no vi detalladamente tu programa ya que trabajas con sistema hex a diferencia de mi que trabajo en sistema binario cuando trabajo directamente con registros de proposito especifico. Uno de tus problemas segun lo que vi puede deberse al tiempo de adquisicion necesario para la conversion. Luego de encender el conversor a/d debes hacer un retardo de unos 20 uS recomendablemente. Aunque tu programa parece hacerlo ya que hay muchas instrucciones luego del encendido del adc, pero aqui te paso la rutina que siempre utilizo con el lm35 para que compares. La he utilizado en 3 ocasiones, llevadas a campo y ha resultado.
Ahora te doy detalles de como lo hice. Primero trabajo con justificacion a la izquierda (utilizando el adresh), ya que asi no tengo problemas con los desbordes del adresl. ademas de eso, la referencia esta a 5 voltios por lo que dividi el resultado de la conversion entre 2 con un rrf por la sensibilidad del lm35.

confi bsf status,5
movlw b'10000101'
movwf adcon1
bcf status,5

conv_temp movlw b'11000001' ; Canal RA0, Oscilador interno, ADC Encendido
movwf adcon0
movlw .35 ; Espera de aprox. 20uSeg
movwf adc_cont
decfsz adc_cont,1
goto $-1
bsf adcon0,2 ; Inicio de conversion
btfss pir1,adif
goto $-1
bcf pir1,adif
movf adresh,0 ; Final de conversion
movwf adresh_r ; Guarda los valores en centena,decena y unidad
rrf adresh_r,w
movwf portc
return


PD: No estoy conectandome muy seguido. Si tienes alguna duda pasame un mensaje privado con la direccion del post y te respondo aqui en el foro. Saludos
 
Hola compañeros, soy nuevo en este foro y es por eso que quiero ingresar aportando algo.

He estado trabajando en la realización de un termómetro digital con visualización en lcd, ya he avanzado un poco en el tema y quiero compartirlo para ver en que me pueden colaborar para pulirlo mejor.

Yo programo en CCS y la simulación la hago en Proteus 7.5 sP3

el código es el siguiente,
Código:
// EINNER CRUZ //
// QUETAME, COLOMBIA//

#include <16F877.h>
#device *=16
#device adc=10
#fuses NOWDT,XT, NOPUT, PROTECT, NODEBUG, BROWNOUT, LVP, CPD, NOWRT
#use delay(clock=4000000)
#include <lcd.c>
#define hard_inc !input(PIN_B1)
#define harw_decr !input(PIN_B2)
#define enter !input(PIN_B3)

INT N1, N2, VAR1, VAR2, VAR3, VAR4, TEMP, entrar=0;


void harwd(void)
   {
    lcd_putc("\f     CONFIG  \n  TEMP ESTABLE");
    delay_ms(500);
    lcd_putc("\f   VMIN   VMAX  ");

    while(enter)
      {if(hard_inc)  VAR1++;
       if(harw_decr)  VAR1--;
       printf(lcd_putc,"\n  %d °C_  %d °C ",VAR1,VAR2);
       delay_ms(150);
      }
       delay_ms(150);

    while(enter)
      {if(hard_inc)  VAR2++;
       if(harw_decr)  VAR2--;
       printf(lcd_putc,"\n  %d °C  %d °C_ ",VAR1,VAR2);
       delay_ms(150);
      }
       delay_ms(150);

    lcd_putc("\f AL_VMIN AL_VMAX  ");
    printf(lcd_putc,"\n  %d °C   %d °C ",VAR3,VAR4);

    while(enter)
      {if(hard_inc)  VAR3++;
       if(harw_decr)  VAR3--;
       printf(lcd_putc,"\n %d °C_   %d °C ",VAR3,VAR4);
       delay_ms(150);
      }
       delay_ms(150);

    while(enter)
      {if(hard_inc)  VAR4++;
       if(harw_decr)  VAR4--;
       printf(lcd_putc,"\n %d °C   %d °C_ ",VAR3,VAR4);
       delay_ms(150);
      }
       delay_ms(150);

    lcd_putc("\f   FIN CONFIG  \n  TEMP ESTABLE");
    delay_ms(2000);
   }

void main(void)
   {setup_adc_ports(RA0_ANALOG);
   setup_adc(ADC_CLOCK_INTERNAL);
   setup_counters(RTCC_INTERNAL,RTCC_DIV_1);
   set_adc_channel(0);
   lcd_init();
   

   VAR1=20;
   VAR2=30;
   VAR3=15;
   VAR4=35;
   output_low(PIN_C0);
   output_low(PIN_C1);
   output_low(PIN_C2);


   while(1)
      {
      printf(lcd_putc,"\f  TEMP AMBIENTE ");
      TEMP=(int)read_adc()/2;
      if (TEMP>25)
      TEMP--;
      if (TEMP>65)
      TEMP--;
      printf(lcd_putc,"\n      %d °C ",TEMP);
      delay_ms(300);
      if(VAR1<TEMP<VAR2)
      {output_low(PIN_C0);
      output_low(PIN_C1);
      output_low(PIN_C2);}
      if(TEMP<VAR1)
      {output_high(PIN_C1);}
      if(TEMP<VAR3)
      {output_high(PIN_C2);
      delay_ms(400);}

      if(TEMP>VAR2)
      {output_high(PIN_C0);}
     
      if(harw_decr)
      harwd();
      }

   }


El programa realiza el muestreo de la temperatura y lo muestra en una lcd de 2x16, y a ciertas temperaturas que están definidas por defecto al inicio del programa prende o apaga calefactores o ventiladores según sea lo necesario, ademas tiene la opción de modificar esos rangos de temperatura con pulsadores, con el pin harw_decr(rb2) se ingresa al menú de configuración y allí se puede realizar el cambio.

Cualquier duda o aporte es bien recibida.

Espero que con el aporte de todos los interesados logremos adquirir muchos mas conocimientos sobre el tema.

por ultimo, quería plantearles una duda, como ven ya he trabajado con el ADC del pic pero la verdad no se cual es el tiempo de conversión de este, si alguien sabe se lo agradezco.

Hasta luego.
 

Adjuntos

  • proy_169.rar
    22.5 KB · Visitas: 1,569
Última edición por un moderador:
Hola amigos, como estan?

Tengo ganas de armar un medidor de carga de baterias de 12v para autos, el tema es que quiero hacerlo con el PIC16F84A y no se como programar el conversor A/D que tiene para poder realizar este proyectito. La idea simplemente es verificar el nivel de tensión que tiene la bateria que alimenta al circuito del pic, si el nivel de bateria es muy bajo (lo suficiente para no accionar a un par de reles de 12v), automaticamente haga una conmutación a una bateria de backup y que en ese momento accione el circuito de carga para la bateria que se descargo.
Bueno, si alguien tiene alguna información, se lo voy a agradecer! no pretendo que me pasen el circircuito y el programa, simplemente que me expliquen como funciona el conversor y veo si puedo programarlo.

Muchas gracias!
Cristian :).
 
hola disculpen, he realizado un medidor de temperatura con el conversor del micro que muestra en display, pero la muestra varia muy rapidamente entre valores aleatorios, y nose porq es, alguno sabe? le colocan otro hardware al conversor? si alguien tiene una solucion agradeceria q me ayude. gracias
 
El problema esta en el tiempo de muestreo que tienes, baja este tiempo y listo. No te va a dar ningun fallo en la medida ya que la temperatura no cambia bruscamente.
 
Hola darwin, no vi detalladamente tu programa ya que trabajas con sistema hex a diferencia de mi que trabajo en sistema binario cuando trabajo directamente con registros de proposito especifico. Uno de tus problemas segun lo que vi puede deberse al tiempo de adquisicion necesario para la conversion. Luego de encender el conversor a/d debes hacer un retardo de unos 20 uS recomendablemente. Aunque tu programa parece hacerlo ya que hay muchas instrucciones luego del encendido del adc, pero aqui te paso la rutina que siempre utilizo con el lm35 para que compares. La he utilizado en 3 ocasiones, llevadas a campo y ha resultado.
Ahora te doy detalles de como lo hice. Primero trabajo con justificacion a la izquierda (utilizando el adresh), ya que asi no tengo problemas con los desbordes del adresl. ademas de eso, la referencia esta a 5 voltios por lo que dividi el resultado de la conversion entre 2 con un rrf por la sensibilidad del lm35.

Código:
confi    bsf    status,5
    movlw    b'10000101'
     movwf    adcon1
    bcf    status,5

conv_temp    movlw    b'11000001' ; Canal RA0, Oscilador interno, ADC Encendido
    movwf    adcon0
    movlw    .35        ; Espera de aprox. 20uSeg
    movwf    adc_cont
    decfsz    adc_cont,1
    goto    $-1
    bsf    adcon0,2        ; Inicio de conversion
    btfss    pir1,adif
    goto    $-1
    bcf    pir1,adif
    movf    adresh,0        ; Final de conversion
    movwf    adresh_r        ; Guarda los valores en centena,decena y unidad
    rrf    adresh_r,w
    movwf    portc
    return



PD: No estoy conectandome muy seguido. Si tienes alguna duda pasame un mensaje privado con la direccion del post y te respondo aqui en el foro. Saludos

hola yo tengo un problema con el ADC del 77A. Al haber configurado todo cual como lo dice el datasheet al leer los valores el los registros ADRESH y ADRESL usando la justificacion a la izquierda veo que solo puedo los 8 bits mas significativos que carga ADRESH pero no los 2 bis menos significativos del ADRESHL, y si justifico a la derecha puedo ver los 2 bits mas significativos del ADRESH mas los 8 restantes no me los muestra el ADRESHL.

Quisiera que me ayudara para poder seguir con mi proyecto ya que este ADC va incluido en el.
aca le dejo mi codigo para ver si quizas usted me pueda corrregir.

Código:
    List    p=16f877A
        Include <P16f877A.inc>
        radix hex


reg1    equ 21h
reg2    equ 22h
bajos    equ 23h
altos    equ 24h
H        equ 0x1e
L        equ 0x1e

        org 0x00
        goto    inicio
        org 0x04
        call retard
        bcf  PIR1,6         ; ADIF = 0
        retfie
        

    
inicio    bsf    STATUS,5    ; entro al banco 1
        bcf STATUS,6
        movlw b'00000001' ; RA0 entrada el resto salida 
        clrf TRISB          ; salida
        clrf TRISC          ; Salida
        clrf TRISD          ; salida
        movlw b'100'      ; RE0, RE1 salidas, RE2 entrada
        movwf TRISE
empieza    movlw b'01001110' ;justifico hacia la izquierda
        movwf ADCON1
        bcf STATUS,5       ;voy al banco 0
        bcf STATUS,6
        movlw b'11000001'; activo el reloj interno del pic
        movwf ADCON0     ; RA0 entrada analogica y activar el modulo de conversion.
        bcf PIR1,6         ; ADIF = 0
        bsf INTCON,6     ; PEIE = 1
        bsf INTCON,7     ; GIE = 1
        bsf STATUS,5     ;         banco 1
        bcf STATUS,6
        bsf PIE1,6         ; ADIE = 1
        

        call retardo      ; tiempo para adquisición
        bcf STATUS,5     ;banco 0
        bcf STATUS,6
        clrf PORTB
        clrf PORTC         ; salida de datos
        clrf PORTD
        clrf PORTE
ini_ADC    bsf    ADCON0,2     ; comienza la conversión
        btfsc ADCON0,2     ; termino la conversión?
        goto $-1             ; No

        bsf    STATUS,5     ; Banco 1
        movf L,0     ; paso los 2 bits mas significativos a W
        movwf bajos
                 ; W a reg3 
        bcf STATUS,5     ; Banco 0
        movf H,0     ; cargo los 7 bits mas significativos a W
        movwf altos         ; W areg4
        movwf PORTB
        movf bajos,0
        movwf PORTE
        call retardo
        goto ini_ADC

retardo movlw 09h          ; .. 40 microseg
        movwf reg1
otravez decfsz reg1,1
        goto otravez
        return

retard    movlw 08h          ; .. 40 microseg
        movwf reg2
repite  decfsz reg2,1
        goto repite
        return

        END
 
Última edición por un moderador:
saludos a todos
quisiera saber cual es el voltaje minimo de entrada en el puertoa y en los demas puertos..
sucede que debo digitalizar uan señal proveniente de un antena que trabaja a una frecuencia de 1GHz y no se como conectar esa señal al pic para digitalizarla, me podrian colaborar con eso?....si no esta claro lo que quiero hacer diganmelo
 
Hola que tal a todos espero que alguien me pueda ayudar con lo que estoy haciendo...para comenzar utilizo un lenguaje BASIC del PIC SIMULAOR IDE...
Mi problema es el siguiente:::

Tengo un pwm de 25Khz, lo estoy variando con el puertos RA0

Lo que estoy haciendo es tomar una señal de referencia de 0 a 5volts con un potenciometro.. lo meto al convertidor A/D.. pero obtengo un valor de 10 bits.. como le hago para introducir ese valor en el pwm.....

Lo que hago es copiar del registro ADRESL en CCPR1L y los otros 2 bit que estan en ADRESH los copio al CCP1CON pero al variar el potenciometro me despliega tres veces el pwm

Dicho de otra manera:
comienzo a girar el potenciometro y comienza el pulso desde cero hasta un valor maximo.. al seguir variando el potenciometro, el pulso comienza nuevamente desde cero y va hasta su valor maximo.. asi lo hace hasta 4 veces hasta que el potenciometro llega hasta el final...

yo quiero que lo haga solo una vez.... T_T

aki esta el programa:
--------------------------------------------------------------
Dim conversion As Word


ADCON0 = %10000000 'RA0 entrada analogica,clock A/D Fosc/8
ADCON1 = %10001110 'RA0 analogico ,RA1:RA7 E/S digitales
'6 bits d mas peso ADRESH a '0'

PR2 = 39
CCP1CON = %00001100 'CCP1 a modulo PWM

pwm:
WaitUs 50
Adcin 0, conversion
CCPR1L = ADRESL '8 bits LSB del Ciclo de Trabajo

CCP1CON.5 = ADRESH.0 '2 bits menos significativos
CCP1CON.4 = ADRESH.1 'del Ciclo de Trabajo

TRISC.2 = 0

T2CON = 0x04 'prescaler 1:1 y ativacion del TMR2
WaitUs 50
Goto pwm
End
 
Hola, me interesa mucho tu código. Necesito algo parecido. Estoy intentando hacer un termómetro con un LM35 pero aprovechando los 10 bits de resolución. Me interesa tener el resultado en formato tal que tenga Unidad, Decena y Centena para sacarlo por a 3 displays de 7 segmentos. Creo tu código va por ahí.
Te agradecería que me pudieras ayudar.
 
Atrás
Arriba