Библиотека AVR-GCC для lcd-экрана Nokia 6610. Обновление.

Валера Гончаренко подготовил очередное обновление своей библиотеки для работы с lcd-экраном от  Nokia 6610. Исправлены ошибки, добавлены новые функции. Ему слово:

На данный момент в свою библиотеку для работы с LCD Nokia6610 я добавил вывод изображений. Вывод текста теперь возможен и по-русски, добавил кириллический шрифт (если неиспользуете кириллицу, то можно отключить эту возможность для экономии ресурсов). Также поправил функции вывода данных из RAM-памяти дисплея.

Теперь немного подробней: в процессе эксплуатации библиотеки я выявил, что команда nlcd_SendByte(CMD_LCD_MODE,LCD_PHILLIPS_MADCTL) выводит текст и изображение не совсем корректно — то есть не по datasheet-у. Прошерстил всю библиотеку, сейчас все функции откорректированы. Так же добавил префикс LCD_PHILLIPS к командам контроллера, дабы избежать путаницы в дальнейшем, так как библиотеку можно использовать и с аналогичными контроллерами других фирм. Для них будет отдельный префикс на такие же команды.

Рекомендую использовать для работы именно эту библиотеку. Получилась она довольно большой. Если она избыточна — всегда ведь можно удалить невостребованные функции, это экономит память программ контроллера (это применительно к мега8). В приложенный к статье архив входят две библиотеки — одна для ATMega8, другая для ATMega32. Разница только в мэйкфайле (makefile) – необходимо выбрать контроллер, с которым будем работать.

Если используем библиотеку для меги32 и меняем настройки в мэйкфайле на мега8 — то не забываем и массив с изображением заменить. Иначе компилятор будет ругаться, и создание HEX-файла будет невозможно. Это происходит из-за того, что размер массива с изображением для мега32 намного превышает объем памяти программ мега8.

Кстати, изображение хранится в памяти программ, конечно, это кощунство – хранить изображение в контроллере, надо бы использовать карту памяти, но пока это, только, в планах. Данные библиотеки призваны продемонстрировать возможности библиотеки и экрана LCD. Далее описание работы библиотеки буду приводить на примере использования Меги32.

Первое что мы сделаем — это преобразуем наше изображение в формат понятный программе-конвертеру, который его сохранит в виде массива. Для этого используем любую программу, которая сохраняет картинки в формате BMP. Я использую Paint.NET. Открываем наше изображение, далее вверху экрана жмем кнопку Изображение -> Изменить размер. Размер по вертикали и горизонтали устанавливаем в пределах 0-132 пикселя. Жмем Ок.

Работа в Paint.Net

Работа в Paint.Net

Файл — >Сохранить как.. Здесь обязательно указываем имя файла с расширением BMP и тип файла – BMP. Жмем Сохранить. Далее будут предложены параметры сохранения — оставим глубину цвета по умолчанию 24 бита. Жмем Ок.

Сохраняем файл в Paint.Net

Сохраняем файл в Paint.Net

Теперь мы преобразуем наше подготовленное изображение в массив, который вставим в нашу библиотеку. Открываем программу NokiaImageCreator, жмем кнопку Open Image и указываем наш подготовленный bmp-файл. Размер по вертикали и горизонтали выставляем согласно размеру изображения 132х94 пикселя. Теперь выберем опцию 12-bit (0x03) и жмем Create C Code.

Конвертер Nokia Image Creator

Конвертер Nokia Image Creator

12 бит (0x03) означает, что преобразование изображения будет происходить 12 бит на пиксель RRRRGGGGBBBB , RGB 4:4:4 то есть 4096 цветов, а байт данных 0х03 – указывает на цветопередачу, это можно увидеть в библиотеке: строка 53 и 54.

Programmers Notepad

Programmers Notepad

Продолжим. Программа предложит сохранить файл, присваиваем файлу имя, тип файла указываем .txt. Жмем Ок. Затем открываем файл с расширением .txt в любом текстовом редакторе, например в блокноте, копируем наш массив и вставляем в программу.

