Autor Tema: voltimetro convertirlo a amperimetro en asm pic16f887  (Leído 6224 veces)

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

Desconectado piccero

  • PIC10
  • *
  • Mensajes: 2
voltimetro convertirlo a amperimetro en asm pic16f887
« en: 02 de Noviembre de 2010, 18:25:14 »
amigos necesito ayuda tengo este proyecto ala mitad tendo que pasar este voltimetro a amperimetro ya le cambie las variables un poco no se como terminarla con ley de ohm ayuda hay les va el codigo en asm


;**********************************************************************
;   This file is a basic code template for assembly code generation   *
;   on the PIC16F887. This file contains the basic code               *
;   building blocks to build upon.                                    *
;                                                                     *
;   Refer to the MPASM User's Guide for additional information on     *
;   features of the assembler (Document DS33014).                     *
;                                                                     *
;   Refer to the respective PIC data sheet for additional             *
;   information on the instruction set.                               *
;                                                                     *
;**********************************************************************
;                                                                     *
;    Filename:       xxx.asm                                           *
;    Date:                                                            *
;    File Version:                                                    *
;                                                                     *
;    Author:                                                          *
;    Company:                                                         *
;                                                                     *
;                                                                     *
;**********************************************************************
;                                                                     *
;    Files Required: P16F887.INC                                      *
;                                                                     *
;**********************************************************************
;                                                                     *
;    Notes:                                                           *
;                                                                     *
;**********************************************************************


   list      p=16f887   ; list directive to define processor
   #include   <p16f887.inc>   ; processor specific variable definitions


; '__CONFIG' directive is used to embed configuration data within .asm file.
; The labels following the directive are located in the respective .inc file.
; See respective data sheet for additional information on configuration word.

   __CONFIG    _CONFIG1, _LVP_OFF & _FCMEN_ON & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & _MCLRE_ON & _PWRTE_ON & _WDT_OFF & _XT_OSC
   __CONFIG    _CONFIG2, _WRT_OFF & _BOR21V



;***** VARIABLE DEFINITIONS
;***** VARIABLE DEFINITIONS
w_temp        EQU     0x7E        ; variable used for context saving
status_temp   EQU     0x7F        ; variable used for context saving

VAR1         EQU      0X20
VAR2         EQU      0X21
COSI         EQU      0X22

L_8X8         EQU      0X23
H_8X8         EQU      0X24

N1_L         EQU      0X25
N1_H         EQU      0X26
N2_L         EQU      0X27
N2_H         EQU      0X28
N3_L         EQU      0X29
N3_H         EQU      0X2A
BK1_H         EQU      0X2B
BK1_L         EQU      0X2C
BK2_H         EQU      0X2D
BK2_L         EQU      0X2E
BK3_H         EQU      0X2F
BK3_L         EQU      0X30
INDI_H         EQU      0X31
INDI_L         EQU      0X32
COCI_H         EQU      0X33
COCI_L         EQU      0X34
FLAGS         EQU      0X35
UNI            EQU      0X36
DEC            EQU      0X37
CEN            EQU      0X38
MIL            EQU      0X39
DECMIL         EQU      0X3A
CONV_H         EQU      0X3B
CONV_L         EQU      0X3C
WREG_H         EQU      0X3D      ;BYTE ALTO DE WREG
STACK_1H      EQU      0X3E
STACK_1L      EQU      0X3F
STACK_2H      EQU      0X40
STACK_2L      EQU      0X41
STACK_3H      EQU      0X42
STACK_3L      EQU      0X43
STACK_4H      EQU      0X44
STACK_4L      EQU      0X45
STACK_5H      EQU      0X46
STACK_5L      EQU      0X47
WREG_H_TEMP      EQU      0X48
WREG_L_TEMP      EQU      0X49
WREG_L         EQU      0X4A

CONT         EQU      0x4B
CONT2         EQU      0x4C
LCDATA         EQU      0X4D

;********* DEFINICIONES DE BANDERAS *************
EN      EQU      0X00
RS      EQU      0X01

CARRY   EQU      0X00



;**********************************************************************
      ORG     0x000             ; processor reset vector
      clrf    PCLATH            ; ensure page bits are cleared
        goto    main              ; go to beginning of program


      ORG     0x004             ; interrupt vector location
      movwf   w_temp            ; save off current W register contents
      movf   STATUS,w          ; move status register into W register
      movwf   status_temp       ; save off contents of STATUS register


; isr code can go here or be located as a call subroutine elsewhere


      movf    status_temp,w     ; retrieve copy of STATUS register
      movwf   STATUS            ; restore pre-isr STATUS register contents
      swapf   w_temp,f
      swapf   w_temp,w          ; restore pre-isr W register contents
      retfie                    ; return from interrupt



