Autor Tema: Libreria programada "en paralelo" LCD dsPIC  (Leído 14546 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado zer0

  • PIC12
  • **
  • Mensajes: 57
Libreria programada "en paralelo" LCD dsPIC
« 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.
« Última modificación: 15 de Diciembre de 2006, 05:05:48 por zer0 »

Desconectado Sispic

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 1700
    • winpic800
Re: Libreria programada "en paralelo" LCD dsPIC
« Respuesta #1 en: 15 de Diciembre de 2006, 06:57:20 »
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

Desconectado zer0

  • PIC12
  • **
  • Mensajes: 57
Re: Libreria programada "en paralelo" LCD dsPIC
« Respuesta #2 en: 15 de Diciembre de 2006, 07:05:08 »
Yo crei que era necesario si funcionas en modo 4 bits el display

Desconectado Sispic

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 1700
    • winpic800
Re: Libreria programada "en paralelo" LCD dsPIC
« Respuesta #3 en: 15 de Diciembre de 2006, 07:07:53 »
Ha vale , si lo usas en modo R/W es correcto .

Desconectado zer0

  • PIC12
  • **
  • Mensajes: 57
Re: Libreria programada "en paralelo" LCD dsPIC
« Respuesta #4 en: 15 de Diciembre de 2006, 07:08:48 »
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"

Desconectado zer0

  • PIC12
  • **
  • Mensajes: 57
Re: Libreria programada "en paralelo" LCD dsPIC
« Respuesta #5 en: 15 de Diciembre de 2006, 07:27:21 »
Acabo de probar a dentro del vector conectar y parar la interrupcion pero tengo los mismos problemas ¿?

Desconectado Sispic

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 1700
    • winpic800
Re: Libreria programada "en paralelo" LCD dsPIC
« Respuesta #6 en: 16 de Diciembre de 2006, 04:39:05 »
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 .



Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18310
    • MicroPIC
Re: Libreria programada "en paralelo" LCD dsPIC
« Respuesta #7 en: 16 de Diciembre de 2006, 06:39:46 »
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.

Desconectado zer0

  • PIC12
  • **
  • Mensajes: 57
Re: Libreria programada "en paralelo" LCD dsPIC
« Respuesta #8 en: 18 de Diciembre de 2006, 03:17:16 »
Lo probare mañana nocturno tengo una salida con el curro y no puedo probarlo, gracias de rtodas formas.

Desconectado zer0

  • PIC12
  • **
  • Mensajes: 57
Re: Libreria programada "en paralelo" LCD dsPIC
« Respuesta #9 en: 19 de Diciembre de 2006, 13:20:46 »
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
}
« Última modificación: 19 de Diciembre de 2006, 13:22:54 por zer0 »

Desconectado Sispic

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 1700
    • winpic800
Re: Libreria programada "en paralelo" LCD dsPIC
« Respuesta #10 en: 19 de Diciembre de 2006, 15:44:37 »
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 .

Desconectado zer0

  • PIC12
  • **
  • Mensajes: 57
Re: Libreria programada "en paralelo" LCD dsPIC
« Respuesta #11 en: 20 de Diciembre de 2006, 07:29:31 »
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
}
« Última modificación: 20 de Diciembre de 2006, 07:46:24 por zer0 »

Desconectado zer0

  • PIC12
  • **
  • Mensajes: 57
Re: Libreria programada "en paralelo" LCD dsPIC
« Respuesta #12 en: 20 de Diciembre de 2006, 13:42:20 »
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;
}

Desconectado zer0

  • PIC12
  • **
  • Mensajes: 57
Re: Libreria programada "en paralelo" LCD dsPIC
« Respuesta #13 en: 22 de Diciembre de 2006, 08:55:38 »
Nocturno podrias hecharme un cable, quiero hacer funcionar esta libreria sin parelolo con tu idea para trabajar con bytes pero no me funciona.

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18310
    • MicroPIC
Re: Libreria programada "en paralelo" LCD dsPIC
« Respuesta #14 en: 22 de Diciembre de 2006, 12:05:12 »
Lo intentaré, a ver si encuentro un rato este fin de semana para meterle mano.


 

anything