Display não mostra caracteres especiais e acentuação

Software e Hardware para linha ARM

Moderadores: 51, guest2003, Renie, gpenga

Display não mostra caracteres especiais e acentuação

Mensagempor sergioms » 03 Fev 2011 12:17

Meu display funciona bem, só tem um problema.

Sempre que chamo a função para escrever na tela, se algum caractere for especial, ou tiver ç acentuação, é substituido por um ponto na tela.

Estou tendo o cuidado de usar unsigned char.

Código: Selecionar todos
/* ----------------------------------------------------------
 * Program to control a T6963C-based 240x64 pixel LCD display
 * using the PC's Parallel Port (LPT1:) in bidirectional mode
 * written in Microsoft Quick C
 *
 * Written by John P. Beale May 3-4, 1997  beale@best.com
 *
 *  Based on information from Steve Lawther,
 *  "Writing Software for T6963C based Graphic LCDs", 1997 which is at
 *  http://ourworld.compuserve.com/homepages/steve_lawther/t6963c.pdf
 *
 *  and the Toshiba T6963C data sheet, also on Steve's WWW page
 *
 *  and info at: http://www.citilink.com/~jsampson/lcdindex.htm
 *               http://www.cs.colostate.edu/~hirsch/LCD.html
 *               http://www.hantronix.com/
 *
 *  See also: http://members1.chello.nl/r.schotsman/LCDFrame.htm
 * ----------------------------------------------------------
 */

#include "t6963c.h"
#include "string.h"
#include "type.h"

/* -------------------- V A R I A V E I S -------------------------------- */
u32_t bytes_per_row;

/* -------------------- C O D I G O -------------------------------------- */
/* -------------------- P R O T O T I P O S ------------------------------ */
void  delay(u32_t d);  // delay proportional to "d" value
void  dput(u8_t byte);  // write data byte to LCD module
u32_t dget(void);      // get data byte from LCD module
u32_t sget(void);      // check LCD display status pbrt
void  cput(u8_t byte); // write command byte to LCD module

/* -------------------- M A C R O S -------------------------------------- */
#define home() dput(T_BASE%256);dput(T_BASE>>8);cput(0x24); // upper-left

/* -------------------- F U N C O E S ------------------------------------ */
/* Block writes would, I think, run faster if you used the DATA AUTO
   mode, eg command 0xB0. I didn't bother.
 */
 
/*
 * Limpa area do grafico
 *
 */
void lcd_clear_graph() {    // clear graphics memory of LCD
    u32_t i;

    dput(G_BASE%256);
    dput(G_BASE>>8);
    cput(0x24);       // addrptr at address G_BASE

    for (i=0; i<5120; i++) {
        dput(0); cput(0xc0);               // write data, inc ptr.
    } // end for(i)
} // end lcd_clear_graph()

/*
 * Limpa area do texto
 *
 */
void lcd_clear_text() {
    u32_t i;
   
    dput(T_BASE%256);
    dput(T_BASE>>8);
    cput(0x24);       // addrptr at address T_BASE
   
    for (i=0; i<(((YMAX+1)/8) * bytes_per_row); i++) {
        dput(0); cput(0xc0);               // write data, inc ptr.
    } // end for(i)
   
    cput(0x81); // EXOR mode
    cput(0x94); // Cursor ON blink
} // lcd_clear_text()

/*
 * Configura modo do cursor
 *
 */
void lcd_setcursor(u8_t mode, u8_t display, u8_t blink, u8_t pattern) {
    cput(0x80 + (mode & 0x03)); // mode
    cput(0x94 + ((display & 0x01) << 1) + (blink & 0x01));
    cput(0xa0 + (pattern & 0x07));
}

/*
 * Poe um caracter na tela
 *
 */
void lcd_putc(char ch) {
    ch -= 0x20;     // convert ASCII to LCD char address
   
    if (ch & 0x80)
        ch='.' - 0x20;
   
    dput(ch);
    cput(0xc0);               // write character, increment memory ptr.
}

/*
 * Imprime uma string na tela
 *
 */
void lcd_print(char *string) { // send string of characters to LCD
    u32_t i;
    u32_t c;
   
    for (i=0; i<strlen(string); i++) {
          c = string[i] - 0x20;     // convert ASCII to LCD char address
          if (c&0x80) c='.' - 0x20;
          dput(c);
          cput(0xc0);               // write character, increment memory ptr.
    } // end for
   
} // end lcd_string

/*
 * Liga um pixel na tela
 *
 */
void lcd_setpixel(u32_t column, u32_t row) { // set single pixel in 240x64 array
    u32_t addr;       // memory address of byte containing pixel to write
   
    addr =  G_BASE + (row*bytes_per_row)  + (column/8);
    dput(addr%256); dput(addr>>8); cput(0x24);  // set LCD addr. pointer
    cput(0xf8 | (7-(column%8)) );  // set bit-within-byte command

} // end lcd_setpixel()

/*
 * Posiciona ponteiro de escrita na RAM modo texto
 *
 */
void lcd_xy(u32_t x, u32_t y) {  // set memory pointer to (x,y) position (text)
    u32_t addr;

    addr = T_BASE + (y * bytes_per_row) + x;
    dput(addr%256); dput(addr>>8); cput(0x24);  // set LCD addr. pointer

} // lcd_xy()

/*
 * Posiciona cursor na tela
 *
 */