main
      BANKSEL   ANSEL
      MOVLW   B'00000001'         ;RA0-RA3 TODOS ANALOGOS
      MOVWF   ANSEL      

      BANKSEL   ANSELH
      MOVLW   B'00000000'         ;RB0-RB7 TODOS DIGITALES
      MOVWF   ANSELH      

      BANKSEL   ADCON1
      MOVLW   B'10000000'         ;JUSTIFICACION A LA DERECHA, VREF EN TIERRA Y FUENTE
      MOVWF   ADCON1

      BANKSEL   ADCON0            ;encender el analogo digital
      MOVLW   B'10000001'         ;FOSC/32, CH0, DONE, ACD ON
      MOVWF   ADCON0


      BANKSEL TRISA
      MOVLW   B'00000001'         ;puerto A y el resto en ceros, hay que ponerlo de entrada en el tirsa
      MOVWF   TRISA            ;LOS 4 BITS DE MENOR PESO DE ENTRADA PARA LUEGO SER ANALOGOS

      CLRF   TRISB         ;PONGO TODOS LOS TRIS DE SALIDA EN EL PUERTO B
 

      BANKSEL   ADCON0

      MOVLW   B'10000001'         ;FOSC/32, CH0, DONE, ACD ON
      MOVWF   ADCON0
      BSF      ADCON0,GO_DONE      ;INICIO UNA CONVERSIÓN A/D

      BANKSEL   PORTA

      MOVLW   .255
      CALL   RETARDOTE
      MOVLW   .255
      CALL   RETARDOTE
      MOVLW   .255
      CALL   RETARDOTE
      MOVLW   .255
      CALL   RETARDOTE
      MOVLW   .255
      CALL   RETARDOTE

      CALL   INIT_LCD
      CALL   MENSAJE_TERMOMETRO
   
      MOVLW   .255
      CALL   RETARDOTE
      MOVLW   .255
      CALL   RETARDOTE
      MOVLW   .255
      CALL   RETARDOTE
      MOVLW   .255
      CALL   RETARDOTE
      MOVLW   .255
      CALL   RETARDOTE
      MOVLW   .255
      CALL   RETARDOTE
      MOVLW   .255
      CALL   RETARDOTE
      MOVLW   .255
      CALL   RETARDOTE
      MOVLW   .255
      CALL   RETARDOTE
      MOVLW   .255
      CALL   RETARDOTE

      CALL   BORRAR

LOOP_PRINCIPAL      ;se tiene que poner en cero
      BTFSC   ADCON0,GO_DONE
      GOTO   NO_DATA
SI_DATA   
      BSF      ADCON0,GO_DONE      ;INICIO OTRA CONVERSIÓN ADC

      ;se pone el watch con: stack_1h, 1l.2l,2h,3l,3h,4l,4h, adresh 0x01, adresl0xff, wre_h, wreg_l, wreg
      MOVF   ADRESH,W
      MOVWF   WREG_H
      BSF      STATUS,RP0
      MOVF   ADRESL,W
      BCF      STATUS,RP0
      MOVWF   WREG_L         ;CARGO EL DATO QUE OBTENDO DEL ADC EN WREG 16 BITS
      CALL   PUSH_2_STACK   ;LO ENTRO A LA PILA

      CALL   ADC_2_VOLT      ;CONVIERTO A VOLTAJE EN BCD (REVISAR REGISTROS DECMIL, MIL ETC)

      CALL   BORRAR

      ;MOVF   DECMIL,W      ;TOMO EL DATO QUE HAYA EN EL REGISTRO, LO PASO A ASCII Y LO ENVIO DE UNA AL LCD
      ;ADDLW   0X30
      ;CALL   LCDD      

      ;MOVF   MIL,W      ;TOMO EL DATO QUE HAYA EN EL REGISTRO, LO PASO A ASCII Y LO ENVIO DE UNA AL LCD
      ;ADDLW   0X30
      ;CALL   LCDD      


      MOVF   CEN,W      ;TOMO EL DATO QUE HAYA EN EL REGISTRO, LO PASO A ASCII Y LO ENVIO DE UNA AL LCD
      ADDLW   0X30
      CALL   LCDD      

      MOVLW   '.'
      CALL   LCDD      ;ENVIO EL PUNTO DECIMAL

      MOVF   DEC,W      ;TOMO EL DATO QUE HAYA EN EL REGISTRO, LO PASO A ASCII Y LO ENVIO DE UNA AL LCD
      ADDLW   0X30
      CALL   LCDD      

      MOVF   UNI,W      ;TOMO EL DATO QUE HAYA EN EL REGISTRO, LO PASO A ASCII Y LO ENVIO DE UNA AL LCD
      ADDLW   0X30
      CALL   LCDD      
      
      MOVLW   'A'
      CALL   LCDD
      
      MOVLW   'm'
      CALL   LCDD
      
      MOVLW   'p'
      CALL   LCDD
