List p=18f458
#include "p18f458.inc"
V1 equ 0x100 ; Registro para guardar ADRESH del conv AD..corresponidente a V1
V1H equ 0x101
V1L equ 0x102
V2 equ 0x103 ;Registro para guardar ADRESH del conv AD..corresponidente a V2
V2H equ 0x104
V2L equ 0x105
V3 equ 0x106 ;Registro para guardar ADRESH del conv AD..corresponidente a V3
V3H equ 0x107
V3L equ 0x108
I1 equ 0x109 ;Registro para guardar ADRESH del conv AD..corresponidente a I1
I1H equ 0x10A
I1L equ 0x10B
I2 equ 0x10C ;Registro para guardar ADRESH del conv AD..corresponidente a I2
I2H equ 0x10D
I2L equ 0x10E
I3 equ 0x10F ;Registro para guardar ADRESH del conv AD..corresponidente a I3
I3H equ 0x110
I3L equ 0x111
COUNT equ 0x112 ; Registro contador para retardo y espera del tiempo de adquisición
A1 equ 0x113 ; W1 byte menos significativo(1)
A2 equ 0x114 ; W1 byte (2)
A3 equ 0x115 ; W1 Byte (3)
A4 equ 0x116 ; W1 byte(4):
B1 equ 0x117 ; W2 byte menos significativo (1)
B2 equ 0x118 ; W2 byte (2)
B3 equ 0x119 ; W2 byte (3)
B4 equ 0x11A ; W2 byte (4).
C1 equ 0x11B ; W3 byte menos significativo (1)
C2 equ 0x11C ; W3 byte (2)
C3 equ 0x11D ; W3 byte (3)
C4 equ 0x11E ; W3 byte (4).
AUX1 equ 0x11F ; Suma W1+W2(A+B).byte (1).
AUX2 equ 0x120 ; suma W1+W2 (A+B).byte (2)
AUX3 equ 0x121 ; suma W1+W2 (A+B).byte (3)
AUX4 equ 0x122 ; suma W1+W2 (A+B).byte (4).
D1 equ 0x123 ; WT byte (1) .
D2 equ 0x124 ; WT byte (2)
D3 equ 0x125 ; WT byte (3)
D4 equ 0x126 ; WT byte (4).
CARRY equ 0x127 ; Registro de acarreo para la suma (A+B) W1+W2
ACARREO equ 0x128; Registro de acarreo para la suma de (AUX + C)= WT.
BCD_0 equ 0x129
BCD_1 equ 0x12A
BCD_2 equ 0x12B
BCD_3 equ 0x12C ; Registros para almacenar dato BCD de 8 digitos..Este dato corresponde a la potencia Total q se enviará Via USART
MSNIB equ 0x12D ; registro para conteo de bits en la conv BIN to BCD
LSNIB equ 0x12E
delay equ 0x12F
PDel0 equ 0x130
PDel1 equ 0x131
PDel2 equ 0x132
data1 equ 0x133
data2 equ 0x134
data3 equ 0x135
data4 equ 0x136
conta equ 0x137
DATO equ 0x138
ORG 0x0000
goto INICIO
; org 0x0008
;goto inter
ORG 0X001A
TX_DATO bcf PIR1,TXIF
movwf TXREG
banksel TXSTA
TX_DAT clrwdt
btfss TXSTA,TRMT
goto TX_DAT
return
RECIBE movf RCREG,W ;Limpia el registro receptor
bcf PIR1,RCIF ;Restaura el flag del receptor
Leer_Car_Wait clrwdt
btfss PIR1,RCIF ;Se ha recibido un carácter ?
goto Leer_Car_Wait ;Todavía no, esperar
movf RCREG,W ;Si, leer el carácter
movwf DATO ;Salvarlo
return
;***************************
INICIO
clrwdt
banksel PORTC
clrf PORTC
clrf PORTB
clrf PORTD
clrf TRISB ; PUERTA B COMO SALIDA
clrf TRISD ; PUERTA D COMO SALIDA
movlw b'10111111'
movwf TRISC ; RC7/RX como entrada, RC6/TX como salida.
movlw b'00100100'
movwf TXSTA ; TX ON, modo asincrono 8 bits
movlw .25
movwf SPBRG ; 9600 baudios con Fosc=4Mhz...asincrono
bsf PIE1,RCIE ; habilita interrupción en la recepción
movlw b'10010000'
movwf RCSTA ; USART ON , recepción continua,sincrono
bsf INTCON,PEIE ;HAB INTERRUPCION DE PERIFERICOS
bsf INTCON,GIE ; ACTIVA INTERRUPCIONES GLOBALES
clrf conta
;loop clrwdt
; goto loop
;************* PROGRAMA PRINCIPAL *****************************
;*************CONVERSION DE CANAL CERO(0) ANALOGICO************
movlw 0xFF
movwf TRISA ; Pines PortA como entradas
movlw b'00000001'
movwf TRISE ; ----RE0 ENTRADA Y RE1 RE2 COMO SALIDAS----
;*//////////////////////////////////////
;*****INICIA RECEPCION DE DATOS DESDE TX*******************
BUCLE CALL RECIBE ; recibe byte 1
CALL TX_DATO ; envia para visualizar en PC
clrwdt
call RECIBE ; recibe byte 2
CALL TX_DATO
CLRWDT
CALL RECIBE ; recibe byte 3
CALL TX_DATO
clrwdt
; CALL RECIBE ; recibe byte 4
;CALL TX_DATO
movlw b'10001001';
movwf ADCON1 ; AD justificado a la derecha.pines AN0-AN5 como pines
clrwdt
movlw b'01000001'
movwf ADCON0 ; HAB A/D.CANAL 0. Fosc/8
bcf PIR1,ADIF ; Borra el flag de fin de conv AD
banksel COUNT ; ubicacion en el banco de COUNT
movlw 0x30
movwf COUNT ; carga 0x06 al registro COUNT
LOOP decfsz COUNT,f ; decrementa y guarda en COUNT y salta si COUNT=0
goto LOOP ; ESPERA TIEMPO DE ADQUISICION
banksel ADCON0
bsf ADCON0,GO ; da la orden de INICIO de CONVERSION
ADC_WAIT CLRWDT
btfss PIR1,ADIF ; Fin de conversión?
goto ADC_WAIT ; aún no!
call MOV_V1 ; subrutina para mover el valor obtenido al registro V1
;******** CONVERSIÓN DE CANAL 1 ANALÓGICO***************
banksel ADCON0
movlw b'01001001'
movwf ADCON0 ; HAB A/D . canal 1. Fosc /8
bcf PIR1,ADIF ; borra flag de fin de conc AD
banksel COUNT
movlw 0x30
movwf COUNT
LOOP1 decfsz COUNT,f ; decrementa COUNT y guarda en COUNT. salta si COUNT =0
goto LOOP1 ; ESPERA TIEMPO DE ADQUISICION
banksel ADCON0
bsf ADCON0,GO; orden de inicio de conversión.
ADC_WAIT1 CLRWDT
btfss PIR1,ADIF ; fin de conversión?
goto ADC_WAIT1 ; aún no!
call MOV_I1 ; subrutina para mover el valor obtenido al registro I1
;**********CONVERSION DE CANAL 2 ANALOGICO***************
banksel ADCON0
movlw b'01010001'
movwf ADCON0 ; HAB A/D . canal 2. Fosc /8
bcf PIR1,ADIF ; borra flag de fin de conc AD
banksel COUNT
movlw 0x30
movwf COUNT
LOOP2 decfsz COUNT,f ; decrementa COUNT y guarda en COUNT. salta si COUNT =0
goto LOOP2 ; ESPERA TIEMPO DE ADQUISICION
banksel ADCON0
bsf ADCON0,GO; orden de inicio de conversión.
ADC_WAIT2 CLRWDT
btfss PIR1,ADIF ; fin de conversión?
goto ADC_WAIT2 ; aún no!
call MOV_V2 ; subrutina para mover el valor obtenido al registro V2
;**************CONVERSIÓN DE CANAL 3 ANALÓGICO********************
banksel ADCON0
movlw b'01011001'
movwf ADCON0 ; HAB A/D . canal 3. Fosc /8
bcf PIR1,ADIF ; borra flag de fin de conc AD
banksel COUNT
movlw 0x30
movwf COUNT
LOOP3 decfsz COUNT,f ; decrementa COUNT y guarda en COUNT. salta si COUNT =0
goto LOOP3 ; ESPERA TIEMPO DE ADQUISICION
banksel ADCON0
bsf ADCON0,GO; orden de inicio de conversión.
ADC_WAIT3 CLRWDT
btfss PIR1,ADIF ; fin de conversión?
goto ADC_WAIT3 ; aún no!
call MOV_I2 ; subrutina para mover el valor obtenido al registro I2
;*******CONVERSIÓN CANAL 4 ANALÓGICO*****************************
banksel ADCON0
movlw b'01100001'
movwf ADCON0 ; HAB A/D . canal 4. Fosc /8
bcf PIR1,ADIF ; borra flag de fin de conc AD
banksel COUNT
movlw 0x30
movwf COUNT
LOOP4 decfsz COUNT,f ; decrementa COUNT y guarda en COUNT. salta si COUNT =0
goto LOOP4 ; ESPERA TIEMPO DE ADQUISICION
banksel ADCON0
bsf ADCON0,GO ; orden de inicio de conversión.
ADC_WAIT4 CLRWDT
btfss PIR1,ADIF ; fin de conversión?
goto ADC_WAIT4 ; aún no!
call MOV_V3 ; subrutina para mover el valor obtenido al registro V3
;******CONVERSION CANAL 5 ANALÓGICO*********************************
banksel ADCON0
movlw b'01101001'
movwf ADCON0 ; HAB A/D . canal 5. Fosc /8
bcf PIR1,ADIF ; borra flag de fin de conc AD
banksel COUNT
movlw 0x30
movwf COUNT
LOOP5 decfsz COUNT,f ; decrementa COUNT y guarda en COUNT. salta si COUNT =0
goto LOOP5 ; ESPERA TIEMPO DE ADQUISICION
banksel ADCON0
bsf ADCON0,GO ; orden de inicio de conversión.
ADC_WAIT5 CLRWDT
btfss PIR1,ADIF ; fin de conversión?
goto ADC_WAIT5 ; aún no!
call MOV_I3 ; subrutina para mover el valor obtenido al registro
; ****LLAMA A LAS SUBRUTINAS PARA MULTIPLICAR LOS RESULTADOS DE V*I Y OBTENER LA POTENCIA TOTAL
call MULT ; subrutina de acondicionamiento de la señal.. se multiplica V*100 e I*200 para obtener un máx
; de 220V y 1A(por cada mv respectivamente.
call OBT_A ; Multiplica V1H-L*I1H-L---->A =W1
call OBT_B ; Mutiplica V2H-L*I2H-L---->B =W2
call OBT_C ; Multiplica V3H-L*I3H-L---->C =W3
call OBT_AUX ; suma W1+W2(a+b)->AUX
call OBT_Wtotal ; suma Aux+C-> D
banksel ADCON0
CLRWDT
goto BUCLE ; INICIA LA RECEPCION Y CONVERSION DE DATOS EN CADA CANAL NUEVAMENTE
;*********************************************************************
; ******************* SUBRUTINAS ***************************************
MOV_V1 ;========= Mueven a V1,V2,V3 e I1 I2 I3 el valor obtenido en ADRESL==========
banksel ADRESL ;=================se garantiza un valor max de 255 a traves del hardware (1.2Vinmax)===
movff ADRESL,V1; ADRESL->V1
return ; retorna a la siguiente instrucción, ubicada despues de la llamada a subrutina
MOV_I1
banksel ADRESL
movff ADRESL, I1; ADRESL->I1
return
MOV_V2
banksel ADRESL
movff ADRESL, V2; ADRESL->V2
return
MOV_I2
banksel ADRESL
movff ADRESL,I2; ADRESL->I2
return ; retorna a la siguiente instrucción, ubicada despues de la llamada a subrutina
MOV_V3
banksel ADRESL
movff ADRESL,V3; ADRESL->V3
return ; retorna a la siguiente instrucción, ubicada despues de la llamada a subrutina
MOV_I3
banksel ADRESL
movff ADRESL,I3; ADRESL->I3
return ; retorna a la siguiente instrucción, ubicada despues de la llamada a subrutina
;********************************************************************
MULT
banksel V1
movlw .96 ; ********************* ADvoltaje*48*2 debido a la resolución!
mulwf V1 ; V1*96 -> PRODH_L ; ADintensidad *48
banksel PRODH ; al multiplicar V*I se obtiene W en unidades de ((mW))....
movff PRODH,V1H ; PRODH->V1H ;
movff PRODL,V1L ; PRODl->V1L
banksel I1
movlw .48 ;*******************
mulwf I1 ; I1*48 -> PRODH_L
banksel PRODH
movff PRODH,I1H ; PRODH->I1H
movff PRODL,I1L ; PRODL-> I1L
;****************************V2(48*2) e I2(48)**************************************
banksel V2
movlw .96; *********************
mulwf V2 ; V2*96-> PRODH_L
banksel PRODH
movff PRODH,V2H ; PRODH->V2H
movff PRODL,V2L ; PRODL->V2L
banksel I2
movlw .48 ;*******************
mulwf I2 ; I2*48 -> PRODH_L
banksel PRODH
movff PRODH,I2H ; PRODH->I2H
movff PRODL,I2L ; PRODL->I2L
;***************************V3(48*2) e I3(48)********************************
banksel V3
movlw .96; *********************
mulwf V3 ; V3*96-> PRODH_L
banksel PRODH
movff PRODH,V3H ; PRODH->V3H
movff PRODL,V3L ; PRODl->V3L
banksel I3
movlw .48 ;*******************
mulwf I3 ; I3*48 -> PRODH_L
banksel PRODH
movff PRODH,I3H ; PRODH->I3H
movff PRODL,I3L ; PRODL-> I3L
return ; fin de subrutina
;====== SUBRUTINA PARA OBTENER A=W1(V1H_L * I1H_L) A4 MSbyte============
OBT_A
banksel V1L
movf V1L,W
mulwf I1L
movff PRODH,A2
movff PRODL,A1
movf V1H,W
mulwf I1H
movff PRODH,A4
movff PRODL,A3
movf V1L ,W
mulwf I1H
movf PRODL,W
addwf A2
movf PRODH,W
addwfc A3
clrf WREG
addwfc A4
movf V1H,W
mulwf I1L
movf PRODL,W
addwf A2
movf PRODH,W
addwfc A3,1
clrf WREG
addwfc A4
return; fin de subrutina
;====SUBRUTINA PARA OBTENER B=W2(V2H_L * I2H_L) B4 MSByte======
OBT_B
banksel V2L
movf V2L,W
mulwf I2L
movff PRODH,B2
movff PRODL,B1
movf V2H,W
mulwf I2H
movff PRODH,B4
movff PRODL,B3
movf V2L ,W
mulwf I2H
movf PRODL,W
addwf B2
movf PRODH,W
addwfc B3
clrf WREG
addwfc B4
movf V2H,W
mulwf I2L
movf PRODL,W
addwf B2
movf PRODH,W
addwfc B3
clrf WREG
addwfc B4
return; fin de subrutina
;==SUBRUTINA PARA OBTENER C=W3 (V3H_L * I3H_L) C4 MSByte =============
OBT_C
banksel V3L
movf V3L,W
mulwf I3L
movff PRODH,C2
movff PRODL,C1
movf V3H,W
mulwf I3H
movff PRODH,C4
movff PRODL,C3
movf V3L ,W
mulwf I3H
movf PRODL,W
addwf C2
movf PRODH,W
addwfc C3
clrf WREG
addwfc C4
movf V3H,W
mulwf I3L
movf PRODL,W
addwf C2
movf PRODH,W
addwfc C3
clrf WREG
addwfc C4
return; fin de subrutina
;***********-----Aux=A+B------- *********************
OBT_AUX
banksel CARRY
clrf CARRY
banksel A1
movf A1,W
addwf B1,W
movwf AUX1
btfsc STATUS,C ; acarreo?
goto INC_CARRY1 ; Si!
UNO movf A2,W ; NO
addwf B2,W
movwf AUX2
btfsc STATUS,C ; ACARREO?
goto INC_CARRY2 ; si!
DOS movf A3, W
addwf B3,W
movwf AUX3
btfsc STATUS,C; acarreo?
goto INC_CARRY3 ;SI!
TRES movf A4,W
addwf B4,W
movwf AUX4
btfsc STATUS,C; acarreo?
incf CARRY
goto FINISH
INC_CARRY1 incf A2
btfsc STATUS,Z; acarreo?
incf A3 ; si!
goto UNO ; NO
INC_CARRY2 incf A3
btfsc STATUS,Z; acarreo?
incf A4
goto DOS
INC_CARRY3 incf A4
btfsc STATUS,Z ; acarreo?
incf CARRY
goto TRES
FINISH return
;****************------D=Aux+C=Wtotal--------***********************
OBT_Wtotal
banksel AUX1
movf AUX1,W
addwf C1, W
movwf D1
btfsc STATUS,C ; acarreo?
goto CARRY1
ONE movf AUX2,W
addwf C2,W
movwf D2
btfsc STATUS,C; ACARREO?
goto CARRY2
TWO movf AUX3, W
addwf C3,W
movwf D3
btfsc STATUS,C
goto CARRY3
THREE movf AUX4,W
addwf C4,W
movwf D4
btfsc STATUS,C; acarreo?
incf ACARREO
goto FIN
CARRY1 incf AUX2
btfsc STATUS,Z; acarreo?
incf AUX3
goto ONE
CARRY2 incf AUX3
btfsc STATUS,Z; acarreo?
incf AUX4
goto TWO
CARRY3 incf AUX4
btfsc STATUS,Z; acarreo?
incf ACARREO
goto THREE
FIN return
end ; fin del programa