Otra cosa el PIC16F887 tiene comparadores analogicos.
¿Le dices al programa que los deshabilite y deje el puerto como digital? Fijate que hay una intruccion ANsel= = de por medio que alguna vez has eliminado en el programa.
Define CLOCK_FREQUENCY = 4 'Frecuencia del reloj en Mhz
TRISA = %11111111
TRISB = %00000000
main:
'WaitMs 40
PORTB = 0
While PORTA <= 3
If PORTA.0 = 1 Then
PORTB.0 = 1
Else
PORTB.0 = 0
'WaitMs 40
Endif
If PORTA.1 = 1 Then
PORTB.1 = 1
Else
PORTB.1 = 0
'WaitMs 40
Endif
If PORTA.2 = 1 Then
PORTB.2 = 1
Else
PORTB.2 = 0
'WaitMs 40
Endif
If PORTA.3 = 1 Then
PORTB.3 = 1
Else
PORTB.3 = 0
'WaitMs 40
Endif
If PORTA.4 = 1 Then
PORTB.4 = 1
Else
PORTB.4 = 0
'WaitMs 40
Endif
Wend
Goto main
End
Por que no pruebas a eliminar las eliminar las lineas del endifDefine CLOCK_FREQUENCY = 4 'Frecuencia del reloj en Mhz
Define SIMULATION_WAITMS_VALUE = 1 'Ignora los valores de Waitms
Dim estado As Byte
Dim estado_ra0 As Byte
Dim estado_ra1 As Byte
Dim estado_ra2 As Byte
Dim estado_ra3 As Byte
Dim estado_ra4 As Byte
TRISA = %11111111
TRISB = %00000000
main:
'Define SIMULATION_WAITMS_VALUE = 1 'Ignora los valores de Waitms
'WaitMs 40
PORTB = 0
estado = 0
estado_ra0 = 0
estado_ra1 = 0
estado_ra2 = 0
estado_ra3 = 0
estado_ra4 = 0
inicio:
p_0: If estado_ra0 = 0 Then
If PORTA.0 = 1 Then
estado = estado + 1
estado_ra0 = 1
If estado >= 3 Then Goto p_1 Else PORTB.0 = 1
Else
PORTB.0 = 0
Endif
Else
If estado_ra0 = 1 Then
If PORTA.0 = 1 Then
If estado >= 3 Then Goto p_1 Else PORTB.0 = 1
Else
estado_ra0 = 0
estado = estado - 1
Endif
Endif
Endif
p_1: If estado_ra1 = 0 Then
If PORTA.1 = 1 Then
estado = estado + 1
estado_ra1 = 1
If estado >= 3 Then Goto p_2 Else PORTB.1 = 1
Else
PORTB.1 = 0
Endif
Else
If estado_ra1 = 1 Then
If PORTA.1 = 1 Then
If estado >= 3 Then Goto p_2 Else PORTB.1 = 1
Else
estado_ra1 = 0
estado = estado - 1
Endif
Endif
Endif
p_2: If estado_ra2 = 0 Then
If PORTA.2 = 1 Then
estado = estado + 1
estado_ra2 = 1
If estado >= 3 Then Goto p_3 Else PORTB.2 = 1
Else
PORTB.2 = 0
Endif
Else
If estado_ra2 = 1 Then
If PORTA.2 = 1 Then
If estado >= 3 Then Goto p_3 Else PORTB.2 = 1
Else
estado_ra2 = 0
estado = estado - 1
Endif
Endif
Endif
p_3: If estado_ra3 = 0 Then
If PORTA.3 = 1 Then
estado = estado + 1
estado_ra3 = 1
If estado >= 3 Then Goto p_4 Else PORTB.3 = 1
Else
PORTB.3 = 0
Endif
Else
If estado_ra3 = 1 Then
If PORTA.3 = 1 Then
If estado >= 3 Then Goto p_4 Else PORTB.3 = 1
Else
estado_ra3 = 0
estado = estado - 1
Endif
Endif
Endif
p_4: If estado_ra4 = 0 Then
If PORTA.4 = 1 Then
estado = estado + 1
estado_ra4 = 1
If estado >= 3 Then Goto p_0 Else PORTB.4 = 1
Else
PORTB.4 = 0
Endif
Else
If estado_ra4 = 1 Then
If PORTA.4 = 1 Then
If estado >= 3 Then Goto p_0 Else PORTB.4 = 1
Else
estado_ra4 = 0
estado = estado - 1
Endif
Endif
Endif
Goto inicio
End
device 16f84
Dim cont As Byte
Dim estado_ra0 As porta.0
Dim estado_ra1 As porta.1
Dim estado_ra2 As porta.2
Dim estado_ra3 As porta.3
Dim estado_ra4 As porta.4
TRISA = %11111111
TRISB = %00000000
porta = 0
portb = 0
estado_ra0 = 0
estado_ra1 = 0
estado_ra2 = 0
estado_ra3 = 0
estado_ra4 = 0
Repite:
call miracont
if cont >= 3 then goto repite
delayms 10
if porta.0 = 1 then
portb.0 = 1
else
portb.0 = 0
endif
Sigue1:
call miracont
if cont >= 3 then goto sigue1
delayms 10
if porta.1 = 1 then
portb.1 = 1
else
portb.1 = 0
endif
Sigue2:
call miracont
if cont >= 3 then goto sigue2
delayms 10
if porta.2 = 1 then
portb.2 = 1
else
portb.2 = 0
endif
Sigue3:
call miracont
if cont >= 3 then goto sigue3
delayms 10
if porta.3 = 1 then
portb.3 = 1
else
portb.3 = 0
endif
Sigue4:
call miracont
if cont >= 3 then goto sigue4
delayms 10
if porta.4 = 1 then
portb.4 = 1
else
portb.4 = 0
endif
goto repite
Miracont:
if porta.0 = 1 then estado_ra0 = 1 : else estado_ra0 = 0
delayus 50
if porta.1 = 1 then estado_ra1 = 1 : else estado_ra1 = 0
delayus 50
if porta.2 = 1 then estado_ra2 = 1 : else estado_ra2 = 0
delayus 50
if porta.3 = 1 then estado_ra3 = 1 : else estado_ra3 = 0
delayus 50
if porta.4 = 1 then estado_ra4 = 1 : else estado_ra4 = 0
delayus 50
cont = (estado_ra0 + estado_ra1 + estado_ra2 + estado_ra3 + estado_ra4)
delayms 10
return
end
acavo de prebar el hex de dogflu66 en mi placa (la easypic6) y tiene basicamente los mismos osea supongamos ke le doy en este orden pulsador 1, 2 ,3 ,4 ,5 pues se enciende en portb el led 1, 2, y lla no mas pero si suelto el 1 y 2 el 3, 4 ,5 siguen apagados hasta ke no libero un pulsador y entonces se enciende de golpe los dos restantes ya ke el programa se keda con tres peticiones pero no tiene ninguna prioridad para para cual de ellos dejar encendida o apagada. esto se podria solucionar con la situacion real ke seria una sonda con por ejemplo el ds1820 o lm35 y le dariamos paso al deposiro conectado a porta mas frio
Por desgracia aquí hay que especificarlo todo. Posiblemente lo más fácil seria que sigan los últimos estados hasta que solo queden 2 teclas pulsadas de nuevo y, solo entonces se actualice el sistema.
device 16f84
Dim cont As Byte
Dim estado_ra0 As porta.0
Dim estado_ra1 As porta.1
Dim estado_ra2 As porta.2
Dim estado_ra3 As porta.3
Dim estado_ra4 As porta.4
TRISA = %11111111
TRISB = %00000000
porta = 0
portb = 0
estado_ra0 = 0
estado_ra1 = 0
estado_ra2 = 0
estado_ra3 = 0
estado_ra4 = 0
Repite:
call miracont
if cont >= 3 then goto sigue1
delayms 10
if porta.0 = 1 then
portb.0 = 1
else
portb.0 = 0
endif
Sigue1:
call miracont
if cont >= 3 then goto sigue2
delayms 10
if porta.1 = 1 then
portb.1 = 1
else
portb.1 = 0
endif
Sigue2:
call miracont
if cont >= 3 then goto sigue3
delayms 10
if porta.2 = 1 then
portb.2 = 1
else
portb.2 = 0
endif
Sigue3:
call miracont
if cont >= 3 then goto sigue4
delayms 10
if porta.3 = 1 then
portb.3 = 1
else
portb.3 = 0
endif
Sigue4:
call miracont
if cont >= 3 then goto repite
delayms 10
if porta.4 = 1 then
portb.4 = 1
else
portb.4 = 0
endif
goto repite
Miracont:
if porta.0 = 1 then estado_ra0 = 1 : else estado_ra0 = 0
delayus 50
if porta.1 = 1 then estado_ra1 = 1 : else estado_ra1 = 0
delayus 50
if porta.2 = 1 then estado_ra2 = 1 : else estado_ra2 = 0
delayus 50
if porta.3 = 1 then estado_ra3 = 1 : else estado_ra3 = 0
delayus 50
if porta.4 = 1 then estado_ra4 = 1 : else estado_ra4 = 0
delayus 50
cont = (estado_ra0 + estado_ra1 + estado_ra2 + estado_ra3 + estado_ra4)
delayms 10
return
end
Si, es que en mi primer programa cuando había más de dos teclas pulsadas no se encendía ningún otro led, pero si se apagaba el de la tecla que se dejara de pulsar siempre y cuando estuviera previamente encendido. Me explico: Si pulso 4 teclas y las mantengo pulsadas tendré dos led encendidos correspondientes estos a las dos teclas que se pulsaron en primer lugar, si dejo de pulsa una tecla seguiré teniendo tres teclas pulsadas, pero si esta tecla ultima que deje de pulsar, de inicio provoco un encendido de led, este led se apagaría incluso manteniendo tres teclas pulsadas, con lo que el resultado seria de quedar un led encendido. Esto quiere decir que se mantendría el refresco de los led al soltar teclas pero no al pulsarlas. ¡Uf!, que parrafada me salió. :mrgreen:
bueno pues el problema este me parece ke se resiste a la perfeccion ya ke todos los intentos de registrar todas las situaciones de los pulsadores siempre hay algo ke se escapa por ejemplo entiendo ke cuando estan los 5 pulsadores activados con dos led encendidos cuando dejamos de pulsar 2, ke no se encienda otro de los libre ya ke no hay ningun criterio ke gestione eso pero lo ke no entiendo es por ke no se apaga el led ke se le ha desactivado su pulsador !!sele olvida acaso al programa de revisar eso?
Si, es que en mi primer programa cuando había más de dos teclas pulsadas no se encendía ningún otro led, pero si se apagaba el de la tecla que se dejara de pulsar siempre y cuando estuviera previamente encendido. Me explico: Si pulso 4 teclas y las mantengo pulsadas tendré dos led encendidos correspondientes estos a las dos teclas que se pulsaron en primer lugar, si dejo de pulsa una tecla seguiré teniendo tres teclas pulsadas, pero si esta tecla ultima que deje de pulsar, de inicio provoco un encendido de led, este led se apagaría incluso manteniendo tres teclas pulsadas, con lo que el resultado seria de quedar un led encendido. Esto quiere decir que se mantendría el refresco de los led al soltar teclas pero no al pulsarlas. ¡Uf!, que parrafada me salió. :mrgreen:
A vale ya entiendo! Que aun teniendo 3 pulsados, si unos de los que ha soltado tenia la salida activada se desactiva! Ya lo he comprobado al simularlo. Pero cual es el problema de eso? En tu 2º programa, de no ser el resultado buscado ya esta arreglado al igual que en el mio :?bueno pues el problema este me parece ke se resiste a la perfeccion ya ke todos los intentos de registrar todas las situaciones de los pulsadores siempre hay algo ke se escapa por ejemplo entiendo ke cuando estan los 5 pulsadores activados con dos led encendidos cuando dejamos de pulsar 2, ke no se encienda otro de los libre ya ke no hay ningun criterio ke gestione eso pero lo ke no entiendo es por ke no se apaga el led ke se le ha desactivado su pulsador !!sele olvida acaso al programa de revisar eso?
Eso que dices no es lo que ha comentado dogflu en su ultimo post?
Un saludo!
program ecli
trisa = %11111
trisb = %00000000
portb = %00000000
porta = %00000
main:
while (porta.0 + porta.1 + porta.2 + porta.3) <=2
if porta.0 = 1 then portb.0 = 1 else portb.0 = 0 delay_ms(100)
end if
if porta.1 = 1 then portb.1 = 1 else portb.1 = 0 delay_ms(100)
end if
if porta.2 = 1 then portb.2 = 1 else portb.2 = 0 delay_ms(100)
end if
if porta.3 = 1 then portb.3 = 1 else portb.3 = 0 delay_ms(100)
end if
if porta.4 = 1 then portb.4 = 1 else portb.4 = 0 delay_ms(100)
end if
wend
end.
Bueno, esto que dices hay que valorarlo, si son activaciones de relés o líneas de datos lentas no se notara, ......
Al entrar en el hilo ya estaba muy avanzado, pero pude ver al principio un error en el primer programa, lo que ocurre es que se corrigió en los programas sucesivos por lo que no le di importancia, así que para evitar seguir haciendo referencia a ese programa con el susodicho error lo indico y lo corrijo en el.
Trisa = %11111 ‘Parte del puerto A como entradas
Trisb = %00000000
Portb = %00000000
Porta = %00000 ‘Esto se definió como entradas y aquí se trata como salidas?.
Es contradictorio y puede producir efectos indeseables. Al definir parte del puerto como entrada Trisa = %11111 y luego forzarlo a un estado predeterminado Porta = %00000, esto es algo contradictorio y puede hacer que algún compilador decida redefinir el puerto como salidas. O puede que el compilador lo defina como entrada o como salida según se haga uso de él, esto último puede que haga que funcione el código pero el derroche de memoria a mi parecer no lo justifica.
Hola bigluis, la definición de puertos y programación de módulos en general en el Basic del PSI no tiene lugar predeterminado, se suele colocar fuera del main para no estar reprogramando continuamente el modulo, esto hace que se pierda tiempo de ejecución con código redundante. En Microbasic desde luego no tengo ni idea de que es mejor.
Huy como ha avanzado esto, llevo 3 dias con un gripazo de muerte :5] :5] :oops: :oops: :oops: y cuando entro de nuevo está casi resuelto el problema. pero tengo una observacion:
...
El error real que se comete es que estas dando una orden innecesaria, simplemente mandas a cero todos los pines que estan como salida.
...
...
El error real que se comete es que estas dando una orden innecesaria, simplemente mandas a cero todos los pines que estan como salida.
...
Lamento decirte que eso no es un error, es una forma de inicializar el registro del puerto b con un valor, y te aseguro por experiencia propia, que hay veces que sin tener eso escrito, he tenido programas al iniciar el programa porque no hacia lo esperado.
Un saludo!
Al entrar en el hilo ya estaba muy avanzado, pero pude ver al principio un error en el primer programa, lo que ocurre es que se corrigió en los programas sucesivos por lo que no le di importancia, así que para evitar seguir haciendo referencia a ese programa con el susodicho error lo indico y lo corrijo en el.
Trisa = %11111 ‘Parte del puerto A como entradas
Trisb = %00000000
Portb = %00000000
Porta = %00000 ‘Esto se definió como entradas y aquí se trata como salidas?.
Es contradictorio y puede producir efectos indeseables. Al definir parte del puerto como entrada Trisa = %11111 y luego forzarlo a un estado predeterminado Porta = %00000, esto es algo contradictorio y puede hacer que algún compilador decida redefinir el puerto como salidas. O puede que el compilador lo defina como entrada o como salida según se haga uso de él, esto último puede que haga que funcione el código pero el derroche de memoria a mi parecer no lo justifica.
Hola bigluis, la definición de puertos y programación de módulos en general en el Basic del PSI no tiene lugar predeterminado, se suele colocar fuera del main para no estar reprogramando continuamente el modulo, esto hace que se pierda tiempo de ejecución con código redundante. En Microbasic desde luego no tengo ni idea de que es mejor.
Supongo que estas cometiendo un error, ya que PORTA y TRISA son registros completamente distintos, lo que quiero decir es que, es muy poco probable que el compilador los confunda.
Supongo que tu error es que crees que ambos son el puerto, pero no es así, cuando defines un valor en PORTA, no defines el valor al puerto a sino al registro que esta relacionado con el al que los fabricantes han llamado PORTA, cundo defines un valor a TRISA, tampoco le defines el valor al puerto, sino a un registro llamado TRISA que se encarga de decidir si cada pin es de entrada o de salida, si lo tradujesemos serían puertos triestado.
El error real que se comete es que estas dando una orden innecesaria, simplemente mandas a cero todos los pines que estan como salida.
Bueno en principio para lo que planteas creo que es mas que suficiente con el 16F887.
Si quieres utilizar 8 entradas -8 salidas pues ya sabes en los ejempls hemos puesto 4 pues seria añadir los restantes para las i/o que quedan.
Respecto a las prioridades pues segun sean así deberan ser las condiciones de test y de accion.
Por ultimo por ejemplo para el Pic Simulator IDE que no he probado me imagino que es con las correspondientes instrucciones TRIS(puerto)= 0 para salida y =1 cuando sean entradas.
Con el compilador proton tambien es asi.
Te digo que creo que es asi por que la version que tengo de PSI es la 6.65 y no soporta tu micro, en el momento que necesite utilzar alguno de la serie 16F88x me actualizare la version.
Fermin
Podrias utilizar para esos menesteres el PIC16F84 o 16F84A estos solo tiene I/O digitales, sin dada adicional, aunque estan en proceso de dejarse de fabricar, creo.
Un sustituto natural a ellos puede ser el PIC16F88
Fermin
amigo bigluis he compilado los programas ke has posteado con mikrobasic ya ke con el compolador de pic simulator ide me da fallo en la linea de while 1
pero bueno al probarlos he obserbado los siguientes problemas y es ke se activan hasta tres salidas simultaneas en portb y lo he solucionado poniendo <=1 pero pasa ke al pulsar pa1 pues pb1, pa2 pues pb2 y si pulso el resto pues no se encienden mas pero si suelto el porta1 y 2 ademas de no encender otros portb solicitados no se apagan los dos ke dejaron de estar solicitados
program salidas_entradas
' Declarations section
dim aux as byte
main:
TRISA=255
TRISB=0
while 1
Delay_ms(40) 'Tiempo necesario para evitar rebotes
'Este retardo debe de ir arriba del if, para evitar los errores.
if (porta.0 + porta.1 + porta.2 + porta.3 + porta.4 + porta.5 + porta.6 + porta.7) <= 2 then
'Si hay activo dos o menos pulsador entonces
PORTB = PORTA 'PORTB sera igual a PORTA haciendo que se enciendan las salidas necesarias
end if 'de lo contrario se mantendran encendidas las salidas que estaban activas y las demas no se encenderan
wend
end.program salidas_entradas
' Declarations section
dim contador,i,aux as byte
main:
CMCON=7 'apagamos comparadores analogicos
VREN_bit=0 'deshabilitamos modulo Vref
TRISA=255 'Puerto A como entrada
TRISB=0 'Puerto B como Salida
PORTB=0 'Limpiamos el puerto B.
while 1
contador=0 'iniciamos valor del contador en 0
for i=0 to 7 'Para i desde 0 hasta 7
if (PORTA.i) and (not contador.1) then
'Si el bit i del puerto A es 1 y contador es menor o igual a 2
PORTB.i=1 'El bit i del puerto B sera 1
contador=contador+1 'y el contador incrementara su valor
else 'de lo contrario
PORTB.i=0 'el bit i del puerto B sera 0
end if
next i
if not contador.1 then continue end if 'si contador es menor a 2 regresar al incio del bucle
while(PORTB and PORTA) = PORTB wend 'mientras se mantengan encendidos los dos bits que inicialmente
'estaban encendidos en PORTA no habra cambio de estado en PORTB
'de lo contrario podra haber cambio de estado en PORTB dando
'prioridad a los bits mas bajos
wend
end.if PORTA.i and contador<=2if (PORTA.i) and (not contador.1) thencontador.1if contador.1 then 'en MirkroBasic
if(contador.1) //En MikroC
BTFSS contador,1 'en Asamblerif (not contador.1) then 'en MirkroBasic
if(!contador.1) //En MikroC
BTFSC contador,1 'en AsamblerLo que haces con esto es preguntar si el bit 1 del registro contador no vale 1, por lo tanto preguntas si el bit1 del registro contador vale 0.if contador.1 = 0 then
if contador.1 = 1 thenPero el complidador generará más código que si haces lo primero.if (PORTA.i) thensi i=0 preguntarás, si el bit 0 del registro PORTA es igual a 1.if (PORTA.i) and (not contador.1) thenestarás preguntando si el bit i (i puede tener valores desde 0 hasta 7) del registro PORTA es igual a 1 y si el bit1 del registro contador es igual a 0 (lo que es equivalente a preguntar si contador es mayor o igual a 2).for x = 0 to 2
for test=0 to 7
portb.test = 1
delay_ms(20)
portb.test = 0
next test
for test=7 to 0 step -1
portb.test = 1
delay_ms(20)
portb.test = 0
next test
next x
for aux =0 to 2 'Para aux desde 0 hasta 2
i=0 'igualar i a 0
while i<7 'mientras i sea menor a 7
Delay_100ms 'Retardo de 100 ms, esta linea es similar a Delay_ms(100) pero cuano
'se utiliza el mismo retardo mas de una vez esta linea permite ahorrar reursos
PORTB=PORTB<<1 'rotar hacia la izquierda los bits de PORTB
i=i+1 'incrementar i en 1
wend
while i>0 'mientras i sea mayor a 0
Delay_100ms 'Retardo de 100 ms
PORTB=PORTB>>1 'rotar hacia la derecha los bits de PORTB
i=i-1 'decrementar i en 1
wend
next aux PORTB=0
while 1
for i=0 to 7 'Para i desde 0 hasta 7
if PORTA=PORTB then goto L1 end if
if PORTA.i then
'Si el bit i del puerto A es 1 y contador es menor o igual a 2
PORTB.i=1 'El bit i del puerto B sera 1
if aux <> portb then 'si auxiliar es distinto de PORTB
contador=contador+1 'el contador incrementara su valor
end if
end if
if contador.1 then 'si el contador es menor a 2.
goto L2 'ir a la linea L2
end if
next i
while PORTB=PORTA 'mientras PORTB sea igual a PORTA
L1: wend 'mantenerse preguntando hasta que ocurra lo contrario
aux=portb and porta 'aux sera igual a la operacion and entre PORTA y B
goto L3 'ir a la linea L3
do
L2: aux = PORTB and PORTA 'aux sera igual a la operacion and entre PORTA y B
loop until aux <> PORTB 'mientras se mantengan encendidos los dos bits que inicialmente
'estaban encendidos en PORTA no habra cambio de estado en PORTB
'de lo contrario podra haber cambio de estado en PORTB dando
'prioridad a los bits mas bajos
L3: portb = aux 'PORTB sera igual a aux
if aux then 'si auxiliar no es cero
contador=1 'contador sera igual a 1
else 'de lo contrario
contador=0 'contador sera igual a 0
end if
wendPrint At 3,-3, "led1 : ON -OFF- "
Print At 4,-3, "led2 : -ON- OFF "
Lcd_Out(3,3,"led1 : ON -OFF- ")
Lcd_Out(3,4,"led2 : -ON- OFF ")