division
   MOVLW   0X03            ;DIVISION POR 1.000
   MOVWF   WREG_H
   MOVLW   0XE8
   MOVWF   WREG_L
   CALL   PUSH_2_STACK

   CALL   DIVI_16S

   MOVF   STACK_1L,W
   MOVWF   MIL

   MOVLW   0X03
   MOVWF   WREG_H
   MOVLW   0XE8
   MOVWF   WREG_L
   CALL   PUSH_2_STACK

   CALL   MULTI_16S

   CALL   RESTA_16S
   
   CALL   DUP
NO_DATA
      GOTO   LOOP_PRINCIPAL


RETARDOTE
LOOP_RETARDOTE
      CALL   RETARDO
      DECFSZ   CONT2,F
      GOTO   LOOP_RETARDOTE
      RETURN

RETARDO
      MOVLW   .255
      MOVWF   CONT
LOOP_RETARDO
      DECFSZ   CONT,F
      GOTO   LOOP_RETARDO
      RETURN

INIT_LCD
      MOVLW   0X30      ;MANDA LA INSTRUCCION 3 VECES, PRIMERA
      MOVWF   PORTB
        CALL    OUTLCD
        MOVLW   0X30      ;SEGUNDA
      MOVWF   PORTB
        CALL    OUTLCD
        MOVLW   0X30      ;TERCERA
      MOVWF   PORTB
        CALL    OUTLCD
        MOVLW   0X20      ;Operacion en 4 bits
      MOVWF   PORTB
        CALL    OUTLCD      ;MANDA LA INSTRUCCION
        MOVLW   0X2C      ;
        CALL    LCDI
        MOVLW   0X08      ;
        CALL    LCDI
        MOVLW   0X0F      ;
        CALL    LCDI
        MOVLW   0X01      ;
        CALL    LCDI
        MOVLW   0X06      ;
        CALL    LCDI
        MOVLW   0X0C
        CALL    LCDI
      RETURN

OUTLCD
      BSF     PORTB,EN         ; PONE EN 1 el enable del lcd  "HABILITA" EL LCD
      MOVLW   0X05         ;0X05
      MOVWF   CONT2
      CALL    RETARDOTE
      BCF     PORTB,EN         ; PONE EN 0 ENABLE DEL LCD
      RETURN

LCDD
      MOVWF   LCDATA      ;
      SUBLW   0X00      ;COMPARO CON 0X00 PARA SABER SI TERMINO DE ESCRIBIR EN LCD
      BTFSC   STATUS,Z   ;SALTO SI NO ES IGUAL A 0X00
      GOTO   FIN_LCDD   ;SI ES IGUAL TERMINO LA RUTINA SIN SACAR NADA POR LCD

      MOVLW   0XF0            ;MASCARA DEL NIBBLE ALTO
      ANDWF   LCDATA,W        ;
      MOVWF   PORTB           ;SACA POR EL PUERTO EL DATO
      BSF      PORTB,RS        ;PONE RS EN CARACTER

      CALL   OUTLCD

      MOVLW   0X0F            ;MASCARA DEL NIBBLE BAJO
      ANDWF   LCDATA,f        ;
      SWAPF   LCDATA,W        ;PONE LOS 4 BITS DE MENOR PESO EN EL DE MAYOR PESO EN LCDATA
      MOVWF   PORTB           ;SACA POR EL PUERTO EL DATO
      BSF      PORTB,RS        ;PONE RS EN CARACTER

      CALL   OUTLCD
FIN_LCDD
      RETURN


LCDI
      MOVWF   LCDATA      ;
      MOVLW   0XF0            ; MASCARA DEL NIBBLE ALTO
      ANDWF   LCDATA,W        ;
      MOVWF   PORTB           ;SACA POR EL PUERTO EL DATO
      BCF      PORTB,RS        ; PONE RS EN INSTRUCCION O COMANDO

      CALL   OUTLCD          ; DA SALIDA POR EL LCD

      MOVLW   0X0F            ; MASCARA DEL NIBBLE BAJO
      ANDWF   LCDATA,f        ;
      SWAPF   LCDATA,W        ; PONE LOS 4 BITS DE MENOR PESO EN EL DE MAYOR PESO EN IODATA
      MOVWF   PORTB           ;SACA POR EL PUERTO EL DATO
      BCF      PORTB,RS        ; PONE RS EN INSTRUCCION

      CALL   OUTLCD          ; DA SALIDA POR EL LCD

      RETURN

