Экран на контроллере RA8875 и чип шрифтов GT21L16T1W

Тема в разделе "Arduino & Shields", создана пользователем PIW2004, 18 апр 2014.

  1. PIW2004

    PIW2004 Нуб

    Имеется TFT экран на базе контроллера RA8875, так же на борту установлен чип со шрифтами GT21L16T1W, После небольшей доработки стандартной библиотеки для этого экрана удалось инициализировать чип шрифтов и вывести текст с их использованием.

    Но возникла проблемка.

    Штатно за вывод текста отвечает вот этот код:

    Основная часть где вводим текст
    Код (Text):
    char string[ ] = "Hello 123456 Привет 123456";
    tft.textWrite(string);
    А это как обрабатывается команда textWrite в библиотеке
    Код (Text):
    void Adafruit_RA8875::textWrite(const char* buffer, uint16_t len)
    {
    if (len == 0) len = strlen(buffer);
    writeCommand(RA8875_MRWC);
    for (uint16_t i=0;i<len;i++)
    {writeData(buffer[i]);
    #if defined(__AVR__)
    if (_textScale > 1) delay(1);
    #elif defined(__arm__)
    if (_textScale > 0) delay(1);
    #endif
    }
    }
    Но возникает проблема, для правильной кодировки символов, с кодом каждого символа необходимо произвести дополнительные манипуляции, взято из даташита на GT21L16T1W.
    Код (Text):
    BaseAdd=0x56BDE +425*34
    if (FontCode>=0x0400) and (FontCode<=0x045F) then
    Address = (FontCode– 0x0400) * 34+BaseAdd
    Else if (FontCode>=0x0490) and (FontCode<=0x04a3) then
    Address = (FontCode– 0x0490+96) *  34+BaseAdd
    (Код сравнения символов и назначения чуть длиннее, но суть та же, арифметические операции к коду символа)

    Попробовал сделать вот так:
    Код (Text):
    void Adafruit_RA8875::textWrite(const char* buffer, uint16_t len)
    {
    if (len == 0) len = strlen(buffer);
    writeCommand(RA8875_MRWC);
    for (uint16_t i=0;i<len;i++)
    {char temp = buffer[i];
    if (temp >= 0x0400 && temp <= 0x045F)  {temp = temp - 0x0400 * 34 + 0x5A450;}
    else if (temp >= 0x0490 && temp <= 0x04A3) {temp = temp - 0x0490 + 96 * 34 + 0x5A450;}
    writeData(temp);
    #if defined(__AVR__)
    if (_textScale > 1) delay(1);
    #elif defined(__arm__)
    if (_textScale > 0) delay(1);
    #endif
    }
    }
    Но выдаёт ошибки:

    assignment of read-only location '*(buffer + ((unsigned int)i))'

    По переводу на русский означает, что переменная только для чтения, но я же произвожу операции с temp, а не buffer?!

    И вторая ошибка

    invalid conversion from 'const char*' to 'char'

    Понимаю, что явно ошибки в преобразовании и сравнении, но т.к. опыта в написании мало, прошу помощи.
     
  2. acos

    acos Официальный гик Администратор

    А что за функция WriteData? Как выглядит?
     
    Последнее редактирование: 19 апр 2014
  3. geher

    geher Гуру

    Пока реальных ошибок в языковых конструкциях не заметил.
    Упорно лезет в голову мысль, что это может оптимизатор чудить.
    Если можно, на какие точно строки идет ругань (номера строк должны быть в сообщении об ошибке)?

    Теперь по самому преобразованию.
    Может быть, я с утра где-то и ошибаюсь, но мне кажется верным следующее.
    1. В char двухбайтовое значение не влезет. А потому (temp >= 0x0400 && temp <= 0x045F) всегда будет false.
    2. В коде явно пропущены скобки из кода даташита.
    3. Судя по коду из даташита, это, скорее всего, преобразование не самого кода символа, а какого-то адреса (возможно, адреса таблицы знакогенератора, в смысле адрес рассчитывается на основании кода символа или, возможно, номера символа в шрифте, который похож на юникодовский код симвода). Причем в качестве кода символа используется двухбайтовое число. Судя по используемым константам (если не напутал), Unicode UTF16 BE.

    В итоге видно, что, во-первых, следует определиться с используемой кодировкой символов в программе.
    Если она не Unicode или другой вариант Unicode (UTF16 LE, UTF8), то придется скорректировать формулы с учетом используемой кодировки. Точно не вспоминается навскидку, но вроде для ANSI (WIN1251, поскольку речь идет о русских символах, опять же, судя по используемым константам) нужно как минимум отнять из всех используемых констант в диапазоне 0х0400-0х04FF значение 0х0400, чтобы оперировать не со страницей в кодовом пространстве UTF16, а с 256 символьной таблицей ANSI.
    Кроме того, следует понять, что есть BaseAdd (добавлю, и Address) в коде из даташита, и как его надо использовать (точно не так, как в вашем коде).
     
    Последнее редактирование: 19 апр 2014
  4. Unixon

    Unixon Оракул Модератор

    PIW2004, приводите, пожалуйста, сообщения компилятора об ошибках вместе с номерами строк, в которых он их видит.