TODOPIC
Microcontroladores PIC => dsPIC => Mensaje iniciado por: superprp en 12 de Junio de 2008, 12:19:33
-
Buenas,
La UART, cuando le llegan 8bytes por ejemplo, ¿interrumpe 8 veces las interrupciones de la UART? ¿o te interrumpen una vez y en la rutina de interrupción puedes leer los 8 bytes haciendo un "while (DataRdyUART)"? y para enviar igual, puedes enviar una cadena de 8bytes con el PutsUART()?
Gracias !!
-
Saludos superprp!
Bueno no he trabajado aún con los dspic (espero hacerlo pronto)... pero la interrupción ocurre después que el buffer de recepción se ha llenado.
Es decir, tu activas la interrupción, y luego que se terminan de recibir los 8 bits del dato, el interrumpe.
En la función que atiende la interrupción puedes leer los 8bits completos con unas cuantas instrucciones sencillas... no sé qué compilador usas, así que no te puedo especificar qué instrucciones son.
Para enviar es el mismo cuento, debe haber alguna instrucción con la que envias los 8 bits al buffer... algunas instrucciones hasta te permiten enviar cadenas de texto completas... por ejemplo en ccs está el puts("cadena")... o si es una variable: putc(dato)... también con el printf puedes incluso darle formato al número.
Pero te repito, no sé cómo será exactamente con los dspic.
Espero haberte ayudado aunque sea un poquito.
Nos leemos! :mrgreen:
-
Esto es lo que dice la data:
The condition for setting the receive interrupt
flag depends on the settings specified by the
URXISEL<1:0> (UxSTA<7:6>) control bits.
a) If URXISEL<1:0> = 00 or 01, an interrupt is generated
every time a data word is transferred
from the Receive Shift register (UxRSR) to the
receive buffer. There may be one or more
characters in the receive buffer.
b) If URXISEL<1:0> = 10, an interrupt is generated
when a word is transferred from the Receive Shift
register (UxRSR) to the receive buffer, which as a
result of the transfer, contains 3 characters.
c) If URXISEL<1:0> = 11, an interrupt is set when
a word is transferred from the Receive Shift register
(UxRSR) to the receive buffer, which as a
result of the transfer, contains 4 characters (i.e.,
becomes full).
Puedes configurarlo como quieras, pero el buffer máximo es de 4 caracteres. Ten cuidado con eso porque si lo llenas y sigues recibiendo datos, el dsPIC se vuelve loco.
-
y como suelen hacerse las rutinas para leeer cuando por ejemplo te llegan por la UART comandos de 80bytes cada 200ms?? el reloj es de 10 Mhz con un PLL x8, con lo cual 80Mhz, 20MIPS. ¿Es posible hacer una rutina sin que desborde el buffer?
-
Le daría tiempo hasta tomarse una copa de ron entre byte y byte.
-
se me ha olvidado decir que el baude rate es de 9600
Esto se pone asi???:
void __attribute__((__interrupt__)) _U2RXInterrupt(void) {
atiendeRX();
IFS1bits.U2RXIF = 0;
}
o se pone un return para que salga??? igual que en atiendeRX(); en esa función tengo que poner un return? o si llega al final vuelve sola? puede dar fallos si no pongo el return???
si envio comandos pequeños de kizas 8 bytes y cada segundo o así no pasa nada, pero si envio 80 bytes y cada 500ms , a los dos segundos o así se queda colgado y deja de hacerme caso... no se porque puede ser, el pic sigue funcionando pero deja de atenderme las interrupciones de envio, y lo mismo sucede cuando me envia muchos paquetes seguidos, llega un momento en que satura el buffer, pienso yo, y deja de enviarme datos...
fuente del problema? posibles soluciones?
-
Yo utilizo el DMA para esos casos .... utilizo en este caso un buffer circular ... ahora tengo dos contadores (punteros): uno que cuenta los bytes que ingresan (RW) y otro que cuenta los bytes leidos (RR).
Cada vez que ingresa un byte RW incrementa. Esto mediante la interrupcion de RX, en esta interrupcion no leo el byte solo incremento RW, el byte se guarda automaticamente en la pila por medio del DMA. Tambien, cada vez que leo un byte RR incrementa. Si leo strings RR aumenta de acuerdo al tamaño del string.
Ahora el problema de aplicaciones con tramas muy grandes la solucioné con un RTOS. Cree una tarea que consulta RR y RW cada 10ms, si RR=RW no hay bytes en pila. Si RW > RR significa que hay uno o mas datos.
Otro problema es cuantos bytes debo leer.!! Para ello establecí un protocolo. Cuando envio una trama desde la PC al PIC: el primer byte indica la orden, comando o funcion que deseo realizar, el segundo byte indica el tamaño total de la trama, el tercer y resto de bytes son los datos, los ultimos 2 bytes son un checksum.
Entonces si RW > RR se lee el primer byte y lo guardo en un registro llamado COMANDO, luego espero nuevamente a que RW > RR, en este lapso el RTOS me permite hacer otra cosa con el micro. Cuando RW > RR leo el byte de tamaño (recuerda que a tarea entra cada 10ms), aqui espero el tiempo adecuado para recibir el resto de la trama. Nuevamente, el RTOS me permite hacer otra cosa mientras espero la trama de datos.
Pasado el tiempo de espera, leo nuevamente RW y RR, si la diferencia es igual al tamaño indicado, leo la trama y la guardo en una pila tempora creada en memoria dinámica y luego la proceso segun sea la funcion establecida por el primer byte (COMANDO).
Claro, hay tiempos de espera por si se falla la comunicación o algo parecido. Tambien hay confirmaciones, cuando recibo el primer byte, se lee, se guarda y se envia a la PC como confirmacion de recibido; procesada la trama se envia a la PC un caracter de que se recibio bien la trama, si el checksum no coincide se envia otro caracter indicando un error, etc, etc, etc.
Saludos
-
que es el DMA? como puedo implementarlo??
-
Cuando tengo que recibir varios bytes, por ejm he recibido 8 bytes de la PC, entonces apenas llega uno interrumpe al pc y atiende la rutina, dentro hace un bucle for i=1:8 y leo todos los bytes porque se que llegarán 8, como esta rutina tiene prioridad sobre las demás termino de leer los 8 bytes y luego salgo de ello.
No suelo usar rutina de interrupción para la transmisión.
saludos
-
Lo del DMA se puede hacer con el dsPIC30f4013???? en el datasheet no aparece, lo que me ocurre es que salta el bit OERR de la recepción de la UART, ¿como puedo hacer para que no salte? Eso es porque no leo lo suficientemente rápido, no?
-
Porque no me deja compilar esto????
U2STAbits.URXISEL1 = 1;
U2STAbits.URXISEL0 = 0;