Foros de Electrónica

Comunidad de discusión sobre Automatización, Electrónica industrial, Microcontroladores y electrónica digital, Robótica, Domótica, Telemática, Tecnologías móviles, y muchos temas más.




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


       



#1  Programa de conversión A/D con Pic 16f877
canales
Ubicación: Managua, Nicaragua
Registrado: 29 Dic 2006
Mensajes: 121
citar
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é.


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.

#2  es lento hacerlo funcionar
carlosxyz
Ubicación: mexico DF
Registrado: 19 Feb 2007
Mensajes: 8
citar
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.

#3  conversion a/d
Jairo
Ubicación: Quito Ecuador
Registrado: 14 Feb 2007
Mensajes: 64
citar
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

#4  
canales
Ubicación: Managua, Nicaragua
Registrado: 29 Dic 2006
Mensajes: 121
citar
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:

********************************************************************************

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.

#5  rutina adc
sromeros
Ubicación: mexico
Registrado: 07 Sep 2006
Mensajes: 8
citar
hola espro te sirva me avisas si te sirvio

saludos desde mexico

#6  Ayuda!!!
JuantoHdez
Registrado: 21 Nov 2006
Mensajes: 1
citar
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...

#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);
}

#7  
PunkistaN
Ubicación: Ibagué, Colombia
Registrado: 10 Ago 2007
Mensajes: 8
citar
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

#8  
ghost_007
Registrado: 31 Jul 2007
Mensajes: 17
citar
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.

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 xD

#9  Lm35 con PIC16F877A en LCD 16x2
ivan_ambriz
Ubicación: Guadalajara, Mexico
Registrado: 18 Ene 2008
Mensajes: 4
citar
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:

'****************************************************************
'* 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.
Archivos Adjuntos

Este mensaje contiene archivos adjuntos, para verlos debes estar registrado.

#10  
darwin2010
Ubicación: Colombia
Registrado: 26 Dic 2008
Mensajes: 1
citar
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

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 atencion y su ayuda

 Responder



 Otros temas de interés 
No hay mensajes nuevos Como separar señales, si son entrada y salida de datos
No hay mensajes nuevos Circuito acondicionador de entrada 4-40mA y salida 0-10 V
No hay mensajes nuevos Entrada/Salida de audio a traves de USB
No hay mensajes nuevos Conectar salida video de camara a monitor video
No hay mensajes nuevos Circuito con reles para puerto paralelo con salida de 3.3v

Foros de Electronica
|| Cuestiones Elementales de Electrónica || Fuentes de alimentacion || Circuitos de radio || Diseño de circuitos en general ||
|| Sistemas de Audio: Preamplificadores, Ecualizadores || Amplificadores || Reparación || Discusión ||
|| Microcontroladores y sistemas embebidos || Circuitos logicos combinacionales y secuenciales || Interfaces y Programacion || Dudas en general || Sistemas de Video || PC Hardware || Telematica y comunicaciones || Tecnologias moviles || Software Electronico || Robotica, Domotica y Mecatronica || Autotrónica || Automatizacion, Electronica industrial y de Potencia || Documentacion, circuitos y esquemas || Donde Las Ideas Convergen... || Tutoriales y Manuales || Proyectos Prácticos ||
Contacto | Acerca de | Ayuda | Normas de la Comunidad | Privacidad | Mapa de los foros
© Foros de Electrónica - Comunidad Internacional de Electrónicos