Autor Tema: 16f870 como conversor AD (Analogo digital)  (Leído 3905 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado catk

  • PIC10
  • *
  • Mensajes: 13
16f870 como conversor AD (Analogo digital)
« en: 10 de Mayo de 2007, 11:03:02 »
Cordial saludo a todos, spy nuevo en este foro y espero poder aportar muchas cosas.

Hoy necesito una ayudita: Estoy intentado crear un conversor A/D con el PIC 16F870, creo que ya logre hacer la conversion pero ahora no se como hacer para que por ejemplo cuando reciba 3v por la entrada analoga me active el puerto RB0 (Por ejemplo), y cosas por este estilo es lo que necesito hacer, pero la verdad no lo he logrado, dejo el codigo en assembler que llevo hasta el momento.

p=16f870
   include <p16f870.inc>
numero   equ   0x26
   org   0x000
   goto   Start
   org   0x004

   Interrupt
   retfile

Start
   bsf   STATUS,RP0
   clrf   PORTB
   bcf   STATUS,RP1

   movlw   H'00'
   movwf   TRISC      ;Configuro los puertos de salida
   clrf   ADCON1
   bcf   STATUS,RP0
   movlw   B'01000001'
   movwf   ADCON0

Main
   call   ad_portc
   goto   Main

ad_portc
   bsf   ADCON0,GO   ;Espero que termine de leer datos
Wait
   btfsc   ADCON0,GO
   goto   Wait
   
   movf   ADRESH,W
   movwf   PORTC
   
   end   



Gracias por la ayuda que me puedan dar.

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5474
    • Electrónica Didacta
Re: 16f870 como conversor AD (Analogo digital)
« Respuesta #1 en: 10 de Mayo de 2007, 12:20:32 »
Hola catk

con una resta puedes comparar el dato obtenido del ADRES (dependiendo de la justificación)

3 volts con una +vref = 5 y -vref = gnd -> 3 * 1023 / 5 ~ 614 pasos almacenados

restas este literal a ADRES(H:L) y mediante los bits Z, C puedes averiguar si es igual

PD: tengo que repasar asm , jeje ya me acostumbré al C  :?
La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado maunix

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4751
    • Mi Sitio Web Personal
Re: 16f870 como conversor AD (Analogo digital)
« Respuesta #2 en: 10 de Mayo de 2007, 12:43:31 »
Dependiendo de la precisión que necesites.  Si necesitas una precisión del orden de los 20mV entonces el modo 8 bits te va a funcionar muy bien y simplemente sería comparar el ADRESH con una constante a determinar de acuerdo al voltaje que quieras comprobar.

- La soberbia de un Einstein es entendible.. la de un salame es intolerable (A.Dolina)
- En teoría no hay diferencia entre la teoría y la práctica. En la práctica... si la hay.
- Lee, Lee, Lee y luego pregunta.(maunix)
- Las que conducen y arrastran al mundo no son las máquinas, sino las ideas (V. Hugo)
- Todos los hombres se parecen por sus palabras; solamente las obras evidencian que no son iguales.(Moliere)
- Todo debería ser hecho tan simple como sea posible pero no mas simple que eso.(A.Einstein)

Desconectado microcom

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 568
Re: 16f870 como conversor AD (Analogo digital)
« Respuesta #3 en: 10 de Mayo de 2007, 14:46:20 »
la salida digital para 3000mv = 1001100110
adresl=01100110
adresH=10
si la justificacion es por la derecha   

JUSTIFICACION LOS OCHO PRIMEROS BITS DE ADRESL Y DOS BITS ADREESH

si comparas estos resultados con una variable podras saber si hay 3 voltios en la entrada.

es solo un paso muy emparapetado de principios; que  muy poco utlizan puesto que hay formas mas elegantes que  hacer esta funcion.

tambien depende la presicion.
para el de maunix se necesitaria la justificacion a la izquierada,
saludos 
« Última modificación: 10 de Mayo de 2007, 14:50:45 por microcom »

Desconectado catk

  • PIC10
  • *
  • Mensajes: 13
Re: 16f870 como conversor AD (Analogo digital)
« Respuesta #4 en: 10 de Mayo de 2007, 18:20:11 »
Cordial saludo.

Gracias a todos y ahi voy avanzando....

Les cuento:

Conecte una pantalla LCD para al PIC para mirar que me esta entrando, pero no se que problema tengo con las decenas, o depronto el problema es general ya que los datos me estan pàsando por el LCD pero no veo concordancia alguna con lo que me esta entrando el codigo que llevo es:

Código: [Seleccionar]
; Febrero 6, 4:42 pm
   list   P=16F870
   #include <P16F870.inc>      ; Registros del PIC16F876A
;/////////////////////////////////////////////////////////////////////////////
   __CONFIG    _CP_OFF & _WDT_OFF & _XT_OSC & _PWRTE_ON & _LVP_OFF & _BODEN_OFF
;/////////////////////////////////////////////////////////////////////////////
; Constantes
;Bancos de memoria RAM (para utilizar banksel)
Banco0   equ   0x20
Banco1   equ   0xA0
Banco2   equ   0x120
Banco3   equ   0x1A0
estado equ 0x03
uni equ 0x21
dec equ 0x22
cen equ 0x23
ptob equ 0x06
buffer equ 0x28


#define CARRY estado,0
#define RPT0 estado,5
E_LCD      equ   7   ;Bit del puerto C para control de E.
RW_LCD       equ   6    ;Bit del puerto C para control de R/W.
RS_LCD      equ   5   ;Bit del puerto C para control de RS.
LCD_Dat      equ   0x06   ;Bus de datos del LCD = PORTB
LCD_Ins      equ   0x07   ;Bus de Control del LCD = PORTC
;/////////////////////////////////////////////////////////////////////////////
TEMPB3      equ   0x21
TEMPB2      equ   0x22
TEMPB1      equ   0x23
;/////////////////////////////////////////////////////////////////////////////

   Org   0x00
   goto   main

main   
   clrf   INTCON
   BANKSEL   Banco1      ; Bank1 seleccionado
   clrf   TRISC     
   clrf   TRISB      ; PORTB = Salidas
   clrf   ADCON0
   bcf    STATUS, RP0
   ;movlw  B'01000001'
   ;movwf  ADCON0

   movlw   b'10000001'
   movwf   ADCON0
; Set ADCON1
   ;BANKSEL ADCON1
   ;movlw   b'10000101'
   ;movwf   ADCON1


   BANKSEL   Banco0      ; Bank0 seleccionado
   clrf   PORTC
   clrf   PORTB
   call inicio

Leer
   call   ad_portc
   goto   Leer

ad_portc
   bsf    ADCON0,GO

Wait
btfsc   ADCON0,GO
goto Wait

; bsf RPT0
movf ADRESH,W
;bcf RPT0

movwf buffer ;Guarda el dato obtenido de ADRESL en el buffer temporal
bcf CARRY ;Limpia el CARRY
btfsc ADRESH, 0 ;Mira el bit menos significativo de ADRESH (Bit 8)
bsf CARRY ;Si está en 1 pone en uno el carry
rrf buffer, 1 ;Hace desaparecer el bit 0 de ADRESL, mete el bit 0 de ADRESH por el 7 de ADRESL

movf buffer, 0 ;Dato digitalizado -> W
call DECIMAL ;Obtiene UNI, DEC y CEN con el agregado de 30h para la tabla ASCII


movf dec,0
call   LCD_printchar

;call   LCD_printchar
movf cen, 0 ;Coloca las decenas
call   LCD_printchar

;call   LCD_printchar
movf uni, 0 ;Coloca las unidades
call   LCD_printchar

call   DelaymS
call   DelaymS
call   BorrarDisplay_LCD
call   DelaymS
call   DelaymS
movf   cen,0
movwf LCD_Dat
bcf      LCD_Ins,RW_LCD 
bsf    LCD_Ins,RS_LCD 
bsf    LCD_Ins,E_LCD   
bcf    LCD_Ins,E_LCD   

call   DelaymS
call   DelaymS
call   DelaymS
call   DelaymS
call   DelaymS
call   BorrarDisplay_LCD

; movlw   "E"
; call   LCD_printchar
; call   DelaymS
; call   DelaymS
return

DECIMAL movwf uni ;Convierte el dato presente en W en UNI, DEC y CEN
clrf dec
clrf cen
movlw d'100' ;Determina la cant. de centenas
CENTENA subwf uni, 1
btfss CARRY
goto CIEN
incf cen, 1
goto CENTENA
CIEN addwf uni, 1
movlw d'10' ;Determina la cant. de decenas
DECENA subwf uni, 1
btfss CARRY
goto DIEZ
incf dec, 1
goto DECENA
DIEZ addwf uni, 1 ;Uni queda con la cant. de unidades (sin decenas ni centenas)

movlw 0x30 ;Le suma 30h a los valores de UNI, DEC y CEN para que queden en ASCII
addwf uni, 1
movlw 0x30
addwf dec, 1
movlw 0x30
addwf cen, 1

return

inicio
   call   Configurar_LCD
   call   BorrarDisplay_LCD
   call   CursorOn_LCD
   call   InicioL1_LCD
   ;movlw   .2
;   call   DelayS

;   movlw   "T"
;   call   LCD_printchar
;   movlw   "E"
 ;  call   LCD_printchar
;   movlw   "I"
   ;call   LCD_printchar
   ;movlw   "K"
   ;call   LCD_printchar
   ;movlw   "O"
   ;call   LCD_printchar
   ;movlw   " "
   ;call   LCD_printchar
   ;movlw   "S"
   ;call   LCD_printchar
   ;;movlw   "."
   ;call   LCD_printchar
   ;movlw   "A"
   ;call   LCD_printchar


;fin
;   nop
;   goto   fin




;/////////////////// Subrutinas ///////////////////

Configurar_LCD
   movlw   .10
   call   DelaymS
   movlw   0x38
   call   LCD_Instruccion
   movlw   .1
   call   DelaymS
   return 

CursorOn_LCD
   movlw   0x0F
   call   LCD_Instruccion
   movlw   .1
   call   DelaymS
   return

CursorOff_LCD
   movlw   0x0C
   call   LCD_Instruccion
   movlw   .1
   call   DelaymS
   return

BorrarDisplay_LCD
   movlw   0x01
   call   LCD_Instruccion
   movlw   .3
   call   DelaymS
   return

InicioL1_LCD
   movlw   .128
   bcf      LCD_Ins,RW_LCD   
    bcf      LCD_Ins,RS_LCD   
    bsf    LCD_Ins,E_LCD   
   movwf   LCD_Dat
   bcf      LCD_Ins,E_LCD
   movlw   .1
   call   DelaymS
   return

InicioL2_LCD
   movlw   .168
   bcf      LCD_Ins,RW_LCD   
    bcf      LCD_Ins,RS_LCD   
    bsf    LCD_Ins,E_LCD   
   movwf   LCD_Dat
   bcf      LCD_Ins,E_LCD
   movlw   .1
   call   DelaymS
   return

LCD_printchar
   bcf      LCD_Ins,RW_LCD 
    bsf    LCD_Ins,RS_LCD 
    bsf    LCD_Ins,E_LCD   
    movwf    LCD_Dat     
   bcf    LCD_Ins,E_LCD   
    movlw   0x01
   call   DelaymS     
   return       

LCD_Instruccion
   bcf      LCD_Ins,RW_LCD   
    bcf      LCD_Ins,RS_LCD   
    bsf    LCD_Ins,E_LCD   
    movwf    LCD_Dat     
    bcf    LCD_Ins,E_LCD   
    return       

DelayS
   movwf   TEMPB3
   movlw   .250
   call   DelaymS
   movlw   .250
   call   DelaymS
   movlw   .250
   call   DelaymS
   movlw   .250
   call   DelaymS
   decfsz   TEMPB3,F
   goto   $-9
   return

DelaymS   
   movwf   TEMPB1
   movlw   .249
   movwf   TEMPB2
   nop
   decfsz   TEMPB2,F
   goto   $-2
   decfsz   TEMPB1,F
   goto   $-6
   retlw   .0



   end



Como ven antes de hacer de nuevo una lectura le meti delay para que el tiempo de refresco del LCD me permita leer, pero como les comento no ahi concordancia entre la entrada y lo que me muestra el LCD, aclarando como les comento que las decenas NO me esta mostrando nada.

Gracias de nuevo a todos

Desconectado maunix

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4751
    • Mi Sitio Web Personal
Re: 16f870 como conversor AD (Analogo digital)
« Respuesta #5 en: 10 de Mayo de 2007, 20:34:24 »
Amigo, te sugiero que vayamos atacando un problema por vez.

En la forma que lo expones, no sabemos si no anda el hardware del A/D , si no anda la rutina de HEX a BCD, o si no anda la rutina del display LCD o bien si no está mal cableado el LCD.

Más allá de eso, ¿qué quieres hacer con esta parte del código?


   movwf   buffer      ;Guarda el dato obtenido de ADRESL en el buffer temporal
   bcf   CARRY      ;Limpia el CARRY
   btfsc   ADRESH, 0   ;Mira el bit menos significativo de ADRESH (Bit 8)
   bsf   CARRY      ;Si está en 1 pone en uno el carry
   rrf   buffer, 1   ;Hace desaparecer el bit 0 de ADRESL, mete el bit 0 de ADRESH por el 7 de ADRESL

   movf   buffer, 0   ;Dato digitalizado -> W
   call   DECIMAL      ;Obtiene UNI, DEC y CEN con el agregado de 30h para la tabla ASCII


No veo porque guardas el contenido de ADRESH en buffer , además luego dices que verificas el bit menos significaivo (bit 8) y en realidad verificas el bit 0 (que sí es el menos significativo).

no veo el sentido a lo que haces y precisamente tal vez estés moviendo todo un lugar a la derecha! (que equivale a dividir por 2) y por eso nunca verás valores mayores a 2.5V

Saludos
- La soberbia de un Einstein es entendible.. la de un salame es intolerable (A.Dolina)
- En teoría no hay diferencia entre la teoría y la práctica. En la práctica... si la hay.
- Lee, Lee, Lee y luego pregunta.(maunix)
- Las que conducen y arrastran al mundo no son las máquinas, sino las ideas (V. Hugo)
- Todos los hombres se parecen por sus palabras; solamente las obras evidencian que no son iguales.(Moliere)
- Todo debería ser hecho tan simple como sea posible pero no mas simple que eso.(A.Einstein)

Desconectado catk

  • PIC10
  • *
  • Mensajes: 13
Re: 16f870 como conversor AD (Analogo digital)
« Respuesta #6 en: 10 de Mayo de 2007, 20:41:03 »
Hola y gracias por tu respuesta.

Vale vamos por pasos, lo que quiero hacer en primera instancia es que el dato leido por analogo me lo muestre en el LCD,

Y con respecto a tu pregunta ahi tomo el valor de ADRESH para manupularlo osea ese valor lo paso a la subrutina DECIMAL que me separa en unidades, decenas y sentenas que luego envio al LCD (O por lo menos en teoria eso es lo que intento hacer).

Gracias por su ayuda.

Desconectado microcom

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 568
Re: 16f870 como conversor AD (Analogo digital)
« Respuesta #7 en: 10 de Mayo de 2007, 22:16:12 »

Desconectado catk

  • PIC10
  • *
  • Mensajes: 13
Re: 16f870 como conversor AD (Analogo digital)
« Respuesta #8 en: 11 de Mayo de 2007, 10:35:35 »
Hola microcon, te agradezco la ayuda que me estas dando.


Te cuento que mire tu codigo pero toy perdido. Me remito a mi codigo de nuevo para mirar lo siguiente:

ad_portc
   bsf    ADCON0,GO

Wait
   btfsc   ADCON0,GO
   goto   Wait
   
;   bsf   RPT0
   movf   ADRESH,W
   ;bcf   RPT0

   movwf   buffer      ;Guarda el dato obtenido de ADRESL en el buffer temporal
   bcf   CARRY      ;Limpia el CARRY
   btfsc   ADRESH, 0   ;Mira el bit menos significativo de ADRESH (Bit 8)
   bsf   CARRY      ;Si está en 1 pone en uno el carry
   rrf   buffer, 1   ;Hace desaparecer el bit 0 de ADRESL, mete el bit 0 de ADRESH por el 7 de ADRESL

   movf   buffer, 0   ;Dato digitalizado -> W
   call   DECIMAL      ;Obtiene UNI, DEC y CEN con el agregado de 30h para la tabla ASCII


Aqui lo que hago es tomar la lectura por la entrada analoga, y pasarla a la rutina DECIMAL para separar unidades, decenas y centenas para luego imprimirlas en el LCD, que parte de este paso tengo mal????


Gracias por tu ayuda!

Desconectado catk

  • PIC10
  • *
  • Mensajes: 13
Re: 16f870 como conversor AD (Analogo digital)
« Respuesta #9 en: 11 de Mayo de 2007, 12:14:35 »
Ayudaaa :'(
Nada que me cuadra, intente hacer esto y nada:

Wait
   btfsc   ADCON0,GO
   goto   Wait
   
   movf   ADRESH,W
   addwf   0x30,0      ;Le suma 30h a los valores recibidos por la entrada analoga para mostrarlo en el display
   call   LCD_printchar
   movlw   "D"
   call   LCD_printchar
   call   DelaymS
   call   DelaymS
   call   BorrarDisplay_LCD

Lo que intento hacer es que el dato RECIBIDO por ADRESH me lo saque por el LCD

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5474
    • Electrónica Didacta
Re: 16f870 como conversor AD (Analogo digital)
« Respuesta #10 en: 11 de Mayo de 2007, 13:18:56 »
Hola catk

una pregunta:

¿ya probaste solo la parte del CAD?

¿te funcionó?

como una sugerencia, deberias primero resolver si está bien lo del convertidor, puedes hacer que el resultado te lo envíe a un puerto y pegas varios led´s para confirmar

luego te pasas a la parte del LCD


La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado catk

  • PIC10
  • *
  • Mensajes: 13
Re: 16f870 como conversor AD (Analogo digital)
« Respuesta #11 en: 11 de Mayo de 2007, 18:31:18 »
Hola de nuevo.

Bueno en mi intento por probar intente correr este codigo y me funciona diria a medias. Me van encendiendo en serie los LEDS pero aumenta o disminuye la intensidad de los mismos, esta bien que hagan eso???

El codigo es:

Código: [Seleccionar]
        __config _LVP_OFF & _XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF & _BODEN_OFF
& _DEBUG_OFF
        list p=16f877

        include "p16f877.inc"

        ; Start at the reset vector
        org     0x000
        goto    Start
        org     0x004
Interrupt
        retfie
Start
        bsf     STATUS,RP0      ;bank 1
        bcf     STATUS,RP1
        movlw   H'00'
        movwf   TRISC           ;portc [7-0] outputs
        clrf    aDCON1          ;left justified, all inputs a/d
        bcf     STATUS,RP0      ;bank 0
        movlw   B'01000001'     ;Fosc/8 [7-6], A/D ch0 [5-3], a/d on [0]
        movwf   aDCON0
Main
        call    ad_portc
        goto    Main


ad_portc
                                ;wait for acquision time (20uS)
                                ;(non-critical for this test)

        bsf     aDCON0,GO       ;Start A/D conversion
Wait
        btfsc   aDCON0,GO       ;Wait for conversion to complete
        goto    Wait

        movf    ADRESH,W        ;Write A/D result to PORTC
        movwf   PORTC           ;LEDs
        return

        end


Gracias a todos por la ayuda!

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: 16f870 como conversor AD (Analogo digital)
« Respuesta #12 en: 12 de Mayo de 2007, 20:46:12 »
Tal vez te falten resistencias limitadoras entre los pines del PIC y los LEDS. Es sólo una suposición. No he mirado el código.

Saludos.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.


 

anything