MENSAJE_TERMOMETRO
      MOVLW   'A'
      CALL   LCDD
      MOVLW   'M'
      CALL   LCDD
      MOVLW   'P'
      CALL   LCDD
      MOVLW   'E'
      CALL   LCDD
      MOVLW   'R'
      CALL   LCDD
      MOVLW   'I'
      CALL   LCDD
      MOVLW   'M'
      CALL   LCDD
      MOVLW   'E'
      CALL   LCDD
      MOVLW   'T'
      CALL   LCDD
      MOVLW   'R'
      CALL   LCDD
      MOVLW   'O'
      CALL   LCDD
      RETURN

ADC_2_VOLT
;   MOVLW   0X01            ;
;   MOVWF   WREG_H
;   MOVLW   0X33
;   MOVWF   WREG_L
;   CALL   PUSH_2_STACK

   MOVLW   0X00            
   MOVWF   WREG_H
   MOVLW   0X32      ;metio el numero 100
   MOVWF   WREG_L
   CALL   PUSH_2_STACK

   CALL   MULTI_16S   ;multiplica lo que leyo por 100

   MOVLW   0X00            
   MOVWF   WREG_H
   MOVLW   0X20 ; 50
   MOVWF   WREG_L
   CALL   PUSH_2_STACK

   CALL   DIVI_16S

   MOVLW   0X00            
   MOVWF   WREG_H
   MOVLW   0X0A
   MOVWF   WREG_L
   CALL   PUSH_2_STACK
   
   CALL   MULTI_16S
   
   MOVLW   0X00            
   MOVWF   WREG_H
   MOVLW   0X20 ; 50
   MOVWF   WREG_L
   CALL   PUSH_2_STACK

   CALL   DIVI_16S

   CALL   HEX_2_DEC_16   ;
   RETURN



HEX_2_DEC_16               ;CONVIERTE EL OBJETO EN EL NIVEL 1 DEL STACK EN DECIMAL
   CALL   DUP               ;DECMIL.MIL.CEN.DEC.UNI

   MOVLW   0X27            ;DIVISION POR 10.000
   MOVWF   WREG_H
   MOVLW   0X10
   MOVWF   WREG_L
   CALL   PUSH_2_STACK

   CALL   DIVI_16S

   MOVF   STACK_1L,W
   MOVWF   DECMIL
   
   MOVLW   0X27
   MOVWF   WREG_H
   MOVLW   0X10
   MOVWF   WREG_L
   CALL   PUSH_2_STACK

   CALL   MULTI_16S

   CALL   RESTA_16S

   CALL   DUP

   MOVLW   0X03            ;DIVISION POR 1.000
   MOVWF   WREG_H
   MOVLW   0XE8
   MOVWF   WREG_L
   CALL   PUSH_2_STACK

   CALL   DIVI_16S

   MOVF   STACK_1L,W
   MOVWF   MIL

   MOVLW   0X03
   MOVWF   WREG_H
   MOVLW   0XE8
   MOVWF   WREG_L
   CALL   PUSH_2_STACK

   CALL   MULTI_16S

   CALL   RESTA_16S
   
   CALL   DUP

   MOVLW   0X00            ;DIVISION POR 100
   MOVWF   WREG_H
   MOVLW   0X64
   MOVWF   WREG_L
   CALL   PUSH_2_STACK

   CALL   DIVI_16S

   MOVF   STACK_1L,W
   MOVWF   CEN

   MOVLW   0X00
   MOVWF   WREG_H
   MOVLW   0X64
   MOVWF   WREG_L
   CALL   PUSH_2_STACK

   CALL   MULTI_16S

   CALL   RESTA_16S


   CALL   DUP

   MOVLW   0X00            ;DIVISION POR 10
   MOVWF   WREG_H
   MOVLW   0X0A
   MOVWF   WREG_L
   CALL   PUSH_2_STACK

   CALL   DIVI_16S

   MOVF   STACK_1L,W
   MOVWF   DEC

   MOVLW   0X00
   MOVWF   WREG_H
   MOVLW   0X0A
   MOVWF   WREG_L
   CALL   PUSH_2_STACK

   CALL   MULTI_16S

   CALL   RESTA_16S

   MOVF   STACK_1L,W
   MOVWF   UNI
   RETURN


CLR_STACK
   MOVLW   0X00

   MOVWF   STACK_4H
   MOVWF   STACK_3H
   MOVWF   STACK_2H
   MOVWF   STACK_1H

   MOVWF   STACK_4L
   MOVWF   STACK_3L
   MOVWF   STACK_2L
   MOVWF   STACK_1L
   
   RETURN

SHIFT_STACK_UP
   MOVF   STACK_3H,W
   MOVWF   STACK_4H
   MOVF   STACK_3L,W
   MOVWF   STACK_4L