Информация на дисплее отображается начиная отсчет из верхнего левого угла – слева направо и сверху вниз.

Рассмотрим, к примеру, функцию nlcd_Bitmap (41, 41, 50 , 50, bitmap_data) немного подробней. Первое число в функции (41) – указывает на начало отображения изображения по оси X в пикселях, т.е. по горизонтали слева направо. Второе число 41- указывает на начало отображения изображения по оси Y в пикселях, но уже по вертикали – сверху вниз. Далее идет размер нашей картинки в пикселях по горизонтали и по вертикали соответственно (50×50 пикс.) и указатель на массив с изображением.

Контроллер тактируется от внутреннего RC-генератора 8 МГц, фьюзы для программы AVRDUDE выставляем так:

Фьюзы (fuses) в AVR Dude

Фьюзы (fuses) в AVR Dude

Схема подключения адаптера и «распиновка» ног контроллера остались прежними, как и в предыдущих версиях этой библиотеки, то есть ничего не менял. Пины, к которым подключен LCD-экран к контроллеру можно посмотреть (и изменить) в файле Nokia6610_lcd_lib.h. Вот, пожалуй, и все. Если возникнут вопросы, пишите здесь — я готов помочь.

ЗЫ: приведу еще несколько фоток с примером, как выглядят картинки на экране nokia 6610. Качество фоток не очень, фоткал на мобильник. В жизни все выглядит намного лучше. Но хоть что то, уж не обессудьте.

Картинка на экране с помощью ATMega8

Картинка на экране с помощью ATMega8

Эта же картинка на экране с помощью ATMega32

Эта же картинка на экране с помощью ATMega32

Ну и просто набор картинок на Мега32:

Картинка 1 - ATMega32, lcd nokia 6610

Картинка 1 - ATMega32, lcd nokia 6610

 

Картинка 2 - ATMega32, lcd nokia 6610

Картинка 2 - ATMega32, lcd nokia 6610

Картинка 3 - ATMega32, lcd nokia 6610

Картинка 3 - ATMega32, lcd nokia 6610

Картинка 4 - ATMega32, lcd nokia 6610

Картинка 4 - ATMega32, lcd nokia 6610

Это все. Пишите.

Валерий Гончаренко
для DigitalChip.ru

 

