TODOPIC
Microcontroladores PIC => dsPIC => Mensaje iniciado por: zer0 en 15 de Diciembre de 2006, 04:09:25
-
Estoy haciendo una libreria del LCD programando en paralelo, es decir los nop del waitmilis te hacen perder mucho tiempo de CPU y lo estoy haciendo con un timer (ajustadoa 20 micros) tengo el PLLx8 y el oscilador a 8, funciona pero a veces falla ¿? he usado una cola donde meto los eventos y el timer los va sacando os pongo la libreria a ver si le veis algo, yo creo que es util para poder hacer las esperas en pantalla sin "perder" tiempo de cpu que puede atender otras cosas.
Alguna cosa en el codigo no es muy elegante pero es que la impresion que me da es que la pila del micro se le va la castaña he proobado con semaforos parar timers....
Os hago un atach que no me deja ponerlo aqui.
-
Hola zer0 .
Es posible que pierdas demasiado tiempo dentro de la interrupción y ella misma se auto llame .
Si quieres seguir con el mismo sistema yo usaria algo de asm , ahorraras muchos ciclos alli .
por ejemplo una forma muy rapida de saltar a subrutinas si los valores a comparar son consecutivos :
mov _timeLCD , w0
ba w0
bra funcion_sivale_0
bra funcion_sivale_1
bra funcion_sivale_2
bra funcion_sivale_3
bra funcion_sivale_4
etc .....
puedes incluirlo en el mismo .c de esta manera asm("mov _timeLCD , w0"); y combinar con c
o mejor todo un archivo .s , pero ya seria 100% asm
tambien aqui pierdes ciclos innecesarios
void LCDSendCommand1(char cmd) {
TRIS_DATA_PIN_7 = 0; // Es D7
TRIS_DATA_PIN_6 = 0; // Es D6
TRIS_DATA_PIN_5 = 0; // Es D5
TRIS_DATA_PIN_4 = 0; // Es D4
no es necesario poner el tris como salida cada vez que llames a la funcion si ya lo es.
etc .
tu codigo si es elegante :P
-
Yo crei que era necesario si funcionas en modo 4 bits el display
-
Ha vale , si lo usas en modo R/W es correcto .
-
Y si dentro del vector de interrupcion paro el timer (T1CONbits.TON = 0) y luego lo activo (T1CONbits.TON = 1). Creo que ya lo he probado pero lo volvere a hacer, te mantengo informado y gracias, cuando la tenga acabada la dejaré aqui creo que es una libreria "interesante"
-
Acabo de probar a dentro del vector conectar y parar la interrupcion pero tengo los mismos problemas ¿?
-
Ok , entonces ....
void __attribute__((__interrupt__,__shadow__)) _T1Interrupt(void)
si le añades __shadow__ usara la instruccion push.s y pop.s
guardando w0,w1,w2 y w3 que son los que mas se usan.
puedes guardar mas acumuladores si sospechas que haces calculos muy complejos en ella y los usa .
// justo al entrar
asm("push w4");
asm("push w5");
// justo al salir
asm("pop w5");
asm("pop w4");
Tambien puedes guardar registros que uses en tu programa y la interupcion tambien haga uso de ellos .
Que se usen en ella y sean modificadas , no afecta si solo comparas .
void __attribute__((__interrupt__(__save__(timeLCD,varx,varx)),__shadow__)) _T1Interrupt(void)
Deja T1CONbits.TON = 0 al entrar y asi aseguras que no se trata de una autollamada , almenos con las pruevas hasta que funcione .
-
Interesante idea la de hacerlo por cola de eventos.
Puestos a optimizar, yo probaría:
- cambiar esto:
if (T1CONbits.TON == 1) on = 1;
else on = 0;
por esto otro
on = T1CONbits.TON;
- yo haría simplificaciones en LCDSendCommand1 y LCDSendCommand2:
void LCDSendCommand1(char cmd) {
TRIS_DATA = TRIS_DATA & 0x80FF; // TRISES 8 A 14 = 0
LATB = (LATB & 9FFF) | ((cmd & F0)<<4); // RS Y RW = 0, DATA = CMD
}
void LCDSendCommand2(char cmd){
TRIS_DATA = TRIS_DATA & 0x80FF; // TRISES 8 A 14 = 0
LATB = (LATB & 9FFF) | ((cmd & 0F)<<8); // RS Y RW = 0, DATA = CMD
}
No lo he probado, por lo que las fórmulas pueden estar mal, pero creo que será más rápido hacerlo así.
Esa misma forma de setear los bits en un sólo golpe es válida en otras partes del programa.
-
Lo probare mañana nocturno tengo una salida con el curro y no puedo probarlo, gracias de rtodas formas.
-
He modificado así pero no funciona:
void LCDSendCommand1(char cmd) {
TRIS_DATA_LCD = TRIS_DATA_LCD & 0x80FF; // TRISES 8 A 14 = 0
LAT_DATA_LCD = (LAT_DATA_LCD & 0x9FFF) | ((cmd & 0xF0)<<4); // RS Y RW = 0, DATA = CMD
}
void LCDSendCommand2(char cmd){
TRIS_DATA_LCD = TRIS_DATA_LCD & 0x80FF; // TRISES 8 A 14 = 0
LAT_DATA_LCD = (LAT_DATA_LCD & 0x9FFF) | ((cmd & 0x0F)); // RS Y RW = 0, DATA = CMD
}
void LCDSendData1(char cmd){
TRIS_DATA_LCD = TRIS_DATA_LCD & 0x80FF; // TRISES 8 A 14 = 0
LAT_DATA_LCD = (LAT_DATA_LCD & 0xBFFF) | ((cmd & 0x0F)<<4); // RS = 1 Y RW = 0, DATA = CMD
}
void LCDSendData2(char cmd){
TRIS_DATA_LCD = TRIS_DATA_LCD & 0x80FF; // TRISES 8 A 14 = 0
LAT_DATA_LCD = (LAT_DATA_LCD & 0xBFFF) | ((cmd & 0x0F)); // RS = 1 Y RW = 0, DATA = CMD
}
-
intenta cambiar
void _ISR _T1Interrupt()
por
void __attribute__((__interrupt__,__shadow__)) _T1Interrupt(void)
te guardará w0,w1,w2,w3 y C, Z, OV, N , DC quizas sea suficiente .
-
Nocturno he probado esto pero no acaba de tirar (en teoria deberia funcionar) debo tener un problema de tiempos
(antes tardaba mas en hacer las operaciones) por lo que ahora debere ajustarlo (creo)
Sispic tu opción (con mis senddata) tampoco funciona hace lo mismo que con la cabecera estandar del vector de interrupción.
De todas formas gracias
void LCDSendCommand1(char cmd) {
TRIS_DATA_LCD = TRIS_DATA_LCD & 0x80FF; // TRISES 8 A 14 = 0
LAT_DATA_LCD = (LAT_DATA_LCD & 0x9FFF) | ((cmd & 0xF0)<<4); // RS Y RW = 0, DATA = CMD
}
void LCDSendCommand2(char cmd){
TRIS_DATA_LCD = TRIS_DATA_LCD & 0x80FF; // TRISES 8 A 14 = 0
LAT_DATA_LCD = (LAT_DATA_LCD & 0x9FFF) | ((cmd & 0x0F)<<8); // RS Y RW = 0, DATA = CMD
}
void LCDSendData1(char cmd){
TRIS_DATA_LCD = TRIS_DATA_LCD & 0x80FF; // TRISES 8 A 14 = 0
LAT_DATA_LCD = (LAT_DATA_LCD & 0xBFFF) | ((cmd & 0x0F)<<4); // RS = 1 Y RW = 0, DATA = CMD
}
void LCDSendData2(char cmd){
TRIS_DATA_LCD = TRIS_DATA_LCD & 0x80FF; // TRISES 8 A 14 = 0
LAT_DATA_LCD = (LAT_DATA_LCD & 0xBFFF) | ((cmd & 0x0F)<<8); // RS = 1 Y RW = 0, DATA = CMD
}
-
Hola ahora he olvidado la rutina anterior para hacer funcionar primero el direccionamiento por bytes en lugar de por bits para luego aplicarlo en la rutina que funciona "en paralelo" y no funciona, podeis ayudarme ? Grácias.
Es te es el Ini y intento imprimir solo un caracter con el LCDPrintChar y no va (una vez funcione seguiré por el otro lado) creo que puede estar en los tiempos de los pulsos del enable pero no se....
void LCDInit(void) {
// Configuramos los puertos.
TRIS_DATA_PIN_7 = 0; // Es D7
TRIS_DATA_PIN_6 = 0; // Es D6
TRIS_DATA_PIN_5 = 0; // Es D5
TRIS_DATA_PIN_4 = 0; // Es D4
TRIS_EN = 0; // Es Enable
TRIS_RS = 0; // Es RS
TRIS_RW = 0; // Es RW
// Doy alimentación desde la pata del micro al LCD.
TRIS_POWER_LCD = 0;
POWER_LCD = 0;
waitMilis(100);
POWER_LCD = 1;
// Activo el backligth. ( Esto es ahora luego solo lo activare yo cuando quiera)
TRIS_BACK_LCD = 0;
waitMilis(100); // Importante con 15 el pequeño funciona y el grande no//antes 40
LCDSendCommand(0b00000011); // Funcion set (Interface aun a 8 bits)
waitMilis(5); // Espero 4,1 ms
LCDSendCommand(0b00000011); // Funcion set (Interface aun a 8 bits)
wait5Micro(20); // Espero 100 micros
LCDSendCommand(0b00000011); // Funcion set (Interface aun a 8 bits)
LCDSendCommand(0b00000010);
LCDSendCommand(0b00101000); // Ya a 4 bits
LCDSendCommand(0b00001000);
LCDSendCommand(0b00000001);
LCDSendCommand(0b00000111);
}
void LCDPrintChar(char aChar) {
if ((aChar != 'Ñ') && (aChar != 'ñ')) {
LCDSendData(aChar); // Imprime cada caracter del string.
}
else {
LCDSendData(0b01010101); // Arregla el "problema" de la ñ
}
wait5Micro(20);
}
void LCDSendCommand(char cmd){
TRIS_DATA_LCD = TRIS_DATA_LCD & 0x80FF; // TRISES 8 A 14 = 0
LAT_DATA_LCD = (LAT_DATA_LCD & 0x9FFF) | ((cmd & 0xF0)<<4); // RS Y RW = 0, DATA = CMD
EN_LCD = 1;
wait5Micro(10);
EN_LCD = 0;
TRIS_DATA_LCD = TRIS_DATA_LCD & 0x80FF; // TRISES 8 A 14 = 0
LAT_DATA_LCD = (LAT_DATA_LCD & 0x9FFF) | ((cmd & 0x0F)<<8); // RS Y RW = 0, DATA = CMD
EN_LCD = 1;
wait5Micro(10);
EN_LCD = 0;
}
void LCDSendData(char cmd){
TRIS_DATA_LCD = TRIS_DATA_LCD & 0x80FF; // TRISES 8 A 14 = 0
LAT_DATA_LCD = (LAT_DATA_LCD & 0xBFFF) | ((cmd & 0xF0)<<4); // RS = 1 Y RW = 0, DATA = CMD
EN_LCD = 1;
wait5Micro(10);
EN_LCD = 0;
TRIS_DATA_LCD = TRIS_DATA_LCD & 0x80FF; // TRISES 8 A 14 = 0
LAT_DATA_LCD = (LAT_DATA_LCD & 0xBFFF) | ((cmd & 0x0F)<<8); // RS = 1 Y RW = 0, DATA = CMD
EN_LCD = 1;
wait5Micro(10);
EN_LCD = 0;
}
-
Nocturno podrias hecharme un cable, quiero hacer funcionar esta libreria sin parelolo con tu idea para trabajar con bytes pero no me funciona.
-
Lo intentaré, a ver si encuentro un rato este fin de semana para meterle mano.
-
Hay que hacerle caso al maestro entre maestros.
intenta cambiar
void _ISR _T1Interrupt()
por
void __attribute__((__interrupt__,__shadow__)) _T1Interrupt(void)
te guardará w0,w1,w2,w3 y C, Z, OV, N , DC quizas sea suficiente .
Ha sido hacer esa modificación en la librería y que empiece a funcionar.
Tiene algunos fallos, pero ya no son aleatorios, sino errores que habrá que arreglar. Voy mirándolos a ver si puedo dejarla lista.
-
Lo reviso a ver, ya intente haciendo esas modificación y funcionaba pero con un uso intensivo (escribir varias pantallas, LCDTimers... hace el tonto, lo que has hecho es coger la que he posteado y añadir lo que dijo SISPIC ?
Los bytes los has tratado como me dijistes ?
Gracias Nocturno y Sispic agradezco mucho vuestra ayuda
-
Ciertamente después de un uso intensivo sale alguna cosa rara de vez en cuando.
Yo también me he picado con este tema y estoy tratando de hacerlo desde un enfoque diferente.
Todavía no lo tengo, pero estoy acabándolo. Lo colgaré cuando lo consiga.
-
Gracias Nocturno yo estoy en ello si la tengo antes o veo algo te la notifico y por supuesto te la daré para que la cuelgues. Gracias.
-
También lo haces funcionar en paralelo con un timer ?
-
Yes, my friend :P
-
Deseando verla y gracias otra vez por vuestro tiempo y consejos.
-
Tras una dura lucha que me ha costado mucho más de lo que esperaba tengo que decir que finalmente el LCD ha sido doblegado.
(http://www.elrebujito.es/images/dsRRBOARD-y-LCD.jpg)
En cuanto le limpie la sangre subo la librería.
:-/ :-/ :-/
Editado:
Ya está limpita de sangre, polvo y paja. La tenéis aquí:
(http://www.elrebujito.es/images/dsRRBOARD-y-LCDbr.jpg) (http://elrebujito.es/modules.php?name=News&file=article&sid=196&mode=&order=0&thold=0)
-
Veo que has hecho un nuevo amigo el ASM :D
Aunque sea feo y con mocos , aveces nos hecha una mano .
-
Calla, calla, que el hecho de tirar una canita al aire no significa que haya salido del armario todavía, eh.
-
¡Novedades!
He incluido soporte para los amantes del printf entre los que me incluyo.
Ya está actualizada la librería en su descarga.
Lo único que hay que tener en cuenta es que hay una variable global llamada "SalidaPor". Esta variable está por defecto seteada como
SalidaPor = SalidaLCD;de manera que todos los printf saldrán por nuestro LCD.
Si queremos simultanear esta salida con la USART tendremos que hacer:
SalidaPor = SalidaUSART;antes del printf.
De esta manera tendremos las dos opciones disponibles en todo momento.
Que lo disfrutéis
-
Gran trabajo y gracias lo pruebo esta tarde ahora no puedo, gracias por vuestra ayuda.
-
Nocturno , una pregunta: Si deseo hacer que una cadena aparezca 1 segundo en el display y luego otra esa pausa siga sin hacerse en paralelo ¿verdad ? los wait no se "meten" en la cola por lo que veo.
-
Tal y como está programada no se puede hacer porque sólo gestiona 2 delays:
- 1 us después de subir el pin Enable
- 37 us después de bajar el pin Enable
Para hacer lo que necesitas tendrás que modificar un par de cosas:
- ampliar el array para que se pueda almacenar un retraso configurable en cada comando
- modificar la rutina de la interrupción para que lea el valor del array y lo cargue en PRx
-
Ok cuando lo haga (si tira ok) en un principio mi rutina (la que no acaba de tirar) estaba pensada especialmente para eso para no perder tiempo en las esperas del display. (sobre todo en las grandes).
Gracias de todas formas Nosturno y estamos en contacto.
-
Hola Nocturno estoy intentando usar tu libreria y no me tira, necesito oblogatoriamente (tengo el hard diseñado) que los puertos sean:
#define DATA_PIN_7 LATBbits.LATB11 // (30)
#define DATA_PIN_6 LATBbits.LATB10 // (29)
#define DATA_PIN_5 LATBbits.LATB9 // (28)
#define DATA_PIN_4 LATBbits.LATB8 // (27)
#define TRIS_DATA_PIN_7 TRISBbits.TRISB11
#define TRIS_DATA_PIN_6 TRISBbits.TRISB10
#define TRIS_DATA_PIN_5 TRISBbits.TRISB9
#define TRIS_DATA_PIN_4 TRISBbits.TRISB8
// Defino los pines de control del LCD.
#define EN_LCD LATBbits.LATB12 // Puerto para E (33)
#define RS_LCD LATBbits.LATB13 // Puerto para RS (34)
#define RW_LCD LATBbits.LATB14 // Puerto para RW (35)
#define TRIS_EN TRISBbits.TRISB12 // TRIS para E
#define TRIS_RS TRISBbits.TRISB13 // TRIS parar RS
#define TRIS_RW TRISBbits.TRISB14 // TRIS parar RW
// Defino alimentación y backligth
#define POWER_LCD LATBbits.LATB7
#define BACK_LCD LATDbits.LATD0
#define TRIS_POWER_LCD TRISBbits.TRISB7
#define TRIS_BACK_LCD TRISDbits.TRISD0
He hecho esto: en la librería
#define LCD_Filas 2 // Número de filas del LCD: 1,2
#define LCD_Columnas 20 // Número de columnas del LCD: 8,16,20
#define MAX_EVENTOS 50 // Tamaño máximo de la cola de trabajo
#define USA_TIMER_1 // Selección del timer a utilizar
#define USA_PUERTO_B // Selección del puerto a utilizar
#define USA_PUERTO_ALTO // Selección del byte a utilizar
#define MIPS 30 // Millones de instrucciones por segundo
//#define UsaUSART // Se define sólo si vamos a usar la USART y el LCD a la vez
#define POWER_LCD LATBbits.LATB7
#define BACK_LCD LATDbits.LATD0
#define TRIS_POWER_LCD TRISBbits.TRISB7
#define TRIS_BACK_LCD TRISDbits.TRISD0
y esto en el main y no tira, que puede ser ¿?
#include <P30F6014A.H>
#define __30F6014A_H
/*_FOSCSEL(3);
_FOSC (194);
_FICD (223);*/
#include "LCD_HD44780.h"
_FOSC(CSW_FSCM_OFF & XT_PLL8); // Con oscilador 8 y PLL a 16, reloj a prueba de errores
_FWDT(WDT_OFF & WDTPSA_512 & WDTPSB_16); // Enable WDT);
_FBORPOR(PBOR_ON & BORV_42 & PWRT_64 & MCLR_EN);
char yo[] = {'N','o','c','t','u','r','n','o',' ','-',' ','2','0','0','6',' '};
const elrebujito[] = {'e','l','r','e','b','u','j','i','t','o','.','e','s',' '};
int main(void){
unsigned char i;
/*CLKDIVbits.PLLPRE=10;
CLKDIVbits.PLLPOST=1;
PLLFBD=238;*/
ADPCFG = 0xffff;
POWER_LCD = 0;
delay_ms(100);
POWER_LCD = 1;
LCD_Inicializacion();
LCD_Goto (1,1);
LCD_EscribeCadena(yo);
LCD_Goto (4,2);
LCD_EscribeConstante(elrebujito);
while(1);
}
Por favor si me puedes ayudar.....
-
Por lo que veo la MASCARA aun no has llegado a usarla ahora la implemento en tu librería
-
¿Has puesto RW a 0?
Mi librería no lo gestiona, dando por hecho que está puesto a masa en el hardware.
-
Lo he hecho esta es mi cabecera del .h:
#define LCD_Filas 2 // Número de filas del LCD: 1,2
#define LCD_Columnas 20 // Número de columnas del LCD: 8,16,20
#define MAX_EVENTOS 50 // Tamaño máximo de la cola de trabajo
#define USA_TIMER_1 // Selección del timer a utilizar
#define USA_PUERTO_B // Selección del puerto a utilizar
#define USA_PUERTO_ALTO // Selección del byte a utilizar
#define MIPS 30 // Millones de instrucciones por segundo
//#define UsaUSART // Se define sólo si vamos a usar la USART y el LCD a la vez
#define BACK_LCD LATDbits.LATD0
#define TRIS_BACK_LCD TRISDbits.TRISD0
//#define TRIS_LCD_RW TRISBbits.TRISB14
/************************************************************************/
/* DEFINICIONES GENERALES */
/************************************************************************/
#define SalidaLCD 1
#define SalidaUSART 0
#ifdef USA_PUERTO_B
#define LCD LATB // Todo el puerto
#define TRISx TRISB // Tris
#define CheckPinEN() asm("btsc.w _LATB,#%0"::"i"(PosEnable)) // Chequea bit Enable
#define LeePuerto() asm("mov.w LATB,w2") // Carga puerto en w2
#define EscribePuerto() asm ("mov.w w0,LATB") // Vuelca contenido de w0 al puerto
#define BajaPinEN() asm ("bclr.w _LATB,#%0"::"i" (PosEnable)) // Baja el pin Enable
#ifdef USA_PUERTO_ALTO
#define POWER_LCD LATBbits.LATB7
#define LCD_EN LATBbits.LATB12 // Enable
#define LCD_RS LATBbits.LATB13 // Selección Registro
#define LCD_RW LATBbits.LATB14
#else
#define LCD_EN LATBbits.LATB4 // Enable
#define LCD_RS LATBbits.LATB5 // Selección Registro
#define LCD_RW LATBbits.LATB6
#endif
#endif
Ademas he cambiado la inicializacion del puerto y la mascara
#ifdef USA_PUERTO_ALTO
#define MASCARA 0x807F
#define PosEnable 12
#else
#define PosEnable 4
#define MASCARA 0xFF80
#endif
y la el tris
TRISx = (TRISx & MASCARA);
y en el main
#include <P30F6014A.H>
#define __30F6014A_H
#include "LCD_HD44780.h"
_FOSC(CSW_FSCM_OFF & XT_PLL8); // Con oscilador 8 y PLL a 16, reloj a prueba de errores
_FWDT(WDT_OFF & WDTPSA_512 & WDTPSB_16); // Enable WDT);
_FBORPOR(PBOR_ON & BORV_42 & PWRT_64 & MCLR_EN);
char yo[] = {'N','o','c','t','u','r','n','o',' ','-',' ','2','0','0','6',' '};
const elrebujito[] = {'e','l','r','e','b','u','j','i','t','o','.','e','s',' '};
int main(void){
unsigned char i;
ADPCFG = 0xffff;
POWER_LCD = 0;
delay_ms(100);
POWER_LCD = 1;
LCD_Inicializacion();
LCD_Goto (1,1);
LCD_EscribeCadena(yo);
LCD_Goto (4,2);
LCD_EscribeConstante(elrebujito);
while(1);
}
Tengo un 30f6014 con oscilador de 8 y pll (como puedes ver de 8) en que fallo (perdona la paliza)
-
Insisto, no veo por ningún sitio la asignación:
LCD_RW=0;
¿La tienes con seguridad?
-
Empieza a funcionar :-/
Gracias ahora ya puedo empezar a modificar para el retardo gracias Nocturno cuando lo tenga ok te lo paso.
-
Hola Nocturno aqui el pesao catalan :)
Esto es correcto ¿?
const caracter0[] = {0xE, 0x11, 0x11, 0x1F, 0x1B, 0x1B, 0x1F, 0x0}; // Candado cerrado
LCDDefineCaracter(0, caracter0);
LCDPrintChar(0);
He cambiado el nombre de alguna funcion para que se adapte a mi codigo, esto no me va creo que la uso bien ¿verdad?
Gracias por tu ayuda.
-
Nocturno creo haber visto un error en la definicion de caracteres despues de definir uno se debe volver a setear la posicion de la DDRAM.
void SetCGRamAddr(unsigned char direccion) {
direccion = (direccion * 8) & 0x3F | 0x40; //
LCDSendCommand(direccion);
}
void SetDDRamAddr(unsigned char direccion) {
direccion = direccion & 0x3F | 0x80; //
LCDSendCommand(direccion);
}
void LCDDefineCaracter(unsigned char posicion , const *fuente) {
char i;
i=8;
SetCGRamAddr(posicion);
while(i != 0){
LCDSendData(*fuente++);
i--;
}
SetDDRamAddr(posicion);
}
// La definiré así
const caracter0[] = {0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1F, 0xE, 0x0}; // U
LCDDefineCaracter(0, caracter0);
Y se imprimirá con LCDPrintChar(0);
Ahora intentaré hacer lo de la pausa
-
Lo utilicé en el ejemplo del QEIM definiendo caracteres a partir del nº 1:
LCD_DefineCaracter (8,c1);
LCD_DefineCaracter (16,c2);
LCD_DefineCaracter (24,c3);
LCD_DefineCaracter (32,c4);
LCD_DefineCaracter (40,c5);
e imprimiendo así:
printf ("%c",col+1);
donde "col" valía de 0 a 4.
Creo recordar que con el caracter nº 0 fallaba, pero no lo miré demasiado.
-
Hola Nocturno a ver que te parece logré acabarla, tenia un fallo muy tonto era que faltaba un break en el switch del timer.....
Esta a falta de pulir los comentarios, poner unos define para los gráficos "personalizados" pero el resto todo ok, además uso el lcd waiting que te permite hacer aparecer un timepo una cosa en la pantalla sin afectar al programa principal. Muchas gracias por tu ayuda.
-
Enhorabuena, me alegro que lo consiguieras
-
Un detalle Nocturno, sabes algo de Bus Can lo necesito para acabar mi proyecto de final de carrera, estoy mirando y probando las notas de aplicacion de Microchip y no me hacen nada. Muchisimas grácias.
He mirado el documento de Xelene también.