91 lines
4.3 KiB
Markdown
91 lines
4.3 KiB
Markdown
---
|
||
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) |