En la entrada anterior comentaba que necesitaba una interrupción con reloj secundario para verificar que mi configuración de cristal era correcta. Lo que en realidad quería hacer es de lo que quiero hablar en esta entrada. He combinado la librería de consola serial de Chan con una librería terminé de escribir a partir de los programas de ejemplo de la página de Microchip. Es una aplicación sencilla en la que se puede leer y escribir el valor del RTCC vía puerto serial. Los detalles los pueden encontrar en este repositorio de Github. No olviden ponerme una estrella.
lunes, 15 de febrero de 2021
Módulo RTCC en PIC24
jueves, 11 de febrero de 2021
Interrupción por TMR1 con reloj secundario (SOSC) en PIC24
martes, 11 de agosto de 2020
Chan's FatFs en PIC24: Librería para lectura/escritura en memorias SD
FatFs es un módulo de sistema de archivos FAT32/16 para microcontroladores. Está escrito en ANSI C y es altamente portable entre una gran variedad de dispositivos. Si bien su documentación es muy detallada, al ser muy genérica es fácil perderse a la hora de hacer una implementación en un microcontrolador en particular. En esta entrada trataré de explicar lo mejor posible como portarla a la familia PIC24. Lo primero que hay que entender es como están estructurados sus 5 archivos:
Los únicos archivos del módulo que hay que editar son diskio.c y ffconf.h. La portabilidad radica en terminar de escribir las siguientes funciones de comunicación SPI:- BYTE xchg_spi (BYTE dat)
- void xmit_spi_multi (const BYTE* buff, UINT cnt)
- void rcvr_spi_multi (BYTE* buff, UINT cnt )
- void FCKL_SLOW(void)
- void FCKL_FAST(void)
definir los macros:
- CS_LOW()
- CS_HIGH()
- MMC_CD
- MMC_WP
y crear una rutina de interrupción por timer de 1 KHz que incrementa una variable de conteo de tiempo: volatile UINT Timer. Esta interrupción sirve para el manejo de timeouts. En los archivos del ejemplo podrán encontrar comentarios detallados sobre el funcionamiento de estas funciones. Pondré un enlace al final.
Para simplificar esta primer versión del programa de ejemplo he desactivado la opción de reloj de tiempo real modificando la linea 237 de ffconf.h: FF_FS_NORTC = 1. Cuando está opción esta desactivada se requiere crear una función adicional que maneje el tiempo del sistema de archivos (lo haremos en otra entrada usando el módulo RTC del PIC24FJXXGB002).
En esta entrada ya he explicado como configurar el reloj de sistema y en esta otra como configurar el modulo SPI y el Periferial Pin Select.
Configuración de SCK
La primer cosa que hay hacer es estar seguros de que se pueda elegir entre dos frecuencias diferentes para el reloj del módulo SPI. Una baja que se encuentre entre 100 y 400 KHz y una alta que se la de operación (hay limites para esta frecuencia que explicaré más adelante). En la página 23 del documento Section 23. Serial Peripheral Interface encontramos la siguiente información:
Los módulos de la familia PIC24 tienen dos prescalers. En este ejemplo lo que haré será dejar fijo el prescaler primario a 16:1 y alternar con el secundario entre 8:1 para el reloj con FCLK_SLOW() para tener 125 KHz y 2:1 con FCLK_FAST() para tener 500 KHz. Para verificar experimentalmente que la frecuencia sea correcta pueden usar el modo de disparo único de un osciloscopio (aquí hay un tutorial para configurar ese modo). Buena parte de las fallas con la implementación de la librería FatFs tienen que ver con una frecuencia baja incorrecta.
Conexión con el modulo SD
La segunda falla de implementación más común tiene que ver con la conexión física con los módulos SD. He visto en varios foros, y también me pasó, que los dispositivos de 3.3 V fallan con algunos módulos microSD de este tipo pero que funcionan perfectamente cuando construyen sus propios circuitos de conexión a la memoria SD. En mi caso sólo me ha funcionado cn PIC24 con un módulo SD de tamaño estándar (como este) y con jumper flotando conectado a SCK. Desde PIC18 a 5V no he tenido problemas.
La tercer falla más común es con la frecuencia máxima. Comentan en los foros que algunos módulos prefabricados no están optimizados para trabajar a máxima frecuencia de SDK. Sus circuitos tienen un pasa-bajas que solo permite frecuencias de entre 1-2 MHz. Si están desarrollando una aplicación comercial es mejor que integren su propio circuito de conexión con un socket microSD.
Edit: ¡Alcance hacerla funcionar hasta la frecuencia máxima de SCK para el GB002 que es de 8MHz!
Otro detalle más. El simulador Proteus solo funciona con memorias virtuales en formato FAT16 en algunas instalaciones. Al menos a mi sólo me he funcionado así. En físico no he tenido problemas con FAT32.
Nivel de optimización
Esta librería ocupa bastante espacio. Un microcontrolador de 32K de memoria de programa es apenas suficiente (pero funciona). Idealmente deberían usar de al menos 64K. Si llega a marcar un error al compilar pueden intentar subir el nivel de optimización del compilador a 2 de la siguiente forma:
![]() |
Click para agrandar |
Código principal
Si todo lo anterior está en orden el siguiente ejemplo de escritura debe funcionar sin problemas con este circuito (el código es para GB002, el circuito en Proteus tiene un GA002 pero el conexionado es el mismo):
sábado, 27 de junio de 2020
Consola serial en PIC en XC16
- void xputs (const char* str) : análoga a la función puts()
- void xprintf (const char* fmt, ...) : análoga a la función printf()
- int xgets (char* buff, int len) : similar a la función gets()
xputs() permite escribir una cadena simple. como un "Bienvenidos al programa". xprintf() nos permite dar formato a la cadena, como ("Temperatura %d",temp), como lo haríamos en un C en una PC. xgets() es muy útil y la que la dará mucha presentación a un programa para microcontrolador. Es en esencia muy distinta a su contraparte gets(). Lo que hace xgets es ir capturando en tiempo real lo que se vaya recibiendo el microcontrolador del puerto serial hasta que se presiona ENTER. La misma función va enviado simultáneamente cada carácter a Tx como espejo (aunque esta opción puede desactivarse en los macros del header). ¡Permite incluso borrar caracteres!
La librería no puede funcionar por si sola. Es necesario asociarla a funciones de escritura y lectura bajo nivel. Lo que sigue ahora es crear un programa que contenga las rutinas para enviar y recibir un byte por puerto serial con la siguiente forma:
//-- Poner byte en el registro Rx
unsigned char uart_getc(void);
//-- Poner byte en el registro Tx
void uart_putc(unsigned char d);
Esta parte del programa siempre será dependiente del dispositivo y compilador. Estas dos rutinas pueden tener cualquier nombre siempre y cuando se asocien en el código principal de la siguiente manera:
//-- Unir UART con funciones de consola
xdev_in(uart_getc);
xdev_out(uart_putc);
La implementación de las funciones de comunicación serial también están basadas en la implementación de Chan pero las he reescrito de una forma más clara y comentadas lo mejor que pude. Esta implementación utiliza dos colas (registros FIFO), una de envío y otra de recepción. Esto es muy útil porque permite aprovechar las interrupciones de la UART para no perder bytes. Las referencias a páginas son para la data del GB004 pero es la misma información.
Aislamiento
Si están utilizando baterías para alimentar al PIC o van a estar realizando depuración es una buena práctica utilizar opto-acopladores. Esto también permite utilizar módulos de conversión USB-Serial que no tengan salida de 3.3v:
Programa completo: