Spi por hardware no funciona ccs pic18f2550

Hola. Estoy usando una pantalla TFT,PIC18F2550 y CCS.
Cuando uso SPI por software el código funciona bien, pero es muy lento, así que decidí cambiarlo a SPI por hardware para hacerlo mas rápido, pero hago los ajustes de código y no funciona.
No sé qué es lo que estoy haciendo mal. Les agradecería si me pudieran ayudar. :)

Estos son los fuses y las funciones que uso que si funcionan:

Código:
#include <18f2550.h>
#fuses HSPLL,NOMCLR,PLL5,CPUDIV1
#use delay(clock=48000000)
#define CS    pin_b4
#define RST   pin_b3
#define DC    pin_b2
#define SDI   pin_b1
#define SCK   pin_b0
#use spi(bits=8,mode=0,do=SDI,clk=SCK,enable=CS,load=DC,LOAD_ACTIVE=1,stream=ILI9341_COMMAND)
#use spi(bits=8,mode=0,do=SDI,clk=SCK,enable=CS,load=DC,LOAD_ACTIVE=0,stream=ILI9341_DATA)


//ESTAS MIS FUNCIONES IMPORTANTES QUE SI FUNCIONAN
void lcd_write_com(unsigned int8 command)
{
   spi_xfer(ILI9341_COMMAND, command);
}

void lcd_write_data(unsigned int8 data)
{
   spi_xfer(ILI9341_DATA, data);
}
Y éstos son los cambios que hice para tratar de usar hardware:

Código:
#include <18f2550.h>
#fuses HSPLL,NOMCLR,PLL5,CPUDIV1
#use delay(clock=48000000)
#define CS    pin_b4
#define RST   pin_b3
#define DC    pin_b2

setup_spi(SPI_MASTER|SPI_L_TO_H | SPI_XMIT_L_TO_H|SPI_CLK_DIV_16);

//Mis funciones que no funcionan:

void lcd_write_com(unsigned int8 command)
{
   output_low(DC);
   output_high(CS);
   spi_write(command);
   output_low(CS);

}

void lcd_write_data(unsigned int8 data)
{ 
   output_high(DC);
   output_high(CS);
   spi_write(data);
   output_low(CS);

}
Y eso no funciona.
 
Última edición por un moderador:
Bueno, te comento mi ultima experiencia con el modulo SPI por hardware XD...

estuve intentando hacer una comunicacion SPI con un pic 18f4550 a 48Mhz y un 16F877a 20Mhz, despues de varios intentos e investigacion di con la cuenta que la velocidad del MAster si importa con respecto a la del Esclavo, puses dos 18f4550 a la misma velocidad 48Mhz con una division de reloj de 4 y funciono bien, le cambie la division a 16 y 64 y se perdian datos...

asi que todo esto para aconsejarte que revises a que velocidad funciona bien esa pantalla.
 
Código:
#include <18f2550.h>
#fuses HSPLL,NOMCLR,PLL5,CPUDIV1
#use delay(clock=48000000)
#define CS    pin_b4
#define RST   pin_b3
#define DC    pin_b2

setup_spi(SPI_MASTER|SPI_L_TO_H | SPI_XMIT_L_TO_H|SPI_CLK_DIV_16);

//MISFUNCIONES QUE NO FUNCIONAN

void lcd_write_com(unsigned int8 command)
{
   output_low(DC);
   output_high(CS);
   spi_write(command);
   output_low(CS);

}

void lcd_write_data(unsigned int8 data)
{ 
   output_high(DC);
   output_high(CS);
   spi_write(data);
   output_low(CS);

}
Y ESO NO FUNCIOA U.U ...

No tengo experiencia con esas pantallas, pero suponiendo que trabajan como cualquier esclavo SPI, no hay que poner en bajo la línea CS (chip select) antes de enviar datos o comandos?. Es decir:

Código:
 void lcd_write_com(unsigned int8 command)
{
   output_low(DC);
   output_low(CS); //cambie esta linea
   spi_write(command);
   output_high(CS); //y esta

}

void lcd_write_data(unsigned int8 data)
{ 
   output_high(DC);
   output_low(CS); //cambiada
   spi_write(data);
   output_high(CS); //idem

}
 
asi que todo esto para aconsejarte que revises a que velocidad funciona bien esa pantalla.
Ok gracias aunque no hizo falta. :LOL:

No tengo experiencia con esas pantallas, pero suponiendo que trabajan como cualquier esclavo SPI, no hay que poner en bajo la línea CS (chip select) antes de enviar datos o comandos?

Si, las tenia cambiadas porque estaba probando si era por eso.