17 комментариев на “Библиотека AVR-GCC для lcd-экрана Nokia 6610. Обновление.”

  1. -Валера-

    Хочу заметить, что при преобразовании изображения в BMP формат, не обязательно указывать максимальное разрешение 132х132 пикселя, программа Nokia Image Creator «обрежет» изображение максимум 132х132 пикс. А вот если есть желание использовать изображения меньшего размера, то явно следует указывать их размер по горизонтали и вертикали в пикселях.

  2. Денис

    В функции nlcd_Pixel похоже ошибка, цвет пикселя получается не тот, что должен быть. Необходимо изменить:

      nlcd_SendByte(DATA_LCD_MODE, (unsigned char)((color>>4)& 0xff) );
      nlcd_SendByte(DATA_LCD_MODE, (unsigned char)((color&0xf)<<4)|0x00 );

    на то, как это сделано в nlcd_Box:

      nlcd_SendByte(DATA_LCD_MODE,(color >> 4) & 0xFF );
      nlcd_SendByte(DATA_LCD_MODE,((color & 0xF) << 4) | ((color >> 8) & 0xF) );
      nlcd_SendByte(DATA_LCD_MODE,color & 0xFF);

    А для упрощения работы с палитрой можно сделать так:

    typedef struct COLORREF
    {
       unsigned char R;   
       unsigned char G;   
       unsigned char B;  
    }COLORREF;

    COLORREF crPINK = {255,0,128}: //RRRGGGBBB

    #define RGB12BIT(COLORREF)     ((int)(COLORREF.R & 0xf0) << 4) | (COLORREF.G & 0xf0) | ((COLORREF.B & 0xf0) >> 4)

    Спасибо за библиотеку, пока отлаживаю в Proteus, если кому нужно вот компонент:
    http://projectproto.blogspot.com/2010/11/nokia-lcds-proteus-vsm-models.html
     
     

  3. -Валера-

    Да- видимо я ошибся, исправлю, так бывает когда делаешь сразу несколько дел.

    А для упрощения работы с палитрой можно сделать так

    У меня сначала и была задумка так сделать, но потом я решил, что это будет избыточно- ведь по-большому счету необходимое количество цветов можно сразу заготовить (типа   #define PINK      0xF6A ) , а отображать всю палитру- ?!  Зачем ? При отображении картинок все и рак работает.
    У меня вопрос: по ссылке эта библиотека работает с моделью под контроллер Phillips PCF8833 ?

  4. Денис

    отображать всю палитру- ?!  Зачем ?

    Так то правильно, просто у меня идея сделать универсальную библиотеку для разных дисплеев. У меня лежит дисплей от S65, под него модели я не нашел, поэтому код отрабатываю на 6610. Чтобы потом не искать и не переписывать палитру под 16 бит я сделал так.

    По ссылке эта библиотека работает с моделью под контроллер Phillips PCF8833 ?

    Да, на этой модели я запускал Вашу библиотеку, только я качал с другого сайта.

    • -Валера-

      А что влаживаешь в смысл- сделать библиотеку универсальной, под какие дисплеи?  У меня тоже имеются пара дисплеев от S65: контроллеры LS020 и L2F50. Думаю их тоже куда-нибудь прикрутить- пока руки не доходят, покопаюсь на досуге в компе- может и модель на S65 найдется.

      • Денис

        По известному закону у меня два LPH88 ))) В планах реализовать аппаратный SPI и написать универсальную библиотеку графических примитивов с учетом возможности использовать ее в будущем на следующих моделях дисплеев большего размера. Единственное я на CVAVR все привык делать.

        • -Валера-

          По известному закону у меня два LPH88 )))

          Так они по системе команд совпадают с LS020, а вот L2F50- там уже другие грабли. Одно меня расстраивает- найти дисплеи от Siemens S65: практически нереально, они сняты с производства и уже давно, или цена заоблачная. Я, правда, 2 штуки «вырвал» плюс плату с «семена» — чтобы можно было разъем под дисплей сдуть. В принципе- я преследую такую же цель: сначала тренировка на 6610, затем дисплей от Nokia6300   320х240, ну и остановку сделаю на Nokia N95- разрешение тоже, только размеры больше.Было бы интересно увидеть твои наработки, может и я чего-нибудь взял бы на вооружение. ИМХО, данные дисплеи перспективны в плане распространенности и цена у них- адекватная.     
          Я когда пробовал писать библиотеку- пробовал CVAVR, но не пошло у меня с ним дело- остановился на Winavr, но различия между компиляторами, по-моему несущественные.

  5. Привет всем! почемуто у меня в протеусе вывод текста по оси Y отображается  зеркально и всё изображение повёрнуто на 90 градусов против часовой стрелки. (пока отлаживаю в проге перед записью в МК) какими командами при инициализации это исправить?(немогу выложить скрин)

    • -Валера-

      Советую посмотреть в сторону команды MADCTL (0x36) , но ИМХО модели в протеусе мне попадались какие-то неадекватные)), так и не смог нормально поработать с дисплеями. Советую сразу в железе проверять и это…  возможно проблема не в команде, а функции вывода текста. Нужно смотреть..

  6. Спасибо за ответ! всё верно, повернул по Y (команда 0х36) и переделал маленько функцию вывода символов, сечас всё прекрасно работает. изначально всё было предусмотрено для «бокового» расположения дисплея, т.е. шлейф с боку, а в протеусе дисплей вертикально (шлейфом вниз). Вобшем спасибо ещё раз и за статью и за библиотеку :).
     
     

  7. Здравствуйте, хочу сделать так-же не подскажете список нужных деталей, и схему? А то не очень пока понимаю

    • -Валера-

      Деталей немного, попрошу chiper-а добавить схемку в архив.  Дисплей Nokia6610, или подобный с коричневым шлейфом (контроллер PCF8833)-1 шт., микроконтроллер (Mega8, Mega32, Mega128- любой AVR, все зависит от объема памяти flash т.к. я всё- и шрифты и картинки храню в ней. Ответный разъем к дисплею-1 шт, резисторы 1К и 470 Ом- по 4 шт каждого, из них состоит делитель- на минус питания выводы всех резисторов 1к а их оставшиеся выводы к контактам дисплея: CS,SCK,SDA,RST.  К указанным выводам дисплея подключаем резисторы на 470 Ом а их ответные части идут к нашему контроллеру. Применительно к Mega32- RST—>PC0, CS—>PC1, SDA—>PC2, SCK—>PC3.  Стабилизатор на 3,3 Вольта, (любой- например 1117, в любом корпусе) два конденсатора на 0,1 мкф и два на 10мкфх10В. На разъеме дисплея следующие манипуляции- вывод 1,6,10 подаем 3,3 вольта, вывод- 9,8 минус питания (и контроллера -5в и стабилизатора -3,3в). Вывод 2- RST, вывод 3- SDA, вывод 4- SCK, вывод 5- CS.
      Уменя программатор USBAsp который питается от порта ноутбука, а уже с программатора 5 вольт заведено на прошиваемый контроллер и стабилизатор дисплея (3,3 вольта). Пожалуй, все..)

    • Добавил картинку со схемой адаптера Nokia 6610 в конце этого поста: http://digitalchip.ru/ispolzovanie-tsvetnogo-displeya-ot-nokia-6610

  8. Вообще конечно русские символы не выводятся, но не в этом проблема:)

    short temperature;
    temperature = tempPress.getTemperature();
    

    Такой вот код. В итоге имею temperature с нужными показаниями. А как их вывести на экран?
    Если просто

    nlcd_Text(temperature,10,3,GREEN,BLACK);
    

    То вылетает ошибка:

    Nokia6610_main.ino: In function 'void loop()':
    Nokia6610_main:75: error: invalid conversion from 'short int' to 'char*'
    Nokia6610_main:75: error: initializing argument 1 of 'void nlcd_Text(char*, unsigned char, unsigned char, int, int)'
    

    Как быть?
     

    • Так не получится. На вход функции nlcd_Text подается строка, а вы пытаетесь подать число. Поэтому и вылазит ошибка по конвертации типов.

      Вам необходимо преобразовать число в переменной temperature в строковый формат. Это можно сделать многими путями. Например, используя стандартные библиотечные функции printf, sprintf и т.д. (но это увеличит размер программы килобайта на 2-3.

      Или написать функцию преобразования числа в строку.

      Вот пример такой функции:

      char* itoa(int value, char* result, int base)
      {
          // check that the base if valid
          if (base < 2 || base > 36) { *result = '\0'; return result; }
          
          char* ptr = result, *ptr1 = result, tmp_char;
          int tmp_value;
          
          do{
              tmp_value = value;
              value /= base;
              *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" [35 + (tmp_value - value * base)];
          } while ( value );
          
          // Apply negative sign
          if (tmp_value < 0) *ptr++ = '-';
          *ptr-- = '\0';
          while(ptr1 < ptr){
              tmp_char = *ptr;
              *ptr--= *ptr1;
              *ptr1++ = tmp_char;
          }
          return result;
      }

       

      Ну и соответственно

      short temperature;
      char* buffer;
      temperature = tempPress.getTemperature();
      itoa(temperature, buffer, 10);
      nlcd_Text(buffer,10,3,GREEN,BLACK);
      

Добавить комментарий

Поля, помеченные знаком звездочка (*) обязательны для заполнения.