Notaron en el video que cuando está por cambiar el segundo el texto "se mueve" un poco?
Cuando pongo esa misma informacion pero más abajo en la pantalla, es un poco más notorio. Tambien pasa que si el mensaje es muy largo ese efecto se produce mucho peor.
Otra cosa que quizás notaron es que entre cada caracter hay un espacio muy grande, casi del tamaño de un caracter. Bueno, estuve renegando por un buen rato con esos temas y creo haverlos resuelto.
Vamos por el más simple, el de la distancia entre caracteres. Mi código para enviar datos es este:
void TIMER2_IRQHandler(void) {
if(LPC_TIM2->IR & 0x1){ // Verificamos que la Int es por Match Register 0
LPC_TIM2->MCR &= ~3; // Deshabilito interrupcion del MR0 del timer 2
if ((line >= lTop) && (line <= lTop + lWid -1)){ //Cada caracter tiene 7 pixeles de alto
ltemp = (line - lTop) * 27 - 64;
LPC_SSP0->DR = ~ltrs[head[0] + ltemp]; Wait();
LPC_SSP0->DR = ~ltrs[head[1] + ltemp]; Wait();
LPC_SSP0->DR = ~ltrs[head[2] + ltemp]; Wait();
LPC_SSP0->DR = ~ltrs[head[3] + ltemp]; Wait();
LPC_SSP0->DR = ~ltrs[head[4] + ltemp]; Wait();
LPC_SSP0->DR = ~ltrs[head[5] + ltemp]; Wait();
LPC_SSP0->DR = ~ltrs[head[6] + ltemp]; Wait();
}
if ((line >= lBot) && (line <= lBot + lWid-1) && !cUpdate){
ltemp = (line - lBot) * 27 - 64;
ntemp = (line - lBot) * 14 - 45;
LPC_SSP0->DR = ~nums[cLatLon[0] + ntemp]; Wait();
LPC_SSP0->DR = ~nums[cLatLon[1] + ntemp]; Wait();
LPC_SSP0->DR = ~nums[cLatLon[2] + ntemp]; Wait();
LPC_SSP0->DR = ~nums[cLatLon[3] + ntemp]; Wait();
LPC_SSP0->DR = ~nums[cLatLon[4] + ntemp]; Wait();
LPC_SSP0->DR = ~nums[cLatLon[5] + ntemp]; Wait();
LPC_SSP0->DR = ~nums[cLatLon[6] + ntemp]; Wait();
LPC_SSP0->DR = ~nums[cLatLon[7] + ntemp]; Wait();
LPC_SSP0->DR = ~nums[cLatLon[8] + ntemp]; Wait();
LPC_SSP0->DR = ~nums[cLatLon[9] + ntemp]; Wait();
LPC_SSP0->DR = ~nums[cLatLon[10] + ntemp]; Wait();
}
}
LPC_TIM2->IR |= 0x1; // clear the interrupt
}
Cuando el timer interrumpe porque estoy en la columna donde empieza el texto tengo unos IF que verifican en que línea estoy para saber que mensaje debo enviar. Luego se hace un cálculo de un offset para las tablas de fuentes y voy poniendo uno a uno los datos en el Data Register del SPI. Luego llamo a la macro Wait, la cual tiene este código:
#define Wait() while ( LPC_SSP0->SR & (1 << 4) ); //Espero a que salga el dato completo
Como pueden ver la solucion es simple, me quedo esperando hasta que la bandera Busy esté en 0. O sea, cuando el SPI termine de enviar los datos.
Bueno, el tiempo entre caracteres es el tiempo que le toma al micro calcular el offset, almacenar el dato en el DataRegister e ir a la Macro. En tiempos tan ajustados, cada nanosegundo cuenta.
El tema es que de esta forma no uso el FIFO del SPI. Tranquilamente podría almacenar datos en el DR mientras el FIFO no esté lleno...
Entonces mi nuevo define de la funcion Wait es:
#define Wait() while ( (~LPC_SSP0->SR) & (1 << 1) );
Entonces si no está lleno el FIFO vuelvo enseguida del Wait y puedo almacenar otro dato en el DR ya que se van acumulando en el FIFO. De este modo, los caracteres ya quedan más juntitos.
El segundo problema, el temblequeo de los caracteres me costó un poco más. El indicio estaba en que el temblequeo se daba más o menos cada 1 segundo. Coincide con el data rate del GPS... entonces me di cuenta que cuando se ejecutaba el código de la UART se movia el texto... pensando pensando pensando recorde lo que me habia explicado BrunoF sobre las prioridades de las interrupciones. Lo que seguramente pasaba era que mientras estaba en la rutina del Timer2, escriviendo en pantalla, llegaban caracteres por el UART y por lo tanto me interrumpia la interrupcion del timer... la solucion... establecer la prioridad de cada interrupcion. Al timer 2 le puse la máxima prioridad, 0, a las interrupciones externas la siguiente prioridad, 1 y a la UART la siguiente, 2. De ese modo todo solucionado!
Ahora, mientras se cargan las baterías del sistema de video, estoy esriviendo el código para mostrar la informacion del GPS, lat y long...
Saludos!