SHIFT_STACK_UNTIL_3
   MOVF   STACK_2H,W
   MOVWF   STACK_3H
   MOVF   STACK_2L,W
   MOVWF   STACK_3L
SHIFT_STACK_UNTIL_2
   MOVF   STACK_1H,W
   MOVWF   STACK_2H
   MOVF   STACK_1L,W
   MOVWF   STACK_2L
   RETURN

SWAP
   MOVF   STACK_2H,W      ;HAGO UNA COPIA TEMPORAL DE STACK_2 EN STACK_5
   MOVWF   STACK_5H      
   MOVF   STACK_2L,W
   MOVWF   STACK_5L      
   CALL   SHIFT_STACK_UNTIL_2      ;HAGO UN SHIFT EN EL STACK HASTA EL NIVEL 3
   MOVF   STACK_5H,W            ;RESTAURO LA COPIA TEMPORAL YA EN STACK_1
   MOVWF   STACK_1H
   MOVF   STACK_5L,W
   MOVWF   STACK_1L
   RETURN

ROT
   MOVF   STACK_3H,W      ;HAGO UNA COPIA TEMPORAL DE STACK_2 EN STACK_5
   MOVWF   STACK_5H      
   MOVF   STACK_3L,W
   MOVWF   STACK_5L      
   CALL   SHIFT_STACK_UNTIL_3      ;HAGO UN SHIFT EN EL STACK HASTA EL NIVEL 3
   MOVF   STACK_5H,W            ;RESTAURO LA COPIA TEMPORAL YA EN STACK_1
   MOVWF   STACK_1H
   MOVF   STACK_5L,W
   MOVWF   STACK_1L
   RETURN

DROP
   MOVF   STACK_2H,W
   MOVWF   STACK_1H
   MOVF   STACK_2L,W
   MOVWF   STACK_1L

   MOVF   STACK_3H,W
   MOVWF   STACK_2H
   MOVF   STACK_3L,W
   MOVWF   STACK_2L

   MOVF   STACK_4H,W
   MOVWF   STACK_3H
   MOVF   STACK_4L,W
   MOVWF   STACK_3L
   CLRF   STACK_4H
   CLRF   STACK_4L
   RETURN

DUP
   MOVF   STACK_1H,W      ;HAGO UNA COPIA TEMPORAL DE STACK_2 EN STACK_5
   MOVWF   WREG_H      
   MOVF   STACK_1L,W
   MOVWF   WREG_L
   CALL   PUSH_2_STACK
   RETURN

PUSH_2_STACK            ;ESTA RUTINA RECIBE LOS DATOS EN (WREG_H:W)
   CALL   SHIFT_STACK_UP   ;PRIMERO HAGO UN SHIFT DEL STACK HACIA ARRIBA PARA ABRIR EL ESPACIO (SE PIERDE EL DATO EN STACK 4)
   MOVF   WREG_L,W
   MOVWF   STACK_1L      ;CARGO EL VALOR DE W EN EL BYTE BAJO DEL PRIMER NIVEL DE STACK
   MOVF   WREG_H,W      ;PONGO EL BYTE ALTO DE W EN EL BYTE ALTO DEL PRIMER NIVEL DE STACK
   MOVWF   STACK_1H      ;
   RETURN

SUMA_16S
   MOVF   STACK_2H,W      ;CARGO LOS DATOS DE LA PILA EN LOS REGISTROS DE TRABAJO DE LA RUTINA SUMA_16
   MOVWF   N2_H
   MOVF   STACK_2L,W
   MOVWF   N2_L

   MOVF   STACK_1H,W      ;CARGO LOS DATOS DE LA PILA EN LOS REGISTROS DE TRABAJO DE LA RUTINA SUMA_16
   MOVWF   N1_H
   MOVF   STACK_1L,W
   MOVWF   N1_L

   CALL   SUMA_16

   MOVF   N3_H,W         ;PONGO EL RESULTADO DE LA OPERACION EN EL NIVEL 2 DEL STACK
   MOVWF   STACK_2H
   MOVF   N3_L,W
   MOVWF   STACK_2L

   CALL   DROP         ;HAGO UN DROP DEL NIVEL 1 PARA QUE LA SUMA QUEDE COMPLETA EN EL NIVEL 1
   RETURN

RESTA_16S
   MOVF   STACK_2H,W      ;CARGO LOS DATOS DE LA PILA EN LOS REGISTROS DE TRABAJO DE LA RUTINA SUMA_16
   MOVWF   N1_H
   MOVF   STACK_2L,W
   MOVWF   N1_L

   MOVF   STACK_1H,W      ;CARGO LOS DATOS DE LA PILA EN LOS REGISTROS DE TRABAJO DE LA RUTINA SUMA_16
   MOVWF   N2_H
   MOVF   STACK_1L,W
   MOVWF   N2_L

   CALL   RESTA_16C

   MOVF   N3_H,W         ;PONGO EL RESULTADO DE LA OPERACION EN EL NIVEL 2 DEL STACK
   MOVWF   STACK_2H
   MOVF   N3_L,W
   MOVWF   STACK_2L

   CALL   DROP         ;HAGO UN DROP DEL NIVEL 1 PARA QUE LA SUMA QUEDE COMPLETA EN EL NIVEL 1
   RETURN

