TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: yopepe en 30 de Agosto de 2009, 23:15:33
-
Antes que nada, aprovecho esta humilde primer contribución para agradecer enormemente a todas las personas que forman parte del foro, tanto los que nos ayudan con sus conocimientos de forma desinteresada, como a los que con sus dudas nos hacen pensar y quizás aprender algo nuevo.
En este momento estoy dedicando mi tiempo disponible al desarrollo de un proyecto que involucra RFid (muy similar a la gran labor del amigo NANO1985, con la adición de escritura en el transponder) y otras cuestiones, entre las cuales se encuentra la ya famosa causante de desvelos interfaz PC <-> PIC. Si bien ya estamos bastante "amigados" con este útil recurso gracias a los pioneros como J1M y otros tantos, que pusieron su esfuerzo para sacar este tema de la oscuridad, y por ello casi sin mayores problemas podemos ponerla a funcionar, el hecho de que es un tema con muchas idas y venidas nos lleva a armar nuestro sistema en base a un montón de recursos genéricos de los cuales muchas veces sabemos poco y nada del funcionamiento. Este último detalle es el que ineludiblemente tarde o temprano nos va a pasar factura en algún aspecto de nuestro proyecto, digamos velocidad, utilización de recursos, etc. Si bien es casi una locura desarrollar todos y cada uno de los aspectos de una comunicación PC <-> PIC, existen algunos puntos en los que uno puede meter mano para hacer un "tuning" más acorde a nuestra aplicación y conseguir resultados notablemente mejores. En esta ocasión vamos a hablar del que, en mi caso, me resultó más problemático; como reza el título, la memoria RAM del microcontrolador.
Acotación al margen: todo lo que se explica a continuación es válido para los dispositivos 18F2455, 18F2550, 18F4455 y 18F4550 en USB modo full speed. En el caso de utilizar uno diferente, los conceptos aplicados son exactamente los mismos, aunque las modificaciones del código deberán ser cambiadas para el caso particular. Ah, no se asusten por lo largo, es fácil ;-).
Todo el código para el microcontrolador está realizado en CCS v 4.088, así como lo ejemplos tomados para modificación. Lo aquí planteado surge después de haber leído el post de Modulay http://www.todopic.com.ar/foros/index.php?topic=21145.40 (http://www.todopic.com.ar/foros/index.php?topic=21145.40)
Ahora sí, pasemos a lo que nos compete. Nos vamos a centrar principalmente en el archivo pic18_usb.h, el cual es en el que se define la capa fisíca USB para los dispositivos de la familia PIC18F.
Como antes dijimos, las cosas diseñadas para ser generales son muy cómodas porque no tenemos que preocuparnos de entender como funcionan, pero justamente por eso su funcionamiento no es óptimo, este es el caso del archivo pic18_usb.h. Primero, vamos a tratar de entender un poco como reserva y realiza la asignación de memoria.
Según el datasheet que nos proporciona Microchip (como dice RedPic, en los datasheet esta todo, algo en lo que coincido totalmente :mrgreen:), la estructura de memoria RAM es la siguiente:
(http://img194.imageshack.us/img194/5808/ram1c.th.jpg) (http://img194.imageshack.us/i/ram1c.jpg/)
Figura 1.
Como podemos ver, la zona de los bancos 4 a 7 es lo que se conoce como USB RAM. Sin embargo esto no significa que esa memoria sea exclusiva para el USB, si leemos en la hoja de datos, nos dice que si bien esta es una zona de memoria especial debido a que es "dual port" (puede ser accedida tanto por el core del microcontrolador como por el SIE que gobierna el USB), su asignación no es fija y depende de nuestra aplicación pudiéndose utilizar tanto para datos como para cuestiones relacionadas al USB. Con esto en mente nos vamos directo y sin escalas al código del archivo pic18_usb.h, en el cual nos encontramos, en orden de aparición, con lo siguiente:
#elif ((getenv("DEVICE")=="PIC18F2455") || (getenv("DEVICE")=="PIC18F2550") || \
(getenv("DEVICE")=="PIC18F4455") || (getenv("DEVICE")=="PIC18F4550"))
#define __USB_4550__
#define USB_TOTAL_BUFFER_SPACE ((int16)0x300)
#define USB_MAX_NUM_ENDPOINTS 16
Esta es la parte de la definición para el caso de los dispositivos de nuestro interés en este caso. Como podemos ver, en USB_TOTAL_BUFFER_SPACE guarda un valor (0x300) que representa la máxima cantidad de posiciones de memoria "disponibles para buffer" (de 500h a 7FFh en figura 1). Vemos que no se está teniendo en cuenta las posiciones de memoria de 400h hasta 4FFh, más adelante veremos porque.
Lo siguiente con lo que nos encontramos es esto:
#define USB_BUFFER_NEEDED (USB_EP0_TX_SIZE+USB_EP0_RX_SIZE+USB_EP1_TX_SIZE+USB_EP1_RX_SIZE+USB_EP2_TX_SIZE+USB_EP2_RX_SIZE+USB_EP3_TX_SIZE+USB_EP3_RX_SIZE+USB_EP4_TX_SIZE+USB_EP4_RX_SIZE+USB_EP5_TX_SIZE+USB_EP5_RX_SIZE+USB_EP6_TX_SIZE+USB_EP6_RX_SIZE+USB_EP7_TX_SIZE+USB_EP7_RX_SIZE+USB_EP8_TX_SIZE+USB_EP8_RX_SIZE+USB_EP9_TX_SIZE+USB_EP9_RX_SIZE+USB_EP10_TX_SIZE+USB_EP10_RX_SIZE+USB_EP11_TX_SIZE+USB_EP11_RX_SIZE+USB_EP12_TX_SIZE+USB_EP12_RX_SIZE+USB_EP13_TX_SIZE+USB_EP13_RX_SIZE+USB_EP14_TX_SIZE+USB_EP14_RX_SIZE+USB_EP15_TX_SIZE+USB_EP15_RX_SIZE)
bastante feo de leer, lo sé :D, pero no es más que sumar el tamaño de todos los endpoints y guardarlos en USB_BUFFER_NEEDED. El valor de USB_BUFFER_NEEDED es la cantidad total de bytes de RAM que vamos a necesitar para buffer
Directamente después vemos que realiza una comparación entre los 2 valores anteriores (USB_BUFFER_NEEDED y USB_TOTAL_BUFFER_SPACE) para determinar si la cantidad de memoria que en nuestro programa asignamos a endpoints (con #define USB_EPn_TX_SIZE y #define USB_EPn_RX_SIZE para cada endpoint) "cabe" en el valor que declaramos con USB_TOTAL_BUFFER_SPACE.
#if (USB_BUFFER_NEEDED > USB_TOTAL_BUFFER_SPACE)
#error You are trying to allocate more memory for endpoints than the PIC can handle
#endif
Si no "cabe", nos da error al momento de compilar.
Luego, nos encontramos con algo como esto:
#reserve 0x400:0x4FF+USB_BUFFER_NEEDED
La directiva #reserve cumple la función de, como su nombre lo indica, reservar estas posiciones de memoria indicadas para que el compilador no las use para otra cosa. Vemos que la zona de descriptores de buffer la reserva completa (0x400:0x4FF, ver Figura 1) y además también reserva la cantidad de memoria contigua indicada por USB_BUFFER_NEEDED (nuestros buffers de endpoints). Ya aquí notamos un comportamiento conservador, ya que por ejemplo no importa que solo utilicemos los endpoints 0 (0 in y 0 out) y 1 (1 in y 1 out), de todas formas seguirá reservando el bloque de descriptores de buffer completo (0x400 a 0x4FF) y por esto toda la memoria que sobre en la zona de descriptores (ya que solo usamos 4 endpoints) el compilador no la va a utilizar, desperdiciándola. Al final veremos como se pueden modificar las cosas para hacer un uso más eficiente. Sin embargo, aquí no termina la cosa, si seguimos analizando el archivo nos vamos a encontrar con esto:
#define USB_BUFFER 0x500
y más abajo:
char usb_ep0_rx_buffer[USB_MAX_EP0_PACKET_LENGTH];
#locate usb_ep0_rx_buffer=USB_BUFFER
char usb_ep0_tx_buffer[USB_MAX_EP0_PACKET_LENGTH];
#locate usb_ep0_tx_buffer=USB_BUFFER+USB_MAX_EP0_PACKET_LENGTH
char usb_data_buffer[USB_TOTAL_BUFFER_SPACE-USB_MAX_EP0_PACKET_LENGTH-USB_MAX_EP0_PACKET_LENGTH];
#locate usb_data_buffer=USB_BUFFER+USB_MAX_EP0_PACKET_LENGTH+USB_MAX_EP0_PACKET_LENGTH
USB_BUFFER simplemente contiene el valor de la primera posición de memoria donde empiezan a estar los buffers de los endpoints, y por lo tanto también es la dirección que separa los buffers de los descriptores de buffer.
La directiva #locate, como también su nombre lo indica, coloca una variable en una posición de memoria especifica y además, también reserva el lugar para que el compilador no lo use. Sabiendo esto:
char usb_ep0_rx_buffer[USB_MAX_EP0_PACKET_LENGTH];
#locate usb_ep0_rx_buffer=USB_BUFFER
Coloca una variable (usb_ep0_rx_buffer) de tamaño USB_MAX_EP0_PACKET_LENGTH (64 para estos dispositivos a full speed) a partir de la posición USB_BUFFER. En criollo, asigna las posiciones de memorias necesarias para el endpoint 0 OUT, al principio de la zona de buffers.
char usb_ep0_tx_buffer[USB_MAX_EP0_PACKET_LENGTH];
#locate usb_ep0_tx_buffer=USB_BUFFER+USB_MAX_EP0_PACKET_LENGTH
Lo mismo que la anterior para el endpoint 0 IN, notar que lo pone a continuación del anterior (USB_BUFFER+USB_MAX_EP0_PACKET_LENGTH)
char usb_data_buffer[USB_TOTAL_BUFFER_SPACE-USB_MAX_EP0_PACKET_LENGTH-USB_MAX_EP0_PACKET_LENGTH];
#locate usb_data_buffer=USB_BUFFER+USB_MAX_EP0_PACKET_LENGTH+USB_MAX_EP0_PACKET_LENGTH
Acá es donde está la madre del borrego, vemos que a continuación de la anterior, asigna una variable del tamaño total de la memoria que disponemos para el usb, menos lo que ya ocupamos con el endpoint 0 IN y OUT. Es decir, no importa si usamos 1,2,3 o 16 endpoints, siempre va a ocupar toda la memoria (lo pueden ver al compilar para diferente número de endpoints de diferentes tamaños, la ram ocupada no cambia) y gracias a esto podemos llegar a estar desperdiciando hasta un 25~30% de nuestra valiosa RAM. Como podemos resolver esto, es tan fácil que parece mentira, modificando:
char usb_data_buffer[USB_TOTAL_BUFFER_SPACE-USB_MAX_EP0_PACKET_LENGTH-USB_MAX_EP0_PACKET_LENGTH];
#locate usb_data_buffer=USB_BUFFER+USB_MAX_EP0_PACKET_LENGTH+USB_MAX_EP0_PACKET_LENGTH
por
char usb_data_buffer[USB_BUFFER_NEEDED-USB_MAX_EP0_PACKET_LENGTH-USB_MAX_EP0_PACKET_LENGTH];
#locate usb_data_buffer=USB_BUFFER+USB_MAX_EP0_PACKET_LENGTH+USB_MAX_EP0_PACKET_LENGTH
Luego de esta modificación prueben de compilar cambiando los tamaños y cantidades de enpoints y verán que la RAM utilizada va cambiando acorde, además, para proyectos con pocos endpoints y pequeños tamaños disminuye drásticamente la cantidad utilizada.
Pero esto no es todo, a pesar de que este cambio es el más notorio, podemos mejorar aún más la situación. Más arriba vimos que el espacio para los descriptores de buffers se reservaba completo siempre (desde 400h hasta 4FFh), si embargo, esta cantidad de memoria se utiliza solo en el caso extremo en que utilicemos los 32 endpoints (16 in y 16 out), y todos con el modo PING-PONG activado, cosa que el compilador de CCS ni siquiera soporta (no vamos a entrar en mucho detalle de como funciona este modo, solo vamos a decir que cuando un descriptor de buffer tiene habilitado el modo PING-PONG ocupa el doble de memoria). Podemos concluir entonces que en el caso extremo (utilizando los 32 endpoints) vamos a estar ocupando solo la mitad de la memoria destinada a los descriptores de buffer (mínimo nos quedan 128 bytes libres), peor aún, si solo utilizáramos los endpoints 0 y 1 estaremos desperdiciando prácticamente todo el bloque. Es importante notar que con esta modificación no solo obtendremos mas memoria RAM para nuestro uso, sino que además esta memoria es de la "especial" y que en el caso de ser necesaria la podemos utilizar para colocar mas buffers para endpoints, ya que si necesitáramos por ejemplo 7 endpoints (7in y 7 out) de 64 bytes, con las cosas como están no nos alcanzaría la memoria, pero al realizar el cambio si podemos implementarlo (solo por dar un ejemplo). Como buenos ahorradores, vamos a resolver esto, es un poquito más complicado que lo que hicimos anteriormente, pero nada del otro mundo. Comencemos viendo como es la estructura de un descriptor de buffer, según el datasheet:
(http://img180.imageshack.us/img180/6229/30963357.th.jpg) (http://img180.imageshack.us/i/30963357.jpg/)
Figura 2.
Como indica la figura 2, cada descriptor de buffer se compone de 4 bytes, en los cuales almacena toda la información pertinente a su buffer asociado. La organización en memoria de los descriptores, para el caso en que no se utiliza el modo PING-PONG es la siguiente:
(http://img198.imageshack.us/img198/1568/bd2a.th.jpg) (http://img198.imageshack.us/i/bd2a.jpg/)
Figura 3.
Observamos que como máximo, si utilizamos los 32 endpoints (16 in y 16 out), la última posición utilizada por los descriptores llega a 47Fh, por lo que desde 480h hasta 4FFh podremos utilizarla para buffers. En el caso de utilizar aun menos endpoints, para saber cual es la primera posición que podemos utilizar hacemos una simple cuenta:
[(numero_de_endpoints_in + numeros_de_endpoints_out) * 4] = cantidad_de_posiciones_de_memoria_para_descriptores (expresion 1)
Luego pasamos el valor anterior a hexadecimal (pueden utilizar la calculadora de windows en modo científico para ello), le sumamos 400h y le restamos 1h y el valor resultante es la última posición utilizada por un descriptor, por lo que la primera que podremos utilizar será la siguiente.
Un ejemplo para que se comprenda mejor puede ser, supongamos que utilizamos 4 endpoints, 0 IN y OUT y 1 IN y OUT, el resultado de la expresión 1 será 16, pasado a hexadecimal es 10h, le sumamos 400h, nos da 410h. Esta es la primer posición libre para utilizar para buffers y por lo tanto, 410h - 1h = 40Fh será la última posición utilizada por los descriptores.
Para que quede en claro, lo que vamos a hacer al modificar es "mover el bloque de los buffers para arriba" para que en vez de comenzar en 500h, empiece en la primer posición libre después de los descriptores, y luego agrandarlo para ocupar el espacio nuevo.
Vamos a ver las 3 modificaciones que tenemos que realizar en el código, todas los trozos de código que aparecen a continuación, son los mismos que están explicados parte por parte más arriba.
Primero, debemos modificar el tamaño de la memoria reservada para descriptores, esto lo realizamos en esta parte:
#reserve 0x400:0x4FF+USB_BUFFER_NEEDED
en donde tenemos que cambiar 0x4FF por el valor que calculamos anteriormente como "última posición utilizada por los descriptores" (en el ejemplo, 40Fh, que en esta notación es 0x40F)
Segundo, debemos modificar el valor de inicio de la memoria para buffers, esto lo realizamos en esta parte:
#define USB_BUFFER 0x500
en donde debemos cambiar 0x500 por el valor que calculamos anteriormente como "primer posición libre para utilizar para buffers" (en el ejemplo, 410h, que en esta notación es 0x410)
tercero, vamos a modificar el valor total de memoria para buffers disponible, lo realizamos aquí:
#elif ((getenv("DEVICE")=="PIC18F2455") || (getenv("DEVICE")=="PIC18F2550") || \
(getenv("DEVICE")=="PIC18F4455") || (getenv("DEVICE")=="PIC18F4550"))
#define __USB_4550__
#define USB_TOTAL_BUFFER_SPACE ((int16)0x300)
#define USB_MAX_NUM_ENDPOINTS 16
en donde debemos cambiar 0x300 por el nuevo valor total de memoria, que será, el valor final de la memoria USB (0x7FF o 7FFh) menos la última posición que ocupan los descriptores, en el ejemplo seria, 0x7FF (o 7FFh) menos 0x40F (o 40Fh) igual a 0x3F0 (o 3F0h)
IMPORTANTE: esta resta deben realizarla en hexadecimal (pueden utilizar la calculadora de windows en modo científico para ello)
Listo, a compilar y a disfrutar. Para ver la diferencia con el pic18_usb.h original, y con los dos cambios explicados, les dejo unas imágenes, que valen más que mil palabras:
ANTES
(http://img440.imageshack.us/img440/2138/antes.th.jpg) (http://img440.imageshack.us/i/antes.jpg/)
DESPUES
(http://img340.imageshack.us/img340/7352/despues.th.jpg) (http://img340.imageshack.us/i/despues.jpg/)
Bueno, esto es todo por el momento, espero que les sea útil, trate de ser lo más claro posible (por eso me extendí un poco :mrgreen: ), pero si no se entiende algo no duden en preguntar.
Les saluda desde Mar del Plata, Argentina, Francisco. 8)
-
Excelente explicacion!! :mrgreen: :mrgreen:
-
Excelente aporte.
Gracias :-/
-
Magnífica aportación, mejor explicación y excelente resultado. Le pongo una chincheta. Gracias yopepe
-
Muchas gracias por el aporte!! :-/ Aparte muy bien explicado 8)
Saludos!
-
Bravo, bravo y bravo! genial y útil explicación :)
Gracias!!
-
Gran comienzo yopepe felicidades... un 25% de memoria no se saca todos los dias
-
Bueno, me alegro que haya tenido aceptación, se agradece! :mrgreen:. Esperemos que el tiempo me lo permita y pueda continuar con esta práctica del escribir que se me hace muy interesante. Un saludo a todos.
-
Wow..
Muchas gracias yopepe :-/ :-/
-
Mil millones de gracias.
Me viene al pelo!!
-
el tamaño del archivo hex antes del truco es de 14,9 kb y cuando aplico las modificaciones respectivas al driver el tamaño del hex resultante es de 15kb... en codigo maquina el tamaño aumenta?????
-
Me sacaste del horno!!! :mrgreen:
Sos un capo!
EN EL HORNO:
(http://www.todopic.com.ar/foros/imgtiny/29zuaag.png)
FUERA DEL HORNO :P:
(http://www.todopic.com.ar/foros/imgtiny/ok4toi.png)
-
Hola, para los que usan la versión 4.093 parece ser que ya está contemplado el ahorro en ram.
Tengo un programa que compilado en la 4.084 marca un 53% de ram mientras que en la 4.093 marca 14%.
He notado que la 4.093 genera más instrucciones en mi aplicación que la 4.084, pero quién sabe si sea un comportamiento generalizado.
CCS PCH C Compiler, Version 4.093 13-Nov-09 11:02
Filename: T_adq_v03.lst
ROM used: 4968 bytes (15%)
Largest free fragment is 27796
RAM used: 269 (13%) at main() level
285 (14%) worst case
Stack: 10 worst case (3 in main + 7 for interrupts)
CCS PCH C Compiler, Version 4.084 13-Nov-09 11:13
Filename: T_adq_v03.lst
ROM used: 4670 bytes (14%)
Largest free fragment is 28094
RAM used: 1093 (53%) at main() level
1106 (54%) worst case
Stack: 10 worst case (3 in main + 7 for interrupts)
-
Uff, pues sí que hay diferencias. Gracias por el dato.
Estas son las compilaciones de un proyecto en el que trabajo,
con la 4.084
(http://img5.imageshack.us/img5/4996/compilacion4084.jpg)
y con la 4.093
(http://img269.imageshack.us/img269/4558/compilacion4093.jpg)
-
Tiene pros y contras la v4.093, menos RAM pero más ROM.
Yo regresé a la 4.084 porque uso la ram USB con apuntadores, porque sé por la datasheet que está desocupada por los endpoints.
-
Me ha pasado justo lo mismo que a ti. Mi programa no cabía cuando lo compilaba con opción bootloader porque ya no cabía en la ROM, así que he tenido que volver a la 4.084
-
Buena explciacion, gracias. Pero, por mi poco conocimiento, puedo decir que los PIC18Fx550 no son capaces de utilizar todos los endpoints que tiene debido a su poca RAM. A menos que este equivocado. De todas formas, nuevamente gracias.
Salu2.
-
Buena explciacion, gracias. Pero, por mi poco conocimiento, puedo decir que los PIC18Fx550 no son capaces de utilizar todos los endpoints que tiene debido a su poca RAM. A menos que este equivocado. De todas formas, nuevamente gracias.
Salu2.
Hola Jeremy, sí se pueden usar todos los endpoints, incluso con pingpong habilitado, pero con ciertas limitantes. Hay 1024 bytes de usb ram disponibles.
Primero la tablita de los buffer descriptors ocuparía una porción del banco 4 (0x0400 a 0x047F - 128 bytes) con pingpong deshabilitado. Esta tablita indica la posición, tamaño y estado de todo endpoint ubicado del banco 4 al 7. El espacio sobrante del banco 4 se puede usar para endpoints.
El máximo número de endpoints que un dispositivo puede tener es 16. Si tienes cada endpoint con tamaño de 64 bytes entonces ocuparás 1024 bytes de ram. Pero si sobraron 128 bytes del banco 4 más 768 bytes de los bancos 5, 6 y 7 apenas si sumas los 1024 bytes.
Entonces para que quepan solo es cuestión de quitarle bytes a unos cuantos endpoints y listo... 16 endpoints en un pic.
Claro está que una aplicación que hace uso de los 16 endpoints es porque busca la máxima velocidad del bus, ya que en caso contrario un solo endpoint bien administrado basta para cualquier cosa.
Incluso en el modo isócrono que puede mandar hasta 1023 bytes estaría un poco limitado el pic, tendría que ocupar 4 bytes para el buffer descriptor del endpoint isócrono y 1020 bytes de tamaño de endpoint. Pero de que se puede... se puede. ;-)
-
Ah, claro pero me referia a todos los endpoints habiliados con envios y recibos de 64 bytes. Ocea intentando buscar la maxima velocidad pues. Es mas, eso sin contar la habilitacion de los ping pong que ni idea xD!
Salu2.
-
Ayuda!... he hecho todo lo que dicen aca pero mm me sale un error al momento de compilar... no se que sucede, espero me puedan colaborar!!
El error que sale es:
***Error112 "C:\Archivos de programa\PICC\drivers\pic18_usb.h" Line 472(1,1): Function used but not defined: ... usb_token_reset SCR=2798
Qué puedo hacer???... bueno puedo resultar algo ignorante en el aspecto, comento qué estoy realizando para complementar en algo lo que he dicho... tengo problemas con la memoria, pues no me cabe todo el programa que necesito en el pic!!!.. Estoy utilizando un PIC18F4550, y bueno, manejo GLCD y varias cosas. Despues de buscar alguna "solución" en internet a mi problema, dí con este post.
Lo que hice fue tomar un programa que ya tenía funcionando y le "adapte" lo que recomiendan en este foro, a esperas de poder comprobar todo satisfactoriamente, pero pues no me sale!!!!... Aclaro, no estoy usando para nada USB, solo necesito mas espacio de memoria!... Entonces please!!! Ayuda!!!!
Ahora me surgen varias dudas:
Qué includes o defines asociados a USB debo utilizar? Buscando por la red y también mirando los ejemplos de CCS, opte, sin experiencia en el tema alguna, por colocar lo siguiente (son las únicas directivas de USB que coloco en todo el programa):
#define USB_HID_DEVICE FALSE
#define USB_EP1_TX_ENABLE USB_ENABLE_BULK
#define USB_EP1_RX_ENABLE USB_ENABLE_BULK
#define USB_EP1_TX_SIZE 1
#define USB_EP1_RX_SIZE 1
#include <pic18_usb.h>
Espero me puedan colaborar!!!... Y Disculpas de antemano si sueno algo corto de conocimiento por lo que he dicho anteriormente. Mil gracias!!!!
Saludos desde Bogotá, Colombia!
-
Hola.
Pues si no estas usando el USB, no pongas los archivos de cabecera y listo no? :?
Saludos
-
Exacto, no incluyas archivo alguno relacionado con USB.
-
Pero entonces como haría lo del ahorro de memoria??? :(
-
Hola.
Es que es justamente eso, para ahorrar RAM cuando se usa el USB, de caso contrario, lo que tienes que hacer es optimizar variables.
-
Si no usas USB, entonces no usas la RAM USB que se declara en los archivos h.
Si no usas los archivos h, entonces tienes 2kB de RAM para tu programa.
-
Hola compañeros. Quisera saber si alguien a utilizado la función get_string usb(char *s, int max) para la comunicación por usb_cdc. Yo no entiendo como implementarla. Gracia.s
-
Hola compañeros. Quisera saber si alguien a utilizado la función get_string usb(char *s, int max) para la comunicación por usb_cdc. Yo no entiendo como implementarla. Gracia.s
Puedes estudiar su código fuente y deducir qué hace:
void get_string_usb(char* s, unsigned int max) {
unsigned int len;
char c;
--max;
len=0;
do {
c=usb_cdc_getc();
if(c==8) { // Backspace
if(len>0) {
len--;
usb_cdc_putc(c);
usb_cdc_putc(' ');
usb_cdc_putc(c);
}
} else if ((c>=' ')&&(c<='~'))
if(len<max) {
s[len++]=c;
usb_cdc_putc(c);
}
} while(c!=13);
s[len]=0;
}
-
Hola migsantiago. Graicas por tu respuesta. Te cuento que hace aproximadamente 1 semana que estoy con el tema de usb_cdc y no puedo usar la instrucción usb_cdc_getc();, no puedo obtener datos desde un programa hacia el pic, no me lee nada. Ya probee todo. Bueno, pero creo que la libreria que estoy usando esta mal editada. Estoy comparando la libreria usb_cdc.h con otra y no son similares y temo que sea eso que me este trabando. Aqui pongo la parte de la libreria que creo esta mal y mi programa. Gracias.
Esta es la parte de la libreria usb_cdc que llama la intrucción usb_cdc_getch(); y que ami no me funciona de ninguna forma.
////////////////// END USB CONTROL HANDLING //////////////////////////////////
////////////////// BEGIN USB<->RS232 CDC LIBRARY /////////////////////////////
char usb_cdc_getc(void) {
char c;
while (!usb_cdc_kbhit()) {}
c=usb_cdc_get_buffer_status_buffer[usb_cdc_get_buffer_status.index++];
if (usb_cdc_get_buffer_status.index >= usb_cdc_get_buffer_status.len) {
usb_cdc_get_buffer_status.got=FALSE;
usb_flush_out(USB_CDC_DATA_OUT_ENDPOINT, USB_DTS_TOGGLE);
}
return(c);
}
Este es mi programa, lo que hago solamente es caergar el valor del puerto y mostrarlo.
do{
usb_task();
if (usb_enumerated()){ // Espera a que el dispositivo sea enumerado por el host.
if(usb_cdc_kbhit()){ // En espera de nuevos caracteres en el buffer de recepción.
lcd_putc("\fPASO2\n");
//get_string_usb(*marco,1);
marco=usb_cdc_getc(); //¿lo que llegó fué el caracter x?
lcd_gotoxy(1,2);
lcd_putc("\fPASO3\n");
printf(usb_cdc_putc,"%c",marco);
}
// delay_ms(200);
}
}while (TRUE); // bucle infinito.
}
-
¿Cómo envías datos al com virtual desde la pc?
-
Hola de nuevo. Yo se que este tema ya está bastante tratado, pero no encuentro solución y ya no se mas que probar. Estoy mandando datos desde el Labview y en un principio solo podía mandar datos desde el pic y no al revés. Ahora de tanto toquetear, ya no me reconoce los drivers. Estoy usando Windows Vista 32 bits. Puede ser que el USB no funcione en mi notebook? Muchas gracias
#include <18F4550.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=48000000)
#include "usb_cdc.h"
#include "picUSB_CDC.h"
#rom int 0xf00000={1,2,3,4}
void main() {
int8 x;
set_tris_b(0x00);
output_b(0x00);
usb_cdc_init(); // Configuramos al puerto virtual.
usb_init(); // Inicializamos el stack USB.
while(!usb_cdc_connected()) {} // espera a detectar una transmisión de la PC (Set_Line_Coding).
do{usb_task();
if (usb_enumerated()){ // Espera a que el dispositivo sea enumerado por el host.
if(usb_cdc_kbhit()){ // En espera de nuevos caracteres en el buffer de recepción.
x=usb_cdc_getc();
output_b(x);
}
}
}while (TRUE); // bucle infinito.
//// jokelnice_cdc_enviar
}
-
Hola de nuevo. Yo se que este tema ya está bastante tratado, pero no encuentro solución y ya no se mas que probar. Estoy mandando datos desde el Labview y en un principio solo podía mandar datos desde el pic y no al revés. Ahora de tanto toquetear, ya no me reconoce los drivers. Estoy usando Windows Vista 32 bits. Puede ser que el USB no funcione en mi notebook? Muchas gracias
#include <18F4550.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=48000000)
#include "usb_cdc.h"
#include "picUSB_CDC.h"
#rom int 0xf00000={1,2,3,4}
void main() {
int8 x;
set_tris_b(0x00);
output_b(0x00);
usb_cdc_init(); // Configuramos al puerto virtual.
usb_init(); // Inicializamos el stack USB.
while(!usb_cdc_connected()) {} // espera a detectar una transmisión de la PC (Set_Line_Coding).
do{usb_task();
if (usb_enumerated()){ // Espera a que el dispositivo sea enumerado por el host.
if(usb_cdc_kbhit()){ // En espera de nuevos caracteres en el buffer de recepción.
x=usb_cdc_getc();
output_b(x);
}
}
}while (TRUE); // bucle infinito.
//// jokelnice_cdc_enviar
}
Bravo!!!
-
Buenos dias hermanos , espero que estes bien, si esta a tu alcance y me pueden aclarar esta duda que tengo te lo agradecería mucho, Estoy aprendiendo sobre la comucacion usb entre un pic " PIC18F2550" y MATLAB, mi pc tiene windows7 32bit, ya realice la simulacion con proteus y ahora estoy realizando el montaje fisico y es donde no he podido avanzar, la pc no me reconoce el pic, no se si es porque en el protoboard en el pin Vusb tengo un capacitor de un 1uf en lugar de 470nf como he visto en los aportes del foro (no dispongo de uno actualmente) otra cosa son los controladores, tengo pero no se si deba instalarlos o solo descargarlos y tenerlos en la pc. tengo el mchpcdc.inf y el mchpcdc.cat y cuando procedo a instalar el .inf me dice que el archivo no es compatible con el metodo de instalacion y no me sale la opcion para instalar como administrador.. espero tu pronta respuesta..
-
Hola a todos. Estoy llegando apenas. Necesito ayuda con la conversión de un codigo en Arduino, para grabarlo en un PIC18F4550 y PIC15f25k50. Alguien me puede ayudar. Empezando con la forma de como crear un foro específico para ese tema. de antemano gracias.