void lcd_cursorxy(u32_t x, u32_t y) {  // set cursor to (x,y) position (text)
  dput(x); dput(y); cput(0x21);  // set LCD addr. pointer
} // lcd_cursorxy()

/*
void delay(u32_t d)  // delay proportional to "d" value
{
    u32_ti;
    double a;

    a = 1.000;
    for (i=0;i<d;i++) {
        a = a / 1.001;
    }
} // end delay()
*/

/* ==============================================================
 * Low-level I/O routines to interface to LCD display
 * based on four routines:
 *
 *          dput(): write data byte
 *          cput(): write control byte
 *          dget(): read data byte         (UNTESTED)
 *          sget(): read status
 * ==============================================================
 */

void lcd_init(u32_t fs)  // initialize LCD memory and display modes
{

    if(fs) {
        FSHI;
        bytes_per_row = 40;
    }
    else {
        FSLO;
        bytes_per_row = 30;
    }

    dput(G_BASE%256);
    dput(G_BASE>>8);
    cput(0x42);       // set graphics memory to address G_BASE
   
    dput(bytes_per_row%256);
    dput(bytes_per_row>>8);
    cput(0x43);  // n bytes per graphics line
   
    dput(T_BASE%256);
    dput(T_BASE>>8);
    cput(0x40);       // text memory at address T_BASE
   
    dput(bytes_per_row%256);
    dput(bytes_per_row>>8);
    cput(0x41);  // n bytes per text line
   
    cput(0x80);  // mode set: Graphics OR Text, ROM CGen
   
    cput(0xa7);  // cursor is 8 lines high
    dput(0x00);
    dput(0x00);
    cput(0x21);  // put cursor at (x,y) location
   
    cput(0x97);  // Graphics & Text ON, cursor blinking
          // (For cursor to be visible, need to set up position)
   
} // end lcd_init()


// ----------------------------------------------------------------
u32_t sget(void) { // get LCD display status byte
  u32_t lcd_status;

  CDHI;         // bring LCD C/D line high (read status byte)
  lcd_status = LCD_BASE_ADDR;      // read LCD status byte
  return(lcd_status);
} // sget()


void dput(u8_t byte) { // write data byte to LCD module over par. port
                     // assume PC port in data OUTPUT mode
  do {} while ((0x03 & sget()) != 0x03); // wait until display ready
  CDLO;
  LCD_BASE_ADDR = byte;    // write value to data port
} // end dput()


u32_t dget(void) {      // get data byte from LCD module
  u32_t lcd_byte;

  do {} while ((0x03 & sget()) != 0x03); // wait until display ready
  CDLO;   // data mode
  lcd_byte = LCD_BASE_ADDR;  // read data from LCD

  return(lcd_byte);
} // dget()

void cput(u8_t byte) { // write command byte to LCD module
          // assumes port is in data OUTPUT mode
  do {} while ((0x03 & sget()) != 0x03); // wait until display ready

  CDHI;                       // control/status mode
  LCD_BASE_ADDR = byte;    // write value to data port

} // cput()

sergioms
Bit
 
Mensagens: 5
Registrado em: 03 Mar 2009 17:20

Mensagempor xultz » 03 Fev 2011 12:35

Você tem dois problemas aí:
Primeiro, o que o compilador interpreta como 'ç'. Ou seja, que valor da tabela ASCII ele está assumindo. A tabela ASCII não possui 'ç', isso geralmente aparece na parte superior da tabela, e foram criadas várias páginas, umas com caracteres latinos especiais (como ç á é õ e assim por diante), outro com símbolos japones, coreanos, etc. O que teu compilador está fazendo? Sabe Deus.
Segundo, cada fabricante de display tem uma tabela superior própria. Tem fabricante que implementa os caracteres latinos, outros colocam símbolos japoneses/chineses/sei lá. Basta mudar de fabricante, que a tabela muda todinha.
O que eu faria: desenhava esses carateres na área da CGRAM, e substituía os 'ç' e acentos por caracteres da CGRAM. Como não cabem muitos, é possível que você tenha que desenhar on-the-fly: vai precisar de um ç? Desenha e põe na tela.
É um saco, mas é o jeito de deixar o firmware compatível com qualquer display do mercado.
98% das vezes estou certo, e não estou nem aí pros outros 3%.
Avatar do usuário
xultz
Dword
 
Mensagens: 3001
Registrado em: 13 Out 2006 18:41
Localização: Curitiba

Mensagempor sergioms » 03 Fev 2011 13:02

URL=http://img706.imageshack.us/i/charrom.jpg/]Imagem[/URL]

Uploaded with ImageShack.us
sergioms
Bit
 
Mensagens: 5
Registrado em: 03 Mar 2009 17:20

Mensagempor eletroinf » 03 Fev 2011 14:55

É como disse o xultz. Pela tabela asc estendida que eu tenho aqui, o Ç é 128 e o ç 135. Pelo seu código, se for acima de 127 a função muda o valor, pois ao que me parece a tabela do display é abaixo disso... não olhei bem, mas pela sua tabela do display o ç é outro valor, algo tipo 1100000 para o maiúsculo e 1100111 para o maiúsculo. Ambos números são menores que 128.
"De cada um segundo sua capacidade a cada um segundo sua necessidade."
Avatar do usuário
eletroinf
Word
 
Mensagens: 948
Registrado em: 12 Out 2006 14:59
Localização: Santa Maria - RS


Voltar para ARM

Quem está online

Usuários navegando neste fórum: Google [Bot] e 1 visitante

cron

x