Si además quieres enviarnos un Artículo para el Blog y redes sociales, pulsa el siguiente botón:
Hola Señores, tengo un problema y pregunto sobre este tema por si me podéis echar un cable con alguna sugerencia.
Resulta que tengo un PIC 16F876a que me controla unos motores mediantes relés y a su vez el PIC es controlado por un PC mediante una comunicación serie, el problema que tengo es que tras varias transmisiones entre PIC y PC, parece que el PIC pierde el norte y no contesta más....
Para que os hagáis una idea, desde el PC siempre transmito 3 bytes con los comandos, y siempre espero 2 bytes de respuesta del PIC que informan de la operación realizada, algunos comandos implican retardos, pero estos retardos se realizan posteriormente a contestar al PC por parte del PIC, y antes de volver a enviarle una orden al PIC me espero un ratito... el caso es que tras varias transmisiones ya no recibo nada del PIC.
Hay que tener en cuenta que uso una rutina enganchada al Timer0, para que el PIC haga otras tareas referentes a los fines de carrera de los motores.
He probado en comunicarme mediante puerto serie, con la aplicación que tengo desarrollada en C, como mediante con el Hyperterminal y en los dos casos sucede lo mismo, el PIC parece no seguir contestando, lo curioso es que a veces sucede antes y otras veces despues.
Alguna idea de porque, pues necesito controlar el PIC desde el PC y ya descarte i2c pues también tenía problemas.
Ciao y gracias.
Ante todo dragonet80 gracias por contestar, lo de la tierra se me había pasado, como dije en el post anterior ya le conectado pero el circuito se sigue comportando igual, y la verdad es que no sé bien porque sucede, salvo que tenga algo que ver con el Timer0 pues es lo único que me tira un poco para atrás.
Gracias
Esa desisncronización puede ser por muchos motivos.
En unas puebas que realize parecidas, cuando desconectabas el puero el pic se tenia que detener (posible caida del PC)
lo hacia correctamente. Al volver a conectar no sincronizaba.
Resolver esto no es dificil. La recepción es por interrupción y lo que hago es enviar tramas desde el PC cada 10ms y si el Pic no lo recibe en el tiempo estipulado resetea la trama. Si la trama recibida tampoco es la correcta reseta la trama recibida.
byte de master seguido de byte de esclavo,seguido de byte de proceso y finalmente el byte a ejecutar, seguido del ACK. Es la tama que uso para garantizar el correcto funcionamiento.
Es decir. El fallo lo tiene el argoritmo de recepción.
Las tierras: Habría que abrir un nuevo hilo para discutir el tema. Con tres hilos se concecta sin problemas
Con "resetear la trama" te refieres, a controlar que llegue el primer byte de una serie de bytes ? Lo haces en el PIC o en el PC ?
Podrías detallarme el proceso de forma más concreta? Tomando por ejemplo tramas de 3 bytes (b1, b2, b3) ?
En mi caso la comunicación es siempre iniciada por el PC.
Te pongo un ejemplo de lo que tu me indicas a ver si lo he entendido bien.
Master Esclavo
PC ______________ PIC
Byte Master ----------------> Recibido
Recicibo <-------------- Byte Esclavo
Byte Proceso --------------> Recibido
Byte Ejecutar --------------> Recibido
Recibido <-------------------- Ack
Entonces lo que ya no entiendo es lo de resetear si lo haces en el PIC o en el PC.
Yo necesito enviar una trama con 3 bytes (1 de comando y 2 de parámetros) y el PIC siempre debe contestar con 2 bytes.
Que en mitad del proceso se produzcan otras interrupciones que no tengan que ver con el puerto serie, no importa no?
Ciao y gracias de verdad!
Hola.
Me encontraba con el problema que cuando se desconectaba el puerto y lo volvia a conectar no se comunicaban y el pic se perdia con la recepcion.
La solución más rápida la hice enviando siempre una trama de X bytes. En mi caso 5 bytes. La trama la envia cada 10 milisegundos. Eso por parte del Pc.
Por parte del pic va recibiendo por interrupcion y procesa los paquetes cuando ha recibido los 5 bytes.
Puede que cuando entre a recibir (conectar y sesconectar el cable) de la casualidad de que solo lea los cuatro ultimos. Si no le llega en 8 milisegundos el quinto byte descarta los cuatro que han entrado y vuelve a contar la entrada de 5 Bytes (lo llamo resetear 🙂 ). Esto es una interrupcion con el Timer.
El motivo de hacerlo así es que el Pc, de vez en cuando hace de las suyas y retrasa el envio de datos o los pausa (interrupciones del PC). Si lo tienes trabajando en otras cosas lo hace bastantes veces (es como cuando queda como colgado pero no lo está)
Saludos
Okey voy entendiendo, pero algunas cosas imagino por mi poca experiencia con PIC me dejan un poco con más preguntas... espero que no te disguste que siga preguntando, ya que lo que pretendo es aclararme al máximo.
Yo en mi rutina INT_RDA, lo que hago es cada vez que recibo un byte lo guardo en un buffer e incremento el contador. Fuera en el main, cuando cierta variable "contador" vale 3, asumo que he recibido una trama entera y la proceso.
#INT_RDA
void serial_interrupt()
{
if (kbhit()) {
if (index==0) {
comando=getc();
if (es_comando(comando)) {
index++;
}
} else if (index==1) {
dato1=getc();
index++;
} else if (index==2) {
dato2=getc();
index=3;
}
}
}
Si te fijas en la rutina INT_RDA anterior, voy leyendo byte e incrementando un contador si el primer byte no es un comando, lo que hago es ir leyendo el resto, hasta que leo un byte que sea el byte de comando, para saber que comienza la ristra de 3 bytes.
Luego en el main, compruebo en un bucle infinito si la variable global "index" vale 3, y si es así proceso la trama, y contesto con 2 bytes de respuesta, ya que en mi caso siempre contesto ante cualquier trama con 2 bytes de respuesta.
Puede ser en mi caso, que el fallo sea que hay "desincronización en algun byte" y luego el PC espera recibir, y el PIC esperara más bytes y ya no se sincronizara? si fuera eso, se te ocurre alguna forma de solucionarlo?
Gracias Bactering!