Hola a todos, posteo el código de un secuenciador programable en PBP para uso en pirotécnia que estoy desarrollando y al final mis preguntas que espero alguien del foro se apiade en contestármelas,
En resumen, el programa pretende, por medio de un teclado matricial 4X4 programar el tiempo en que se debe encender cerillos electrónicos conectados a los pines del portC de un PIC16F877A, con la opción de encender leds conectados al portB para checar que la secuencia es la correcta antes de hacer detonar las cargas de los cohetes, además, los datos grabados deben permanecer aunque se interrumpa el suministro de energía, todos con una resolución de 1/10 sec.
Yo creo que casi está listo, pero hay detalles que me han estado haciendo quebrarme la cabeza y sin poder avanzar, así que espero que con su experiencia me ayuden a terminar con éste calvario que me ha resultado hacer éste código.
Todo lo he hecho en base a lo que he aprendido en éste foro, pero ahora sí estoy totalmente bloqueado, bueno, a continuación el código y al final las preguntas:
DEFINE OSC 4
A VAR PORTD.0 ;nombres para los pines de las filas
B VAR PORTD.1
C VAR PORTD.2
D VAR PORTD.3
UNO VAR PORTD.4 ;nombres para los pines de las columnas
DOS VAR PORTD.5
TRES VAR PORTD.6
CUATRO VAR PORTD.7
salida var word ;variables para cálculo de tiempo
mostrar var word
mult var word
cifra var word
cont var word
primera var word ;variables para número de salida
segunda var word
tercera var word
cuarta var word
quinta var word
sexta var word
septima var word
octava var word
PAUSE 500 ;pantalla de bienvenida
LCDOUT $FE,1, "SECUENCIADOR "
LCDOUT $FE,$C0, " PROGRAMABLE"
LCDOUT $FE,$D0, "DESARROLLADO POR"
PAUSE 2000
LCDOUT $FE,1, "URIEL F. PONCE "
PAUSE 200
inicio:
LCDOUT $FE,$90, "INGRESE DATOS " ;espera datos
PAUSE 200
LCDOUT $FE,$9D, "."
PAUSE 200
LCDOUT $FE,$9D, ".."
PAUSE 200
LCDOUT $FE,$9D, "..."
PAUSE 200
LCDOUT $FE,$9D, " "
pause 200
LOW C
IF TRES = 0 THEN ;opción de programación
LCDOUT $FE,$C0, " # DE SALIDA? ":_
LCDOUT $FE,$90, " ":PAUSE 500:GOSUB borrado
else
IF cuatro = 0 THEN ;opción datos grabados
LCDOUT $FE,$C0, "TEST O DISPARO? ":_
LCDOUT $FE,$90, " ":pause 500:gosub memoria
else
pause 10
goto inicio
endif
endif
borrado:
eeprom 0,[0,0,0,0,0,0,0,0] ;borra datos de la EEPROM
salidas:
mult=1
cifra=0
LCDOUT $FE,$C0, " # DE SALIDA? "
LCDOUT $FE,$90, " "
LOW A
IF DOS = 0 THEN lcdout $FE,$90," 1 ":salida=0:PAUSE 500:gosub tiempo
IF TRES = 0 THEN lcdout $FE,$90," 2 ":salida=1:PAUSE 500:gosub tiempo
IF CUATRO = 0 THEN lcdout $FE,$90," 3 ":salida=2:PAUSE 500:gosub tiempo
HIGH A
LOW B
IF UNO = 0 THEN lcdout $FE,$90," 4 ":salida=3:PAUSE 500:gosub tiempo
IF DOS = 0 THEN lcdout $FE,$90," 5 ":salida=4:PAUSE 500:gosub tiempo
IF TRES = 0 THEN lcdout $FE,$90," 6 ":salida=5:PAUSE 500:gosub tiempo
IF CUATRO = 0 THEN lcdout $FE,$90," 7 ":salida=6:PAUSE 500:gosub tiempo
HIGH B
LOW C
IF UNO = 0 THEN lcdout $FE,$90," 8 ":salida=7:PAUSE 500:gosub tiempo
HIGH C
pause 10
GOTO SALIDAS
ENd
tiempo:
mostrar=salida+1
LCDOUT $FE,$C0, "SALIDA:",#mostrar," "
LCDOUT $FE,$90, "INGRESE TIEMPO: " ;espera ingreso de tiempo
LOW A
IF UNO = 0 THEN mult=mult*10:cifra=((mult*cifra)/10)+0:_
lcdout $FE,$D2,#cifra
IF DOS = 0 THEN mult=mult*10:cifra=((mult*cifra)/10)+1:_
lcdout $FE,$D2,#cifra
IF TRES = 0 THEN mult=mult*10:cifra=((mult*cifra)/10)+2:_
lcdout $FE,$D2,#cifra
IF CUATRO = 0 THEN mult=mult*10:cifra=((mult*cifra)/10)+3:_
lcdout $FE,$D2,#cifra
HIGH A
LOW B
IF UNO = 0 THEN mult=mult*10:cifra=((mult*cifra)/10)+4:_
lcdout $FE,$D2,#cifra
IF DOS = 0 THEN mult=mult*10:cifra=((mult*cifra)/10)+5:_
lcdout $FE,$D2,#cifra
IF TRES = 0 THEN mult=mult*10:cifra=((mult*cifra)/10)+6:_
lcdout $FE,$D2,#cifra
IF CUATRO = 0 THEN mult=mult*10:cifra=((mult*cifra)/10)+7:_
lcdout $FE,$D2,#cifra
HIGH B
LOW C
IF UNO = 0 THEN mult=mult*10:cifra=((mult*cifra)/10)+8:_
lcdout $FE,$D2,#cifra
IF DOS = 0 THEN mult=mult*10:cifra=((mult*cifra)/10)+9:_
lcdout $FE,$D2,#cifra
IF TRES = 0 THEN lcdout $FE,$90,"DATO NO GRABADO ":pause 500:GOTO salidas
IF CUATRO = 0 THEN gosub programar
HIGH C
LOW D
IF UNO = 0 THEN lcdout $FE,$C0," "_
:lcdout $FE,$90," DATOS BORRADOS ":lcdout $FE,$D0," "_
:PAUSE 500:GOTO borrado
IF DOS = 0 THEN lcdout $FE,$D0," DATOS GRABADOS ":PAUSE 500:gosub memoria
HIGH D
pause 100
GOTO tiempo
end
programar:
LCDOUT $FE,$C0, " PROGRAMANDO "
LCDOUT $FE,$90, " "
LCDOUT $FE,$D0, " "
write salida,cifra
pause 500
goto salidas
end
memoria:
cont=0
LCDOUT $FE,$C0, "TEST O DISPARO? " ;espera opción test o disparo
LCDOUT $FE,$90, " "
LCDOUT $FE,$D0, " "
read 0,primera
read 1,segunda
read 2,tercera
read 3,cuarta
read 4,quinta
read 5,sexta
read 6,septima
read 7,octava
LOW D
IF TRES = 0 THEN lcdout $FE,$C0," "_
:lcdout $FE,$90," FUNCION TEST ":lcdout $FE,$D0," "_
:pause 500:GOSUB test
IF CUATRO = 0 THEN lcdout $FE,$C0," "_
:lcdout $FE,$90,"FUNCION DISPARO ":lcdout $FE,$D0," "_
:pause 500:gOSUB disparo
HIGH D
pause 10
GOTO MEMORIA
end
test:
cont=cont+1
TRISB.0=0
TRISB.1=0
TRISB.2=0
TRISB.4=0
TRISB.5=0
TRISB.6=0
TRISB.7=0
TRISA.5=0
LCDOUT $FE,$C0, " TEST "
LCDOUT $FE,$90, " "
LCDOUT $FE,$D0, " "
while cont>=primera
HIGH PORTB.0
WEND
while cont>=SEGUNDA
HIGH PORTB.1
WEND
while cont>=TERCERA
HIGH PORTB.2
WEND
while cont>=cuarta
HIGH PORTB.4
WEND
while cont>=quinta
HIGH PORTB.5
WEND
while cont>=sexta
HIGH PORTB.6
WEND
while cont>=septima
HIGH PORTB.7
WEND
while cont>=octava
HIGH PORTA.5
WEND
call temporizador
end
disparo:
CONT=CONT+1
TRISC=%00000000
LCDOUT $FE,$C0, " DISPARO "
LCDOUT $FE,$90, " "
LCDOUT $FE,$D0, " "
while cont>=primera
HIGH PORTC.0
WEND
while cont>=SEGUNDA
HIGH PORTC.1
WEND
while cont>=TERCERA
HIGH PORTC.2
WEND
while cont>=cuarta
HIGH PORTC.3
WEND
while cont>=quinta
HIGH PORTC.4
WEND
while cont>=sexta
HIGH PORTC.5
WEND
while cont>=septima
HIGH PORTC.6
WEND
while cont>=octava
HIGH PORTC.7
WEND
call temporizador2
end
temporizador:
LCDOUT $FE,$D0, " TODO BIEN " ;configuración de TMR0 para desbordarse cada 16.384 milisegungos
OPTION_REG = $55 ;Define la configuración de TMR0 y habilita los pullups de PORTB
INTCON = $a0 ;Habilita interrupción de TMR0
On Interrupt Goto test
end
temporizador2:
LCDOUT $FE,$D0, " TODO BIEN " ;configuración de TMR0 para desbordarse cada 16.384 milisegungos
OPTION_REG = $55 ;Define la configuración de TMR0 y habilita los pullups de PORTB
INTCON = $a0 ;Habilita interrupción de TMR0
On Interrupt Goto disparo
end
Y las preguntas son:
El uso del TMR0 es, lo acepto y espero no los moleste, una total copia de un código del foro, he estudiado un poco de eso en el un manual pero no logro entenderlo, ¿me podrían decir los valores que tengo que poner en OPTION_REG y en INTCON para que se desborde cada décima de segundo, y si no es mucha molestia, una breve explicación del mismo?
¿Cuál es el valor decimal más grande que se puede manejar con las variables WORD?, ¿Existe alguna manera de manejar valores mayores? He oído que se pueden "partir" los valores y guardarlos en dos variables, me podrían explicar cómo se hace ésto
¿Es correcta la forma en que manejé los datos en el código para obtener el valor del tiempo?, ¿Me podrían sugerir alguna otra manera?
Consideré que el comando WHILE... WEND permite que el programa siga corriendo y al mismo tiempo ejecutar los comandos dentro de la sentencia cuando se cumple la condición, ¿es ésto cierto o debo modificar el código para lograrlo?
¿Cómo se puede utilizar la opción brown-out del PIC para detectar la batería baja en PBP?, ¿Me podrían dar un ejemplo?
Eso es todo por el momento, espero no los agobie y que puedan ayudar a ésta pobre alma desesperada.