--- title: "Вывод иконок на дисплей Nokia 3310/5110 (переходим на avr-gcc)" categories: ["mcu", "archive"] date: 2015-08-13T00:00:00+03:00 draft: false featured_image: miniature.jpg --- Наконец-то переехал с CVAvr на AVR-GCC. От нечего делать начал собирать барометр. Купил nokia3310, выдрал дисплей. Библиотеку использовал [вот эту](https://github.com/gresolio/N3310Lib). Всё отлично, но библиотека умеет рисовать круги, линии, прямоугольники, выводить полноэкранные изображения, НО. Что должен уметь электронный барометр? Правильно, определять погоду по давлению. И выводить картинку с облачком или солнышком. А с полноэкранным изображением это делать не вариант - занимает кучу памяти да и с обновлением дисплея будет беда. Так что, я взялся за дело. Просидев весь вечер, написал программку-рисовалку картинок с конвертацией в массив и функцию-дополнение к библиотеке. Вот так выглядит программа: ![LCDPict|](lcdpict.png) Прямая ссылка, по традиции, в конце статьи. Функция выглядит следующим образом: ```c byte LCDIcon(const byte *pic, byte x, byte y, byte arrayRows, byte arrayColumns, byte progMem) { byte iterCol; byte iterRow; byte iterByte; byte picX = x; byte picY = y; byte symbolChar; for (iterCol = 0; iterCol < arrayColumns; iterCol++) { for (iterRow = 0; iterRow < arrayRows; iterRow++) { if (progMem) { symbolChar = (byte) pgm_read_byte(&pic[iterCol + iterRow * arrayColumns]); } else { symbolChar = pic[iterCol + iterRow * arrayColumns]; } for (iterByte = 0; iterByte < 8; iterByte++) { if ((symbolChar >> iterByte) & 1) { LcdPixel(picX, picY, PIXEL_ON); } picY++; } } picY = y; picX++; } UpdateLcd = TRUE; return OK; } ``` В качестве первого аргумента скармливаем **указатель на первый элемент массива**, второй и третий - координаты картинки,предпоследние аргументы - размер **массива, не картинки**. Не путать. Последний аргумент определяет откуда читать данные: из памяти МК (атрибут **PROGMEM**) или же из оперативной памяти. Пример: ```c #include #include #include #include "n3310.h" const byte out[2][24] = { {0x0, 0x0, 0x0, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0, 0xc, 0x6, 0x86, 0xc6, 0xec, 0xb8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, {0x0, 0x0, 0x0, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x0, 0x18, 0x10, 0x10, 0x10, 0x19, 0xf, 0x0, 0x0, 0x0, 0x0, 0x0} }; int main(void) { LcdInit(); while (1) { LcdClear(); LCDIcon(&out[0][0], 0, 0, 2, 24, false); LcdUpdate(); _delay_ms(5000); } } ``` UPD: Только сейчас заметил, что в программе неверно написан тип данных. Вместо **const char out** нужно использовать **const unsigned char out.** Исходник я давно потерял, поэтому исправить не могу. **Ссылки:** [LCDPict](lcdpict.zip) [Библиотека для дисплея nokia3310](https://github.com/gresolio/N3310Lib) [Форк библиотеки с программным SPI](https://github.com/MultiMote/N3310Lib)