MULTI_16S
   MOVF   STACK_2H,W      ;CARGO LOS DATOS DE LA PILA EN LOS REGISTROS DE TRABAJO DE LA RUTINA SUMA_16
   MOVWF   N1_H
   MOVF   STACK_2L,W
   MOVWF   N1_L

   MOVF   STACK_1H,W      ;CARGO LOS DATOS DE LA PILA EN LOS REGISTROS DE TRABAJO DE LA RUTINA SUMA_16
   MOVWF   N2_H
   MOVF   STACK_1L,W
   MOVWF   N2_L

   CALL   MULTI_16

   MOVF   N3_H,W         ;PONGO EL RESULTADO DE LA OPERACION EN EL NIVEL 2 DEL STACK
   MOVWF   STACK_2H
   MOVF   N3_L,W
   MOVWF   STACK_2L

   CALL   DROP         ;HAGO UN DROP DEL NIVEL 1 PARA QUE LA SUMA QUEDE COMPLETA EN EL NIVEL 1
   RETURN

DIVI_16S
   MOVF   STACK_2H,W      ;CARGO LOS DATOS DE LA PILA EN LOS REGISTROS DE TRABAJO DE LA RUTINA SUMA_16
   MOVWF   N1_H
   MOVF   STACK_2L,W
   MOVWF   N1_L

   MOVF   STACK_1H,W      ;CARGO LOS DATOS DE LA PILA EN LOS REGISTROS DE TRABAJO DE LA RUTINA SUMA_16
   MOVWF   N2_H
   MOVF   STACK_1L,W
   MOVWF   N2_L

   CALL   DIVI_16

   MOVF   COCI_H,W         ;PONGO EL RESULTADO DE LA OPERACION EN EL NIVEL 2 DEL STACK
   MOVWF   STACK_2H
   MOVF   COCI_L,W
   MOVWF   STACK_2L

   CALL   DROP         ;HAGO UN DROP DEL NIVEL 1 PARA QUE LA SUMA QUEDE COMPLETA EN EL NIVEL 1
   RETURN

SUMA_16
   MOVF   N1_L,W
   ADDWF   N2_L,W
   MOVWF   N3_L
   MOVF   N1_H,W
   BTFSC   STATUS,C
   INCF   N1_H,W
   ADDWF   N2_H,W
   MOVWF   N3_H
   RETURN
   
RESTA_16C
   BSF      FLAGS,CARRY               ;PRESUPONGO INICIALMENTE QUE LA OPERACION DA MAYOR QUE 0
   MOVF   N2_L,W
   SUBWF   N1_L,W
   MOVWF   N3_L
   BTFSS   STATUS,C
   CALL   DECREMENTA_CON_CARRY      ;DEBO INDICAR CUANDO EL BYTE ALTO PRODUCE CARRY
   MOVF   N2_H,W
   SUBWF   N1_H,W
   MOVWF   N3_H

   MOVF   STATUS,W               ;ESTA PARTE DE LA RUTINA DEBE LOGRAR QUE RESTA_16 GENERE CARRY=0
   ANDLW   B'00000001'               ;CUANDO UNA OPERACION DA NEGATIVA, BIEN SEA EN EL BYTE ALTO O EN EL BAJO
   ANDWF   FLAGS,W
   BCF      STATUS,C
   BTFSS   STATUS,Z
   BSF      STATUS,C

   RETURN

DECREMENTA_CON_CARRY
   BSF      FLAGS,CARRY               ;USO UNA BANDERA DE USUARIO PARA "ACORDARME" DEL CARRY EN EL BYTE ALTO
   MOVLW   0X01
   SUBWF   N1_H,F
   BTFSS   STATUS,C
   BCF      FLAGS,CARRY
   RETURN
   
MULTI_16
         CALL   N2_2_INDI         ;COPIO EL VALOR DE UNO DE LOS MULTIPLOS A OTRA VARIABLE LLAMADA INDICE QUE INDICARA
         CLRF   N2_H            ;CUANTAS VECES DEBO SUMAR EN 16 BITS
         CLRF   N2_L            ;LUEGO, EN N2 ACUMULO EL VALOR DE LA MULTIPICACION, POR LO TANTO LO ARRANCO EN 0X0000
