Hola amigos del foro. en el subforo de preguntas me ayudaron con un problemita que tenia, y el codigo ya esta listo, asi que lo publico aca por si le es util a alguien.
program fasbas3
dim tiempo as byte
dim medir as byte
dim atento as byte
dim angulo as float
dim x as float
dim cosfi as float
dim mostrarw as word
dim mostrarh as byte
dim i as byte
dim cap as byte
sub procedure interrupt
if portb.6=0 then 'si voltaje y corriente estan en 0
if portb.7=0 then
atento=1 'entonces estamos atentos
goto fin
end if
end if
if atento=1 then 'si estamos atentos, y hay un cambio en V o I
TMR0=0 'ponemos TMR0 en cero
if portb.6=1 then 'si el que subio primero fue la corriente
cap=1 'entonces es una carga capacitiva
end if
atento=0 'ya no estamos atentos
medir=1 ' y seteamos medir para que a la proxima interrupcion
'entre al bloque "if, end if" siguiente
intcon=%00101000 'habilitamos la interrupcion por desbordamiento TMR0
goto fin
end if
if medir=1 then 'Si medir esta en 1 a la proxima interrucion
tiempo=TMR0 'tomamos el tiempo
if intcon.t0if=1 then 'si se desborda el TMR0
tiempo=0 'no se produjo interrupcion por V o i, y tiempo=0
end if
medir=0
intcon=%00000000 'desabilitamos interrupcion por TMR0 y por puerto B
end if
fin:
end sub
main:
'iniciamos las variables
tiempo=0
medir=0
atento=0
option_reg=%00000100 'divisor de frecuencia en 1:32
cmcon=7 'todas las entradas y salidas como digitales
trisb=%11000000
trisa=%00110000
portb=0
porta=0
i=96 'iniciamos i=96 para que mida de inmediato
inicio:
if i=96 then
intcon=%10001000 'activamos interrupcion por cambio del puerto B
end if
if i=100 then 'si se ha mostrado el resultado 100 veces, calulamos denuevo
intcon=0 'desabilitamostodas las interrupciones
i=0
atento=0
medir=0
if cap=1 then 'si cap=1, entonces
portb.4=1 'la carga es capacitiva, encendemos rb4
portb.5=0 'y apagamos rb5
else 'si no
portb.4=0 'la carga es inductiva, apagamos rb4
portb.5=1 'y encendemos rb5
end if
cap=0 'iniciamos el indicador de craga "cap"
if porta.5=1 then 'si entrada ra5=1, calculamos el angulo
porta.6=0
porta.7=1 'encendemos indicador de que mostramos angulo
if porta.4=1 then 'si ra4=1, trabajamos con 50Hz
angulo=5.76*tiempo 'angulo para 50 Hz
else
angulo=6.912*tiempo 'angulo para 60 Hz
end if
mostrarw=angulo 'transformamos de float a word (sacamos parte entera)
else 'si no, calculamos el coseno del angulo
porta.7=0
porta.6=1 'encendemos indicador de que mostramos el coseno
if porta.4=1 then 'si ra4=1, trabajamos con 50Hz
x=0.010053*tiempo 'angulo en radianes para 50 Hz
else
x=0.012064*tiempo 'angulo en radianes para 60 Hz
end if
cosfi=1000*(1-(1/2)*x*x+(1/24)*x*x*x*x-(1/720)*x*x*x*x*x*x) 'sacamos cos x
mostrarw=cosfi 'sacamos parte entera, float -> word
end if
mostrarw=dec2bcd16(mostrarw) 'transformamos mostrarw de decimal a bcd
mostrarh=hi(mostrarw) 'guardamos los 8 bits de mas peso de mostrarw
end if
'Mostramos en los displays, multiplexamos.
porta.0=1
porta.1=0
porta.2=0
porta.3=0
portb.0=mostrarw.0
portb.1=mostrarw.1
portb.2=mostrarw.2
portb.3=mostrarw.3
delay_ms(3)
porta.0=0
porta.1=1
porta.2=0
porta.3=0
portb.0=mostrarw.4
portb.1=mostrarw.5
portb.2=mostrarw.6
portb.3=mostrarw.7
delay_ms(3)
porta.0=0
porta.1=0
porta.2=1
portb.3=0
portb.0=mostrarh.0
portb.1=mostrarh.1
portb.2=mostrarh.2
portb.3=mostrarh.3
delay_ms(3)
porta.0=0
porta.1=0
porta.2=0
porta.3=1
portb.0=mostrarh.4
portb.1=mostrarh.5
portb.2=mostrarh.6
portb.3=mostrarh.7
delay_ms(3)
i=i+1
goto inicio
end.
Este es un programa para medir el desfase entre voltaje y corriente en un circuito alterno, o el factor de potencia (el coseno del angulo). ya sea para 50 Hz o 60 Hz. Tambien indica si la carga es capacitiva o inductiva. Los pines se distribuyen de la siguiente manera:
rb0 a rb3 : salida en binario a los display de 7 segmentos (pasa primero por del deco BCD/7 seg)
ra0 a ra3 : destinados a activar cada display en el momento correcto (destinados a multeplexear)
br7: entrada de la señal de voltaje. rb6: entrada de la señal de corriente
rb5: enciende led indicando carga capacitiva. rb4: enciende led indicando carga inductiva
ra7: enciende el punto del display de la izquierda, necesario para medir fp (Ej: 0.985)
ra6: enciende el punto del segundo display contando desde la izquierda, necesario para medir angulo (Ej: 85.23)
ra5: entrada que escoge si queremos medir angulo o fp (cos del angulo)
ra4: entrada que escoge si queremos medir en 50Hz o en 60Hz
Para el calculo del coseno se ocupo la aproximacion por polinomio de taylor, la cuel es exacta para varios decimales (la funcion cos de microbasic consume muchos recursos). La señal de voltaje y corriente deben entrar de forma cuadrada, pasando primero por comparadores. Se puede usar un trafo de voltaje para disminuir el voltaje, y una resistencia de bajo valor en serie para la corriente, o hacerse un trafo de corriente con un nucleo troidal. Se puede utilizar filtros para eliminar problemas con armonicos, claro que cambiaran la fase de la señal y habra que corregirlo con un circuito o por programa. Eso es todo. Adios.
![rebotando :-/](http://www.todopic.com.ar/foros/Smileys/default/bounce.gif)