TODOPIC
Microcontroladores PIC => Lenguaje Basic para microcontroladores PIC => Mensaje iniciado por: eldire en 01 de Febrero de 2010, 16:18:34
-
Buenas, despues de muchos intentos he "conseguido" (entre comillas) el comunicar a traves del 485 con pic basic. pero tengo algunos problemillas, he decir en midefensa y antes de pegar el codigo, que es mi primer programa (por decirlo asi) en pic basic y el primero para un microcontrolador.Aqui el ejemplo:
INCLUDE "modedefs.bas"
'Declaracion de Variables tanto de luz como de pin de control
control VAR porta.4 ' Pin de Control para poner en alto y bajo el 485
ledpower VAR porta.0' Luz de encendido solo parpadea 2 veces cuando tiene corriente
ledenvio var porta.1' Luz de envio se enciende cuando se realiza el envio
ledalaesc1 var portb.0' Luz de alarma de esclavo1, se enciende cuando no responde el esclavo
ledalaesc2 var portb.1' Luz de alarma de esclavo2, se enciende cuando no responde el esclavo
ledalaesc3 var portb.2' Luz de alarma de esclavo3, se enciende cuando no responde el esclavo
ledrecepcion var portb.3'Luz de recepcion, se enciende cuando pones el maestro en modo recepcion
rec VAR BYTE ' Variable para alojar los datos enviados por el esclavo
val var byte ' Variable para llevar el contador en el envio de los esclavos
falloesc1 var byte ' Variable para control de alarmas
falloesc2 var byte ' Variable para control de alarmas
falloesc3 var byte ' Variable para control de alarmas
'Iniciamos programa y nos vamos a enceder la luz de encendido x 2 veces
GOSUB poweron
controlfallo:
falloesc1=0
falloesc2=0
falloesc3=0
inicio:
'Iniciamos la variable de contador a cero y le vamos sumando uno a cada ejecución
val=0
'Comenzamos el envio a los esclavos
envio:
'Ponemos en alto el 485 para indicar que vamos a escribir en el bus.
val=val+1
HIGH control
'Vemos a que contador tenemos que llamar para saber que cadena mandar.
if (val=1) then goto esc1
if (val=2) then goto esc2
if (val=3) then goto esc3
'Cuando el valor de val llegue a 4 nos vamos a inicio
if (val=4) then goto inicio
'Volvemos a envio ya que contador no es cuatro.
goto envio
esc1:'Subrutina que se encarga del envio de la cadena al esclavo1
gosub luzenvio
serout porta.2,T9600,["A"]
pause 500
gosub recesc1
return
esc2:'Subrutina que se encarga del envio de la cadena al esclavo1
gosub luzenvio
serout porta.2,T9600,["B"]
pause 500
gosub recesc2
return
esc3:'Subrutina que se encarga del envio de la cadena al esclavo1
gosub luzenvio
serout porta.2,T9600,["C"]
pause 500
gosub recesc3
return
recesc1:'Subrutina que se encarga de la recepcion de la cadena del esclavo1
low control
high ledrecepcion
serin porta.3,t9600, rec
pause 500
low ledrecepcion
if (rec="X") then goto okesc1 ' Si ok nos vamos a otra subrutina para encender led de Ok.
if (rec<>"X") then goto koesc1' Si ko nos vamos a otra subrutina para llevar contador de fallos, si fallos 3 alarma.
return
recesc2:'Subrutina que se encarga de la recepcion de la cadena del esclavo1
low control
high ledrecepcion
serin porta.3,t9600, rec
pause 500
low ledrecepcion
if (rec="Y") then goto okesc2 ' Si ok nos vamos a otra subrutina para encender led de Ok.
if (rec<>"Y") then goto koesc2' Si ko nos vamos a otra subrutina para llevar contador de fallos, si fallos 3 alarma.
return
recesc3:'Subrutina que se encarga de la recepcion de la cadena del esclavo1
low control
high ledrecepcion
serin porta.3,t9600, rec
pause 500
low ledrecepcion
if (rec="Z") then goto okesc2 ' Si ok nos vamos a otra subrutina para encender led de Ok.
if (rec<>"Z") then goto koesc2' Si ko nos vamos a otra subrutina para llevar contador de fallos, si fallos 3 alarma.
return
okesc1:' Si todo Ok encendemos y apagamos una vez la luz de alarma
high control
high ledalaesc1
pause 200
low ledalaesc1
pause 200
high ledalaesc1
pause 200
low ledalaesc1
pause 200
falloesc1=" "
rec=" "'Limpiamos la variable de recibido
return ' Y volvemos.
okesc2:' Si todo Ok encendemos y apagamos una vez la luz de alarma
high control
high ledalaesc2
pause 200
low ledalaesc2
pause 200
high ledalaesc2
pause 200
low ledalaesc2
pause 200
falloesc2=" "
rec=" "'Limpiamos la variable de recibido
return ' Y volvemos.
okesc3:' Si todo Ok encendemos y apagamos una vez la luz de alarma
high control
high ledalaesc3
pause 200
low ledalaesc3
pause 200
high ledalaesc3
pause 200
low ledalaesc3
pause 200
falloesc3=" "
rec=" "'Limpiamos la variable de recibido
return ' Y volvemos
koesc1:
falloesc1=falloesc1+1
if falloesc1=5 then alarmaesc1
rec=" "
return
koesc2:
falloesc2=falloesc2+1
if falloesc2=5 then alarmaesc2
rec=" "
return
koesc3:
falloesc3=falloesc3+1
if falloesc3=5 then alarmaesc3
rec=" "
return
alarmaesc1:
high ledalaesc1
pause 1000
return
alarmaesc2:
high ledalaesc2
pause 1000
return
alarmaesc3:
high ledalaesc3
pause 1000
return
poweron:
high ledpower ' Encendemos luz de encendido
pause 200 ' Pausa de 200 milisegundos
low ledpower ' Apagamos luz de encendido
pause 200 ' Pausa de 200 milisegundos
high ledpower ' Encendemos luz de encendido
pause 200 ' Pausa de 200 milisegundos
low ledpower ' Apagamos luz de encendido
pause 200 ' Pausa de 200 milisegundos
return
luzenvio:
high ledenvio
pause 200
low ledenvio
pause 200
return
luzrecepcion:
high ledrecepcion
pause 200
low ledrecepcion
pause 200
return
end
Voy a intentar pegar el codigo de uno de los esclavos y el resto serian igual pero cambiando la cadena que reciben y la cadena que envian, si no puedo lo pego en otro post a continuacion de este.
INCLUDE "modedefs.bas"
control VAR porta.4 ' Pin de Control para poner en alto y bajo el 485
ledpower VAR porta.0' Luz de encendido solo parpadea 2 veces cuando tiene corriente
ledenvio var porta.1' Luz de envio se enciende cuando se realiza el envio
ledrecepcion var portb.3'Luz de recepcion, se enciende cuando pones el esclavo en modo recepcion
ledalaesc1 var portb.0' Luz de alarma de esclavo1, se enciende cuando ok envio del maestro
rec VAR BYTE ' Variable para alojar los datos enviados por el maestro
gosub poweron
inicio:
low control
high ledrecepcion
serin porta.3,t9600, rec
low ledrecepcion
if (rec="A") then okmaestro
if (rec<>"A") Then komaestro
gosub inicio
okmaestro:
high control
gosub ok1
gosub luzenvio
Serout porta.2,t9600,["X"]
return
ok1:' Si todo Ok encendemos y apagamos una vez la luz de alarma
high ledalaesc1
pause 200
low ledalaesc1
pause 200
high ledalaesc1
pause 200
low ledalaesc1
pause 200
rec=" "'Limpiamos la variable de recibido
return ' Y volvemos
komaestro:
low control
high ledalaesc1
pause 1000
rec=" "
return
poweron:
high ledpower ' Encendemos luz de encendido
pause 200 ' Pausa de 200 milisegundos
low ledpower ' Apagamos luz de encendido
pause 200 ' Pausa de 200 milisegundos
high ledpower ' Encendemos luz de encendido
pause 200 ' Pausa de 200 milisegundos
low ledpower ' Apagamos luz de encendido
pause 200 ' Pausa de 200 milisegundos
return
luzenvio:
high ledenvio
pause 200
low ledenvio
pause 200
return
luzrecepcion:
high ledrecepcion
pause 200
low ledrecepcion
pause 200
return
end
Ya se que el codigo es depurable y optimizable en cuanto a las subrutinas se refiere pero como ya he dicho es mi primer programa en y para un pic con basic.
Bueno el problema es que no pasa a los llamada a los siguientes esclavos, creo que el programa genera varios errores por lo menos eso es lo que dice el proteus en la simulacion, pero como es mi primera simulacion tambien tengo mis dudas.
Gracias de nuevo por leer este pedazo de post que me ha salido y por intertar ayudarme.
-
Una pregunta:
¿Cuando realizas lo siguiente
if (rec="Z") then goto okesc2 ' Si ok nos vamos a otra subrutina para encender led de Ok.
if (rec<>"Z") then goto koesc2' Si ko nos vamos a otra subrutina para llevar contador de fallos, si fallos 3 alarma.
return
saltas a las rutinas como:
koesc2:
falloesc2=falloesc2+1
if falloesc2=5 then alarmaesc2
rec=" "
return
Pero si haces un goto koesc2 y se ejecuta esta, entonces no regresas a la rutina inicial del if. ¿no deberian ser
if (rec="Z") then gosub okesc2 y
if (rec<>"Z") then gosub koesc2' esto creo que lo deberias de poner en cada llamada.
Es decir sustituir el(os) goto por gosub. De esa manera regresarias a la rutina inicial.
Fermin
-
Gracias fer_taca, de ahi creo que parte los dos stack overflow y underflow que me devuelve el proteus voy a realizar los cambios y haber como se comporta.
¿El resto de codigo le ves bien?
Gracias de nuevo
-
No lo revise a fondo.
Solo que lo anterior me chocó bastante.
Si lo corriges y te sigue dando otros fallos, ya sabes vete posteandolo y trataremos de echarte un cable.
Fermin
-
Buenas de nuevo, Fer_taca, despues de leer tu ultimo mensaje, he de decirte que tengo el siguiente problema:
He modificado el codigo para que sea más simple el funcionamiento, el cual es :
Ambos parpadean tres veces el led RA0, para saber que estan vivos, el maestro envia una "A" al esclavo, el esclavo recibe la "A" si es para el entonces envia una "Z" y el maestro vuelve al inicio. Cuando el esclavo no recibe una "A" enciende el led en RA1, lo mismo cuando el maestro no recibe la "Z" del esclavo.
Tengo el maestro y el esclavo funcionando bajo una red 485, para ver en todo momento lo que manda el esclavo y el maestro me he montado otra protoboard con un rs232 para poder conectarlo al pc y asi hacerlo de sniffer. Pues bueno te cuento, el tema es que la comunicacion desde el maestro al esclavo es correcta, llegando a este la cadena que tiene que llegar. El esclavo la procesa y entonces envia la cadena que esta esperando el maestro, lo que pasa es que en la entrada del rx del maestro me esta llegando null, con lo cual el maestro no puede verificar la respuesta del esclavo. Voy a adjuntar el esquema de conexion del maestro, el esclavo y el bus de comunicaciones de 485, pare ver si hay algun problema .
De nuevo gracias por vuestra ayuda.
(http://img94.imageshack.us/img94/1677/esquemat.jpg)
Tambien adjunto los codigos fuentes de pbp , tanto del maestro como del esclavo.
Maestro
INCLUDE "modedefs.bas"
control VAR porta.4
led VAR porta.0
led2 var porta.1
rec VAR BYTE
Gosub power
inicio:
high control
serout porta.2,T2400,["A"]
pause 200
low control
serin porta.3,T2400, rec
if (rec="Z") then
gosub ok
else
high led2
endif
goto inicio
ok:
low led2
high led2
pause 200
low led2
goto inicio
power:
high led
pause 200
low led
pause 200
high led
pause 200
low led
pause 200
high led
pause 200
low led
return
end
ESCLAVO
INCLUDE "modedefs.bas"
control VAR porta.4
led VAR porta.0
led2 var porta.1
rec VAR BYTE
gosub encendido
inicio:
low control
serin porta.3,T2400, rec
pause 200
if (rec="A") then
gosub reciboa
else
high led2
endif
goto inicio
reciboa:
low led2
high control
serout porta.2,T2400, ["Z"]
high led
pause 100
low led
rec=0
goto inicio
encendido:
high led
pause 200
low led
pause 200
high led
pause 200
low led
pause 200
high led
pause 200
low led
return
end