LOOP_MULTI_16
         CALL   SUMA_16            ;HAGO LA PRIMERA SUMA (N1+0)=N3
         CALL   BKUP_N1_N2_N3      ;HAGO UNA COPIA DE SEGURIDAD DE TODA LA OPERACION DE SUMA PORQUE A CONTINUCION DEBO HACER UNA RESTA
         CALL   INDI_2_N1         ;PONGO EL INDICE EN N1 CON LA INTENCIÓN DE RESTARLE 1 AL INDICE (INDICE=INDICE-1)
         CLRF   N2_H            ;PERO DEBE HACERSE EN 16 BITS
         MOVLW   0X01            ;
         MOVWF   N2_L            ;CARGO N2 CON 0X0001 (0X00 Y 0X01)
         CALL   RESTA_16C         ;(INDICE=INDICE-1)
         CALL   N3_2_INDI         ;EL RESULTADO DE LA RESTA LO ALMACENO EN INDICE
         CALL   CHECK_INDI_0
         BTFSC   STATUS,Z
         GOTO   FIN_MULTI_16      ;EN CASO DE QUE SE HAYA LLEGADO A 0, SIMPLEMENTE SE TERMINA LA OPERACION
         CALL   RSTR_N1_N2_N3      ;EN CASO DE QUE AUN FALTEN CICLOS, ENTONCES SE RESTAURAN LOS VALORES DE LA SUMA
         CALL   N3_2_N2            ;SE ACUMULA EL VALOR DEL RESULTADO EN N2 (N2=N3)
         GOTO   LOOP_MULTI_16      ;Y SE REANUDA EL PROCESO
FIN_MULTI_16
         CALL   RSTR_N1_N2_N3      ;DESPUES DE RESTAURAR LOS VALORES EN N3 SE ENCUENTRA LA RESPUESTA
         RETURN

DIVI_16
         CLRF   COCI_H            ;INICIALIZO EL COCIENTE
         CLRF   COCI_L
LOOP_DIVI_16
         CALL   RESTA_16C         ;INICIO CON UNA RESTA EN 16 BITS
         BTFSS   STATUS,C         ;CUANDO ME DE UN CARRY NEGATIVO, PARO DE "RESTAR"!
         GOTO   FIN_DIVI_16
         CALL   BKUP_N1_N2_N3      ;HAGO BACKUP PARA PODER OPERAR CON LAS RUTINAS OTROS DATOS
         CALL   COCI_2_N1
         CLRF   N2_H
         MOVLW   0X01            ;LE SUMO EN 16 BITS 1 AL CONTADOR (COCIENTE)
         MOVWF   N2_L
         CALL   SUMA_16
         CALL   N3_2_COCI         ;COPIO EL RESULTADO DE LA SUMA AL COCIENTE
         CALL   RSTR_N1_N2_N3      ;RESTAURO LAS COPIAS PARA CONTINUAR CON LA DIVISION
         CALL   N3_2_N1
         GOTO   LOOP_DIVI_16
FIN_DIVI_16
         RETURN

CHECK_INDI_0
         MOVLW   0X00            ;EN LA MULTIPLICACION DEBO CHEQUEAR CUANDO LA VARIABLE INDICE ME DA 0
         SUBWF   INDI_H,W
         BTFSS   STATUS,Z         ;PARA PODER PARAR DE SUMAR
         GOTO   FIN_CHECK_INDI_0
         MOVLW   0X00            ;COMO ES EN 16 BITS, ENTONCES TOCA ASEGURARSE POR CADA BYTE
         SUBWF   INDI_L,W
         BTFSS   STATUS,Z
         GOTO   FIN_CHECK_INDI_0
         BSF      STATUS,Z
         RETURN
FIN_CHECK_INDI_0
         BCF      STATUS,Z
         RETURN


BKUP_N1_N2_N3                     ;RUTINA DE BACK UP
      MOVF   N1_H,W
      MOVWF   BK1_H
      MOVF   N1_L,W
      MOVWF   BK1_L
      MOVF   N2_H,W
      MOVWF   BK2_H
      MOVF   N2_L,W
      MOVWF   BK2_L
      MOVF   N3_H,W
      MOVWF   BK3_H
      MOVF   N3_L,W
      MOVWF   BK3_L
      RETURN

RSTR_N1_N2_N3                     ;RUTINA DE RESTAURACION
      MOVF   BK1_H,W
      MOVWF   N1_H
      MOVF   BK1_L,W
      MOVWF   N1_L
      MOVF   BK2_H,W
      MOVWF   N2_H
      MOVF   BK2_L,W
      MOVWF   N2_L
      MOVF   BK3_H,W
      MOVWF   N3_H
      MOVF   BK3_L,W
      MOVWF   N3_L
      RETURN

