mmote.ru/content/posts/avr-lcd-images/index.md

91 lines
4.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
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). Всё отлично, но библиотека умеет рисовать круги, линии, прямоугольники, выводить полноэкранные изображения, НО. Что должен уметь электронный барометр?
<!--more-->
Правильно, определять погоду по давлению. И выводить картинку с облачком или солнышком. А с полноэкранным изображением это делать не вариант - занимает кучу памяти да и с обновлением дисплея будет беда. Так что, я взялся за дело. Просидев весь вечер, написал программку-рисовалку картинок с конвертацией в массив и функцию-дополнение к библиотеке. Вот так выглядит программа:
![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 <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#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 <span style="text-decoration: underline; color: #993366;">char</span> out** нужно использовать **const <span style="text-decoration: underline; color: #008000;">unsigned char</span> out.** Исходник я давно потерял, поэтому исправить не могу.
**Ссылки:**
[LCDPict](lcdpict.zip)
[Библиотека для дисплея nokia3310](https://github.com/gresolio/N3310Lib)
[Форк библиотеки с программным SPI](https://github.com/MultiMote/N3310Lib)