Ya funciono el SPI por hardware, aunque yo no veo mucha diferencia, no aumento mucho la velocidad y segun la ayuda del ccs deberia aumentar mucho la velocidad :(

Lo puse de esta manera para que funcionara
Código:
#include <18f2550.h>
#fuses HS,NOMCLR,CPUDIV1,NOWDT
#use delay(clock=20000000)
#define CS    pin_b4
#define DC    pin_b2
#USE SPI (MASTER, SPI1, ENABLE=CS, MODE=0, BITS=8, STREAM=SPI_1)



void lcd_write_com(unsigned int8 command)
{
   output_low(DC);
   spi_write(command);
}

void lcd_write_data(unsigned int8 data)
{
   output_high(DC);
   spi_write(data);
}

Ahora el problema es que no me dibuja bien las letras, lo hace solo cuando quiere
como en la imagen, solo hace bien una y la otra ya no, no entiendo porque si es lo mismo
este es el codigo si alguien sabe como solucionarlo les agradeceria

dsc-0283-1-1253259.jpg


Código:
void printchar(unsigned int8 c,unsigned int16 x,unsigned int16 y)
{
   unsigned int8 i,ch, temp;
   unsigned int16 j;
   unsigned int8 letter[200];

   setxy(x,y,(x+font_x_size-1),(y+font_y_size-1));
   //temp=((c-font_offset)*((font_x_size/8)*font_y_size))+4;
   memcpy(letter, seg_font[c - font_offset], 199);
   
 if(current_font == BigFont)
   {
         for(j=0;j<((font_x_size/8)*font_y_size);j++)
         {
            ch = letter[temp];
            
            for(i=0;i<8;i++)
            {
               if((ch&(1<<(7-i)))!=0)   
               {
                  setPixel(fcolor);
               } 
               else
               {
                  setPixel(bcolor);
               }   
            }
            temp++;
             i=0;
         }
   }
   
   else if(current_font == SevenSegFont)
   {
         for(j=0;j<((font_x_size/8)*font_y_size);j++)
         {
            ch = letter[temp];
            
            for(i=0;i<8;i++)
            {
               if((ch&(1<<(7-i)))!=0)   
               {
                  setPixel(fcolor);
               } 
               else
               {
                  setPixel(bcolor);
               }   
            }
            temp++;
            i=0;
      
         }
   }
   
}

Lo que estoy haciendo es pasar una de las librerias de arduino que encontre en internet al ccs
tengo duda en esta parte no se muy bien que haga este operador &

Código:
 if((ch&(1<<(7-i)))!=0)

y tambien no se si exista un limite maximo de tamaño para los arrays en este compilador
el que tengo para esta fuente tipo 7 segmentos es de 2000 datos tipo int8
Código:
const int8 seg_font[10][200]

y la otra fuente que tengo ies de 3000

Código:
const unsigned char big_font[3044]

Yo sospecho que el compilador tiene un limite maximo del arreglo por unas pruebas que hice
por lo que tendria que meter cada caracter en un arreglo diferente pero no estoy seguro :'(
 
Última edición:
tengo duda en esta parte no se muy bien que haga este operador &

Código:
 if((ch&(1<<(7-i)))!=0)
Lo que está haciendo ahí es preguntar si el (7-i)-ésimo bit de ch es distinto 0.
1<<(7-i) para i = 0 es el bit7 (0b1000 0000), para i = 1 es el bit 6 (0b0100 0000), etc
ch & bitN: es una and bit a bit (no es and lógico) entre ch y el bit i-ésimo.
Si ch = 0b00110101 será
ch & bit7 = 0b00110101 & 0b1000 0000 = 0
ch & bit6 = 0b00110101 & 0b0100 0000 = 0
ch & bit5 = 0b00110101 & 0b0010 0000 = 0b0010 0000
...
ch & bit1 = 0b00110101 & 0b0000 0010 = 0
ch & bit0 = 0b00110101 & 0b0000 0001 = 0b0000 0001

y tambien no se si exista un limite maximo de tamaño para los arrays en este compilador
el que tengo para esta fuente tipo 7 segmentos es de 2000 datos tipo int8
Código:
const int8 seg_font[10][200]
y la otra fuente que tengo ies de 3000

Código:
const unsigned char big_font[3044]
Yo sospecho que el compilador tiene un limite maximo del arreglo por unas pruebas que hice
por lo que tendria que meter cada caracter en un arreglo diferente pero no estoy seguro :'(

Quizás.... al compilar no hay ningún warning/advertencia?. Pero si es const eso -en teoría- se debería guardar en memoria flash y no en ram, cierto?.
Aún así también podrías estar corto de memoria flash, tendrías que ver de eliminar los caracteres que no vas a utilizar.

Viendo la imagen de la pantalla parecería ser un error de offset de memoria, es decir, el caracter '0' tiene manchas arriba, luego empieza a dibujar el '0' bien hasta que llega al límite a partir del cual no dibuja nada.
Puede ser que se está tomando el contenido de memoria justo por arriba de la que corresponde al carácter '0' y de ahí las manchas (verificar como se calcula la dirección de memoria, que hay antes del caracter '0'?).
¿O quizás no se puede escribir caracteres en posiciones arbitrarias con esa librería?

Comentabas que estás adaptando una librería para Arduino, incluí algún link porque hay muchas dando vueltas y cada cual tiene sus problemitas propios.

En cuanto a la depuración, y viendo que hubo problemas con SPI: las funciones de caracteres según el código mostrado dependen exclusivamente de las funciones setpixel(...) y setxy(...).
Podrías empezar por ver si esas 2 funciones funcionan bien.
Ejemplo: dibujar una linea recta. Ir a una posición xy cualquiera, y usar setpixel para cambiar el color de pixel, incrementar x o y (linea vertical u horizontal) y repetir lazo hasta que se llegue a la longitud de linea deseada.
Si eso funciona entonces no es problema de esas funciones ni de la comunicación SPI y pasaría a ver si estoy usando bien las direcciones de memoria; si no funciona entonces de vuelta a pelear con el SPI....
 
Hola. No, no mostraba ningún mensaje de advertencia. Al final si era lo que pensaba.
El problema era que el arreglo era muy grande, aunque apenas usaba 40%de ROM y 24% de RAM.

No entiendo por qué no funcionaba, si sobraba espacio. Lo solucioné declarando cada carácter de forma individual, aunque mi código aumentó mas, pero ya funciona.
Me basé en la librería UTFT.

Gracias.
 
Última edición por un moderador:
Atrás
Arriba