N2_2_INDI                        ;RUTINAS DE COPIADO ENTRE VARIABLES PARA PODER OPERAR CON LAS MISMAS
      MOVF   N2_H,W               ;VARIABLES QUE INICIALMENTE SE NOMBRARON PARA CADA NUMERO N1 N2 N3
      MOVWF   INDI_H
      MOVF   N2_L,W
      MOVWF   INDI_L
      RETURN

N3_2_COCI
      MOVF   N3_H,W
      MOVWF   COCI_H
      MOVF   N3_L,W
      MOVWF   COCI_L
      RETURN


INDI_2_N1
      MOVF   INDI_H,W
      MOVWF   N1_H
      MOVF   INDI_L,W
      MOVWF   N1_L
      RETURN

COCI_2_N1
      MOVF   COCI_H,W
      MOVWF   N1_H
      MOVF   COCI_L,W
      MOVWF   N1_L
      RETURN

N3_2_INDI
      MOVF   N3_H,W
      MOVWF   INDI_H
      MOVF   N3_L,W
      MOVWF   INDI_L
      RETURN

N3_2_N2
      MOVF   N3_H,W
      MOVWF   N2_H
      MOVF   N3_L,W
      MOVWF   N2_L
      RETURN

N3_2_N1
      MOVF   N3_H,W
      MOVWF   N1_H
      MOVF   N3_L,W
      MOVWF   N1_L
      RETURN


BORRAR
      MOVLW   .1
      CALL   LCDI
      RETURN

      END                       ; directive 'end of program'

Desconectado mtristan

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 395
Re: amperimetro pic16f887 assembler
« Respuesta #1 en: 02 de Noviembre de 2010, 18:35:12 »
.


¿Cómo sería lo de convertir un voltímetro en amperímetro con la ley de ohm?  :huh:


When you see a good move, look for a better one (Emanuel Lasker)

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: amperimetro pic16f887 assembler
« Respuesta #2 en: 02 de Noviembre de 2010, 19:38:06 »
.


¿Cómo sería lo de convertir un voltímetro en amperímetro con la ley de ohm?  :huh:




  Básicamente, hacer circular la corriente por una Resistencia de bajo valor (valor conocido) y medir la tensión en dicha resistencia (de eso se encargaría el voltímetro). Luego hacés la operación I = V/R (corriente = tensión/resistencia)
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado bmb

  • PIC18
  • ****
  • Mensajes: 423
Re: voltimetro convertirlo a amperimetro en asm pic16f887
« Respuesta #3 en: 02 de Noviembre de 2010, 21:27:06 »
Hola piccero, yo de assembler poco, pero creo que tu problema es más bien de hardware, ya que como circuito base de un amperímetro se usa comúmnente un voltímetro.  Lo que necesitarías implementar es una resistencia 'shunt', leer la caída de voltaje en ella y ahí si aplicarías la ley de ohm (si estamos hablando de DC).

Saludos!

Edito:  Disculpa AngelGris, no se por que razón no había visto tu post.  Saludos!
« Última modificación: 02 de Noviembre de 2010, 22:26:41 por bmb »

Desconectado todopic

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3495
    • http://www.todopicelectronica.com.ar
Re: voltimetro convertirlo a amperimetro en asm pic16f887
« Respuesta #4 en: 02 de Noviembre de 2010, 21:55:59 »
Como te manifiesta BMB, si po ejemplo, colocas en paralelo a la entrada de tu voltimetro, una resistencia de 1 ohm, y esta en serie al circuito a medir, cuando circule un amprer, la caida en la resistencia sera de un voltio, que, como le cambias "la denominacion" , te dirá un amper  ;-)
Esto de manera rudimentaria... el shunt tendrá que ser del menor valor posible, por ejemplo 0.1 ohm... por lo que tendras que adaptar la tension, o multiplicar los datos leidos....  :mrgreen:

Piccero, has colocado lo mismo en 3 lugares diferentes....
« Última modificación: 02 de Noviembre de 2010, 22:19:18 por todopic »
Firmat - Santa Fe - Argentina

www.TodoPic.net

Solo se tiran piedras, al arbol que tiene frutos...

Desconectado mtristan

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 395
Re: voltimetro convertirlo a amperimetro en asm pic16f887
« Respuesta #5 en: 02 de Noviembre de 2010, 22:59:40 »
.


Ahí lo terminé de entender  ;-) Gracias.


When you see a good move, look for a better one (Emanuel Lasker)

Desconectado piccero

  • PIC10
  • *
  • Mensajes: 2
Re: voltimetro convertirlo a amperimetro en asm pic16f887
« Respuesta #6 en: 03 de Noviembre de 2010, 16:15:56 »
lo que no se es continuar con la rutina :(


 

anything