Работа с дисплеем от nokia 3310

Работа с дисплеем от nokia 3310

Дисплей идет в сборе с клавиатурой и динамиком, поэтому для универсальности отрезал все лишнее и собрал вот такой модуль:

Библиотеку для работы с дисплеем в Bascom-AVR взял отсюда. Эта библиотека позволяет выводить цифровую, текстовую и графическую информацию. Для подготовки картинок нашел замечательную программу FastLCD, которая шла под компилятор FastAVR, но после небольшой доработки выходного файла изображения, можно использовать с этой библиотекой.
Для примера подготовил картинку в формате BMP разрешением 48 на 84 пикселя, картинка должна быть монохромной:

После создания изображения, перегоняем его в массив данных для библиотеки, кнопкой BAS. Получаем следующий код:

Который необходимо привести к такому виду (перед каждой строчкой ставим Data):

Теперь копируем подготовленный массив в файл 3310bmp1.bas
Компилируем и наблюдаем следующую картину:

А вот как это выглядит вживую:

  • 1
  • 2
  • 3
  • 4
  • 5

tank u 82 exersizze

how i can a var as byte and . and show on display
for example:

dim rus as byte

how I show var rus ??

hi
for me have some error
please edit or what this error

http://wle.ir/up/do.php?imgf=139204670353481.jpg
http://wle.ir/up/do.php?imgf=139204670358922.jpg
http://wle.ir/up/do.php?imgf=139204670363453.jpg

Выходит что на 8й меге не запустится? Вот сейчас пробую и не выходит, и похоже что это из-за размеров стека.

UDP: Все запустилось, проблема была в том, что при 3.3 В питания мега8 прошивалась некорректно. 5 В питания все исправили.

Да синим маркером поперек, видимо на складе для себя пометку делают.
С отображением текста и цифр удалось,а вот при выводе своей картинки всё так же рассыпается: Инициализация: вводим строки не с 0 до 5, а с 1 до 6
В подпрограмме очистки ввел ‘For D3310pixelloop = 0 To 711 вместо For D3310pixelloop = 0 To 503
Sub D3310reset
D3310re = 0
Waitus 250
D3310re = 1
End Sub

Sub D3310init
D3310ce = 0 ‘Display data input enable
D3310dc = 0 ‘Command mode
D3310commandout &H21 ‘Перевод LCD в режим внешних команд.Расширенный режим команды, горизонтальное расположение
D3310commandout &H45 ‘ Для китайского
D3310commandout &HC8 ‘Middle contrast
D3310commandout &H06 ‘Temperature setting
D3310commandout &H14 ‘Bias 1:48 //как ни странно это контрастность по умолчанию 13
D3310commandout &H20 ‘Normal command mode, horizontal addressing
D3310commandout &H0C ‘Uninverted Screen
D3310ce = 1 ‘Display data input disable
End Sub

Не могу понять почему картинки выводит криво, в каком месте библиотеки копаться может кто знает?

Синим маркером пречеркнут в самую точку, в С дисплей китайский вроде победили я думаю и в Bascome можно. осталась пока полоса вверху в пиксел, читаю дальше по форумам.
Пока инициализация имеет вот такой вот вид:

Sub D3310init
D3310ce = 0 ‘Display data input enable
D3310dc = 0 ‘Command mode
D3310commandout &H21 ‘Extended command mode, horizontal addressing
‘D3310commandout &HC8 ‘Middle contrast
D3310commandout &HE1

D3310commandout &H06 ‘Temperature setting
D3310commandout &H13 ‘Bias 1:48

D3310commandout &H7F ‘ Для китайского
D3310commandout &H20 ‘Normal command mode, horizontal addressing
D3310commandout &H0C ‘Uninverted Screen
D3310ce = 1 ‘Display data input disable
End Sub

я вот сейчас раскрутил старый оригинальный nokia 3310 и вытащил экран из него. на железке слева вверху выдавлено nokia. вот этот дисплей сразу заработал как надо.
жаль, что это последний оригинальный экран.

(а на купленных мной китайцах на всех 5ти экранах еще и маркером синяя полоска, и рыжая квадратная наклеечка прямо на экран)

Верхняя строка съедается, в общем картинка как бы сдвинута вверх.
Пробовал вставлять D3310commandout &H7F ‘ первая строка на пиксель ниже
Но тогда не помещается шрифт Х4,съедается нижняя строка.

Sub D3310init
D3310ce = 0 ‘Display data input enable
D3310dc = 0 ‘Command mode
D3310commandout &H21 ‘Extended command mode, horizontal addressing
D3310commandout &HC8 ‘Middle contrast
D3310commandout &H06 ‘Temperature setting
D3310commandout &H13 ‘Bias 1:48
D3310commandout &H7F ‘ Для китайского
D3310commandout &H20 ‘Normal command mode, horizontal addressing
D3310commandout &H0C ‘Uninverted Screen
D3310ce = 1 ‘Display data input disable
End Sub

Электроника и автоматика на МК

Обозначения выводов приведены в таблице:
Вывод..Название..Функция
1..| VDD..| Питание +2.7. +3.3В
2..|SCLK..|Тактовый сигнал SPI
3..|SDIN..|Линия данных SPI
4..|DC. |Режим: данные(HIGH)/команда(LOW)
5..|SCE. |Выбор кристалла (LOW)
6..|GND . |Земля
7..|VOUT .|Внутреннее напряжение
8..|RES. |Сброс (LOW/HIGH)
Для подсоединения проводов к контактам надо постараться сделать (найти) разъём, но в крайнем случае можно припаять проводки прямо к контактам. При этом нужно быть крайне осторожным дабы не перегреть контакты и не испортить стекло.
Дисплей питается от 3,3 вольтах. Чтобы подключить дисплей к микроконтроллеру, который питается от 5 вольт понадобиться небольшая развязка(Рис.2). Между выводом 7 VOUT и землёй дожен быть подключен конденсатор ёмкостью 1..10 мкФ(керамика или электролит) — фильтр для внутреннего источника питания LCD. Вывод 5 SCE можно сразу подцепить на землю.При нуле на SCE – чип дисплея принимает данные с входящей линии, при единице – находится в состоянии высокого импеданса, то есть отключён от линии.(сигнал ноль-активен).Назначение остальных выводом узнаем по ходу статьи.

Немного теории о том, как организована работа контроллера этого экрана.
Сразу после подачи питания экран необходимо сбросить, подав на вывод RES «0». Это нужно сделать обязательно, иначе можно повредить контроллер! После сброса (перевод RES «0»->»1″) контроллер готов к записи. Чтение из контроллера не предусмотрено. Применяется стандартный SPI протокол: на вывод SCE подаётся активный низкий уровень, и по линии SDIN вводятся биты данных. Защёлкивание бита осуществляется по переднему фронту SCLK, сдвиг по заднему, данные передаются старшим битом вперёд (MSB). Если во время передачи последнего бита из восьми на выводе D/C логическая «1», то запись производится в память данных, иначе в управляющие регистры.

Для задания режима работы служат несколько управляющих регистров. Запись в них происходит при «0» на выводе DC. ( LOW DC )
ссылка на таблицу управляющих регистров

Reserved приведённый регистор команд являются резервированными и его использование недопустимо и далее где будет такой регистр мы будем его пропускать так он не предоставляет нам интереса(хотя практически им тоже можно побаловаться можите почитать тут).
Function set 0 0010 0PVH управление питанием, способ ввода, выбор расширенных инструкций. Команда Function Set изменяет 3 управляющих бита контроллера:
• P — PowerDown; P=0 — кристалл включен; P=1 — кристалл в режиме низкого эн.потребления
• V — адресация; V=1 — увеличивается указатель адреса строк(вертикальная адресация); V=0 — столбцов(горизонтальная адресация);
• Н — набор инструкций; H=0 — обычный; H=1 — расширенный
Write Data 1 dddd dddd запись данных в память дисплея..просто передача байта в память экрана, dddd dddd — просто байт данных.

Набор инструкций для H=0-обычный:
Display Control 0 0000 1D0E режимы отображения. Команда Display Control включает следующие режимы отображения:
• D=0, E=0 — дисплей пустой
• D=1, E=0 — обычный режим («0» — светлая точка, «1»-тёмная)
• D=0, E=1 — все элементы включены
• D=1, E=1 — режим инверсии («1» — светлая точка, «0»-тёмная)
Set Y 0 0100 0YYY установить адрес строки
Set X 0 1XXX XXXX установить адрес столбца

Набор инструкций для H=1 — расширенный :
Temperature Control 0 0000 01TT установить температурный коэффициент для ТС1 и ТС2 изходя из таблице(Table 2)
Bias System 0 0001 0BBB выбрать систему питания, таблица(Table 4 Programming the required bias system)
Set Vop 0 1VVV VVVV включить напряжение питания дисплея пункт(8.9 Set VOP value)

Значение и аргументы команд с H=1 объяснять долго и сложно, поэтому предлагаю воспользоваться чисто дилетантским приёмом. Ставьте: TT=10, BBB=011, VVVVVVV=100 1000, и всё будет! Тем, кто с таким подходом не согласен — читайте даташиты.
Ну с настройкой управляющих регистров разобрались, теперь перейдем к непосредственно выводу информаций на дисплей.

Каждому столбцу (Xi) данной строки (Yj)соответствует 1 байт памяти (Рис.4), причем верхнему пикселю соответствует младший бит (LSB). Выбрав номер строки и столбца (см. чуть выше), передаём байт в память данных, и он отображается на экране столбиком 8х1. После записи байта автоматически увеличивается на единицу указатель адреса столбца. Поэтому следующий байт отобразится в той-же строке но со сдвигом на 1 пиксель вправо. Если при записи достигнут конец строки y=yi; x=83 то происходит переход на следующую строчку y=yi+1; x=0. Вышесказанное справедливо для случая когда бит адресации V=0. При V=1 заполнение происходит по аналогии, но каждый последующий байт отображается со сдвигом на 8 пикселей вниз.
Примечание. Движение курсора и расположение банков можно настраивать.

С теорией разобрались, перейдем к практике.
Подключения дисплея и МК можно посмотреть на (рис.2)

200?’200px’:»+(this.scrollHeight+5)+’px’);»>
‘Текст программы инициализации LCD дисплея Nokia 3310
‘—————————————————————————————————————————————————-
DC VAR GPIO.2 ‘определяем порты которым подключен дисплей
DTA VAR GPIO.1 ‘ я использовал pic12f629 соответственно GPIO.X
RST VAR GPIO.4
CLK VAR GPIO.0
‘——————————-определяем переменные——————————————————————————————
Chr VAR Byte ‘ Счетчик цикла For для очистки экрана
PosX VAR Byte ‘Позиция курсора по Х координате
PosY VAR Byte ‘Позиция курсора по Y координате
LcdData VAR Byte ‘ Данные для отправки по SPI

PAUSE 100
GOSUB LCD_INIT ‘ Подпрограмма инициализации дисплея
PAUSE 100
GOSUB LCD_Clear ‘ Подпрограмма очистки дисплея

main:
‘основная программа
‘сдесь заполним в следущей статье
end

LOW RST :pause 20 : HIGH RST ‘Сброс и Окончание Сброса LCD
LOW DC ‘Низкий уровень режим Kоманд

LcdData= $20: GOSUB LCD_ByteOut ‘ Команда Function Set ($20 = % 0010 0000) P=0 ,V=1,H=0 — обычный
LcdData= $0c: GOSUB LCD_ByteOut ‘ Команда Display Control ($0c = % 0000 1100) D=1, E=0
LcdData= $21: GOSUB LCD_ByteOut ‘ Команда Function Set ($21 = % 0010 0001) P=0 ,V=1,H=1-расширенный
LcdData= $06: GOSUB LCD_ByteOut ‘ Temperature Control ($06 = 0000 0110) установить температурный коэффициент
LcdData= $13: GOSUB LCD_ByteOut ‘ Bias System ($13 = 0001 0011) выбрать систему питания
LcdData= $c8: GOSUB LCD_ByteOut ‘ Set Vop ($c8 = 1100 1000) включить напряжение питания дисплея
RETURN

‘——————————————подпрограмма для передачи Команд по SPI ——————————————————
‘данную подпрограмму стоит выделить отдельно от всего процесса инициализации, так как к ней будем постоянно ‘обращаться чтобы передать Команды управляющим регистрам
LCD_ByteOut: ‘подпрограмма для передачи Команд по SPI
SHIFTOUT DTA,CLK,1,[LcdData] ‘передаём по SPI байт с командой.
RETURN

Читайте также  Ученые создали новый метод выращивания тонких пленок германия

‘——————————————-Подпрограмма очистки дисплея———————————————————————
LCD_Clear: ‘ Подпрограмма очистки дисплея
PosX=0:PosY=0 ‘Устанавливаем X=0,Y=0 начало координат
GOSUB LCD_GotoXY
HIGH DC ‘Высокий уровень режим Данных
FOR Chr=1 TO 252 ‘Очищаем дисплей заполняя его «0» — светлыми точки
LcdData=0:GOSUB LCD_ByteOut
LcdData=0:GOSUB LCD_ByteOut
NEXT Chr
RETURN

‘——————————-Подпрограмма определения положения курсора————————————————————
‘данную подпрограмму стоит выделить отдельно от всего процесса инициализации, так как к ней будем постоянно ‘обращаться чтобы установить нужную для нас строку или столбец
LCD_GotoXY: ‘определяем место положения курсора
LOW DC ‘Низкий уровень режим команд
LcdData=%01000000 | PosY :GOSUB LCD_ByteOut ‘ 0х40+номер банка (0…5)
LcdData=%10000000 | PosX :GOSUB LCD_ByteOut ‘ 0х80+иксовая координата (0…83)
RETURN

В итоге в процессе инициализации LCD дисплея требуется выполнить один раз подпрограмму LCD_Init: и больше в процессе работы программы нет надобности к ней обращаться.
Подпрограмма LCD_Clear: вам понадобиться если придеть очистить экран от предыдущих записей(скажем большого изображения)
Как я и писал ранее в комментария подпрограммы (LCD_GotoXY: , LCD_ByteOut:) вы будете часто обращаться, что бы скажем сделать экран инверсным, поменять строку,столбец

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

Работа с дисплеем от nokia 3310

Драйвер для LCD от Nokia 3310

Автор: Aheir
Опубликовано 16.02.2010

Сегодня поговорим об экранах от мобильных телефонов, а именно — об экране от Nokia 3310. Казалось бы, тема достаточно избитая, однако, как это часто бывает, при возникновении необходимости найти готовое подходящее решение не удается и приходится изобретать велосипед. Вот и мне пришлось самостоятельно разбираться в вопросе, когда захотелось использовать этот экранчик в своих конструкциях.
Собственно, подопытный (картинка честно стянутая со странички, спасибо авторам (хотя и они тоже ее откуда-то позаимствовали)):

Область отображения 84*48 точек (что позволяет разместить 6 строк текста по 14 символов 5×7 в каждой), питание 2,7..3,3 В, интерфейс SPI с пропускной способностью до 4 Mbit/s. И все бы хорошо, но дело в том что существуют две разновидности этого дисплея. Внешние отличия несущественны, но они есть:

Из отживших свое телефонов извлекаются оригинальные дисплеи с надписью «Nokia» на рамке и как правило металлизированными ламелями на самом экране, в магазинах запчастей для сотовых продаются так называемые «китайские» дисплеи без надписи и без металлизации. И те, и другие прекрасно работают при установке в телефон, однако при попытке заменить оригинальный дисплей на неоригинал в какой-нибудь конструкции на микроконтроллере возникнет ситуация, когда на неоригинальном дисплее изображение окажется смещенным и отчасти нечитаемым (фотка с нашего Форума, спасибо автору):

Как выяснилось, в этих дисплеях стоят разные контроллеры: в оригинальном — PCD8544 (документация на который доступна в Сети), а вот что установлено в китайском — доподлинно неизвестно. Поиск по Интернету и собственные наблюдения позволили сделать ряд заключений относительно контроллера неоригинального дисплея, тем более что как-то он все же работает, а значит более-менее корректно инициализируется и принимает данные.
Ниже представлена таблица команд для PCD8544 с известными на сегодняшний день уточнениями для неоригинального контроллера (выделено красным):

Ничего экзотического в командах контроллера не наблюдается, стандартный набор для графического экрана. Разве что настройки напряжения Vop, позволяющие программно менять контрастность. Оригинальный дисплей на дополнительные команды неоригинала просто не реагирует, так что можно их использовать вне зависимости от контроллера дисплея.
Сдвиг экрана неоригинального контроллера вверх (и цикличность прокрутки экрана) говорит о наличии в его области памяти дополнительных строк изображения, а анализ результата при выводе на экран картинки позволил установить, что «неоригинал» еще и шире на 18 точек. Я предположил, что разрешение экрана составляет 102х64 точки, что впоследствии подтвердилось экспериментально. Следовательно, область экрана 84×48 точек является некоторой частью памяти на 102х64 точек неоригинального контроллера.
Существующие решения по обеспечению совместимости экранов основаны на осуществлении сдвига экрана: либо на полстроки, остатки которой видны на экране (тогда первая строка не отображается и область экрана начинается со второй), либо на «полный оборот» (тогда первая строка отображается на точку ниже, чем должна быть). Однако мои эксперименты показали их пригодность почему-то только для режима отображения текста, при попытке вывести картинку изображение рассыпалось (рискну предположить, что это происходит потому, что при выводе текста каждая строка адресуется перед выводом (т.е. сказали куда вывести — вывели строку, переставили указатель на начало следующей строки — вывели вторую и т.д.), а при выводе картинки данные пишутся в память сплошным потоком, что приводит к рассыпанию из-за большей программной ширины дисплея).
Отсюда получаем два способа вывода нормальной картинки на неоригинальный дисплей: отображать экранный буфер на часть памяти контроллера, программно отслеживая смещение, либо выводить картинку с адресацией каждой строки. Я реализовал первый (как-то оно проще для меня оказалось), хотя у него есть один недостаток: в драйвере требуется однозначно указывать, с каким дисплеем предполагается работа, тогда как вторым способом можно в теории сделать более универсальный драйвер. Видимо, как раз по второму алгоритму и работает телефон, если уж к нему подходят любые экраны. Но лично меня это не расстраивает, потому как сделать две версии прошивки совсем несложно, да и вообще, оригинальных дисплеев у меня всего один (и вряд ли будут еще), а вот неоригинала с десяток имеется. Ладно, поехали уже к практике, теории пока хватит.
Для начала — изготовили простейшую макетную плату. Собственно, процессор Атмега8, пара конденсаторов, разъем программирования и сам экран. Все. Подключение простое: вывод SCK экрана на SCK контроллера; SDIN — на MOSI; D/C, SCE и RES — на любые пины порта, к Vout — конденсатор на землю, VDD — на питание, GND — к земле. Собственно, что-то вроде этого:

Поскольку чтения из индикатора не происходит, параллельно одному индикатору совершенно безболезненно можно подсоединить второй, только вот на Vout повесить отдельный конденсатор:

На плате разведены элементы термодатчика и подсветки индикатора, но ничего из этого не установлено. Питание — 3,3В, я лично запитывал плату непосредственно от USB-программатора.
Индикатор от телефона мне достался без рамки, но к нему можно просто припаяться, а вот с китайским индикатором такой номер не пройдет ввиду отсутствия металлизации, поэтому паяемся к металлическому коннектору, который прижимается к экрану рамкой и пластиком:

Теперь можно и попрограммировать маленько. МК настроен на тактирование от внутреннего генератора на 4МГц, фьюзы:

За основу были взяты исходники с уже упоминавшейся странички и доработаны для совместимости с CodeVision AVR и обеспечения требуемого функционала. Вот перечень функций для работы с LCD:

void LcdSend (unsigned char data, unsigned char cmd); //запись данных в LCD
void LcdUpdate (void); //копирование буфера в RAM дисплея
void LcdClear (void); //очистка дисплея
void LcdInit (void); //настройка SPI и дисплея
void LcdContrast (unsigned char contrast); //установка контраста
void LcdMode (unsigned char mode); //режимы дисплея: 0 — blank, 1 — all on, 2 — normal, 3 — inverse
void LcdPwrMode (void); //инвертирует состояние вкл/выкл дисплея
void LcdImage (flash unsigned char *imageData); //вывод изображения
void LcdPixel (unsigned char x, unsigned char y, unsigned char mode); //управление пикселем с координатами x,y
void LcdLine (int x1, int y1, int x2, int y2, unsigned char mode); //рисование линии
void LcdCircle(char x, char y, char radius, unsigned char mode); //рисуем круг с координатами центра и радиусом
void LcdBar(int x1, int y1, int x2, int y2, unsigned char persent); //рисуем батарейку и заполняем ее на %
void LcdGotoXYFont (unsigned char x, unsigned char y); //установить курсор в положение x,y
void clean_lcd_buf (void); //очистка текстового буфера
void LcdChr (int ch); // печатает символ на текущем месте
void LcdString (unsigned char x, unsigned char y); //печатает строку
void LcdChrBold (int ch); //печатает символ на текущем месте, большой и жирный)
void LcdStringBold (unsigned char x, unsigned char y); //печатает большую и жирную строку
void LcdChrBig (int ch); //печатает символ на текущем месте, большой
void LcdStringBig (unsigned char x, unsigned char y); //печатает большую строку

Функционал понятен из названий и комментариев. Результатом работы этих функций становятся вот такие изображения на дисплее:

Математически реализованы шрифты удвоенной высоты и удвоенного размера, имеются широкие возможности для построения сложных объектов на основе графических примитивов (линии и окружности отрисовываются по алгоритмам Брезенхема). При помощи директив условной компиляции реализована сборка драйвера для того или иного дисплея, выбор осуществляется при помощи строки #define china 1: если дефайн активен — работаем по алгоритмам «китайского» дисплея, иначе — оригинального. По ссылке можно посмотреть видео работы экрана

Изображения на дисплеях идентичны при соответствующей прошивке. Надеюсь, кому-нибудь пригодится, ну а если кто-нибудь не поленится и реализует построчный метод отрисовки — вообще будет здорово)

UPDATE от 23.02.2010.

Предлагаю Вашему вниманию вторую версию драйвера.
По результатам эксплуатации исправлены всячеcкие косячки, глючки и прочие жучки)
Основное нововведение — добавлен программный SPI, так что теперь можно вешать дисплей практически на любые порты микроконтроллера (применительно к AVR не реализовывал за ненадобностью поддержку портов от F и далее). Кроме того, добавлено пару функций, наиболее полезной из которых является

void LcdStringInv (unsigned char x, unsigned char y);

которая позволяет писать строки инверсным шрифтом (на черном фоне) — удобно для выделения каких-либо сообщений, настроек и т.п.
Пока вот как-то так.

Урок 18. Работа с дисплеем от Nokia 3310

Наверное все помнят легендарный мобильник Nokia 3310? Да, было время когда этот телефон был одним из самых популярных, а теперь разве что найти его можно в запылившихся ящиках столах и на разборках. Но и сейчас он может пригодится в качестве донора деталек для самодельных конструкций. Одна из таких интересных деталек это дисплей от Nokia 3310. Приемуществ у него масса, а именно: маленький, тонкий, графический, работает по SPI, жрёт меньше миллиампера и если покупать то стоит копейки. Вот так он примерно выгядит:

Читайте также  Шумы и помехи в тракте звуковой частоты

Теперь поговорим о его характеристиках. Разрешение дисплея состовляет 48х84 пикселя. Основой является контроллер PCD8544 выполненный по технологии COG — Chip On Glass, чип на стекле, по этому дисплей очень хрупкий, это следует учитывать при установки, пайки и креплении. Кстати наши китайские братья научились клепать такие дисплейчики, на оригинальном дисплее металлизированные контакты а на китайском металлические штырьки или ещё хуже — резинка. Если волею судьбы вам попался дисплей без контактов, только дорожки на стекле то в таком случае удобно использовать язычки от разьёма PBS, припаял и надел, удобно (сам так делал). И так пришла пора подключить сие чудо к микроконтроллеру и написать прошивку на баскоме! Для начала соберём простую схемку:

Фьюз-биты микроконтроллера в программе SinaProg:

Если смотреть на лицевую сторону дисплея контактами к вверху то выводы считаются с права на лево от 1 до 8. Питание дисплея не должно превышать 3 вольта иниче он может сгореть, хотя некоторые люди запитывали его от 5 вольт и дисплей нормально работал, но вам так делать не советую. Поскольку в дисплее нет знакогенератора то для работы с ним в BASCOM-AVR нужна специальная библиотека взять её можно тут или в файлах к статье. Вообще можно сказать что главный недостаток экранчика заключается в том что в нём нет знакогенератора, поэтому всё символы приходится хранить во flash памяти микроконтроллера, в общем выбирайте микроконтроллер с немалым обьёмом флеша (минимум Atmega8).

Как собрали схемку можно писать и программу. Для начала установим размер стека и фрейма микроконтроллера для работы с библиотекой, вот так:

Потом настроим порты к которым у нас подключён дисплей:

В данном случае: SCL=PORTC.0, SDIN=PORTC.1, D/C=PORTC.2, SCE=PORTC.3. Поскольку у нас используется программный SPI то дисплей можно вешать абсолютно к любым портам микроконтроллера, если вы подключили дисплей к другим портам микроконтроллера нежели на схеме то просто впишите другие названия портов. После того как настроили порты, инициализируем SPI:

Далее подключим один из файлов библиотеки:

И инициализируем дисплей командой:

Всё, теперь можно работать с дисплеем. Вот команды:

Call D3310clear — Очистка дисплея

Call D3310position(x , y) — установка текстовго курсора в позицию экрана x, y

Call D3310print( «txt») — вывод текста txt после текстового курсора

Call D3310invert — Инвертировать пиксели дисплея (Отключенные пиксели включаются, включенные отключаются — инверстный эффект)

Call D3310uninvert — Отмена инвертирования дисплея

Restore Img — Загрузить в память картинку массив которой называется Img

Call D3310bmpout — Вывести картинку загруженную ранее в память

В программе картинка представляет из себя массив который загружается в дисплей. Чтобы вывести свою картинку нужно: нарисовать её в любом графическом редакторе, разрешение должно быть 48х84 пикселя, далее картинку нужно сохранить в чёрно-белом BMP формате. Позже открыть в её специальной программой FastLCD (при открытии в окошке установите флажок New Size), потом нажмите на кнопку BAS, выберите флажок HD, SEG, Nokia3310 и сохраните BAS файл.

Далее откроем этот файл и увидим массив картинки, перенесём этот массив в конец своей программы предварительно добавив перед каждой строчкой Data. Также дайте название массиву в программе, название пишется в начале массива, в конце названия ставится двоеточие. Для демонстрации я в Paint нарисовал такую картинку:

Перевёл её в массив, добавил Data и написал название. Вот что получилось:

Для демонстрации работы дисплея я написал следующую программу:

Вот так работает она, выводит на дисплей текст:

Вот видео как это работает:

Вот собственно и всё! Если возникнут вопросы задавайте их в комментариях, всегда рад помочь, 73!

Технические характеристики LCD Nokia3310:

— Напряжение питания 2,7 – 3,3 В
— Встроенный контроллер Philips PCD8544
— Интерфейс SPI
— Размер дисплея 38х35 мм
— Размер активной области 30х22 мм
— Разрешение 84х48 пикселей
— Диапазон рабочих температур –27…+70 0С

Схема подключения к микроконтроллеру

Распиновка LCD Nokia3310

Программная часть

Собственно для работы с дисплеем достаточно трех функций

void LCDInit(void)

void LCDClear(void)
Полностью очищает дисплей.

void LCDStr(unsigned char x, unsigned char row, unsigned char *dataPtr )

Пример:
LCDStr(0, 2, “lcd Nokia3310” );

Related items

  • Библиотека для опроса кнопок
  • Работа с SD картой. Воспроизведение wav файла. Ч3
  • Работа с SD картой. Подключение к микроконтроллеру. Ч1
  • AVR315: Использование TWI модуля в качестве ведущего I2C устройства
  • ATtiny10. Самый маленький микроконтроллер AVR

Comments

Итого, как я понимаю, в любом случае выводить придётся «посимвольно» — по 8 бит, причем начиная с ординаты, кратной восьми. Так?

в самой 3310 как я вижу весь текст имеет высоту 8 пикселей, но выводится он с произвольных точек (ордината не обязательно кратна восьми). Интересно, как сделано? надо даташит PCF8814 покурить, может там есть чего.

Я так понимаю что библиотека с буфером это как будто двойная буферизация в видеокарте — рисуем в нашем буфере, потом делаем апдейт аля SwapBuffers(). Так? А данные разые быстро передадутся? (у меня дисплей от 1100, там не SPI а чё-то другое, но принцип вроде похож)

и еще вопрос — сейчас Data Write именно _присваивает_ текущему байту заданное значение. А нет ли способов вместо присваивания делать, скажем, операции «И», «ИЛИ»? типа операции |= и &=

Всё же смотрю на мобилу, катаюсь по менюшкам и не могу понять — как же происходит вывод текста на экран в точку с координатами, некратными восьми.

А, я рановато обрадовался. Режимы вывода «И», «ИЛИ», «искл.ИЛИ» только для этой библиотеки. А я думал это вшито в драйвер дисплея.

Короче говоря, если возиться с дисплеем на низком уровне (ну или писать библиотеку самому с нуля) — то рисовать на нём можно ТОЛЬКО столбиками по 8 бит, затирая то что уже нарисовано под этим столбиком. Других способов рисования драйвер дисплея не предусматривает . Я правильно понял?

Решил тоже поиграться с таким дисплеем. Но видимо мне какой-то косячный попался.

Во-первых, разрешение у него 37х84 😮
Во-вторых, столбики не по восемь точек идут, а вот так: 1 столбик на 4 точки, 5 столбов по 6 точек и 1 по 3. И когда я посылаю первую строку байтов, точки выводятся только под действием последних 4-х бит.

Это чё за хрень такая? Так и должно быть или я чё-то не так настроил? 😕

Не, кажись общитался 😳 . Высота всё-таки 48 пикселей. Проблема вот в чём. Посылаю допустим в память 0b00001111 84 раза, при этом с начала экрана выводится строка шириной 1 пикс (а должно по идее 4 пикселя и четыре пробела). Следующие строки идут нормально (по восемь пикселей). Ну и в последней строке остаётся только 3 пикселя. Короче говоря, получился сдвиг на 3 пикселя вверх, о причинах которого мне и хотелось бы узнать.

>Дисплей точно от Nokia3310?
Скорее всего. Брал тут http://shop.siriust.ru/product_info.php/products_id/382

Большое спасибо за ссылку — пригодится.

Но тема все таки все еще актуальна (по ссылке проект с экраном от Nokia 1100, он даже выглядит немного иначе).

а как выводить дополнительные фонты?

вопрос снимается, я плохо код посмотрел 🙂

PashGan Подскажи, как изменить контраст?
Пишу даже
LCDInit();
LCDContrast(0x0 0);
LCDClear();
LCDStr(0, 0, «Курсова робота»);

но никаких изменений,?

Пожалуйста, объясните, где первая нога? Во всём интернете ни одной картинки и ни одного слова про это!

Вот дисплей: смотрю на него. На экран. Лично у меня он сзади чем-то закрыт: непрозрачный. Если б я мог насквозь видеть, то б эти 8 ног были сверху и рядом с правой (если продолжать смотреть на экран, а не на ноги) был б такой пластмассовый выступ.

я подключал как то дисплей от нокиа 1100 (на сириусте всего 50 руб стоит) — но у меня возникла проблема с контактами дисплея которые наклеены на стекло — при попытке подпаятся к ним — дисплей просто потом не работал (вернее сначала работал, потом работал если прижать контакты, а потом уже нифига не работал (ну может изредка).. извел я 3 или 4 дисплея и забросил эту идею..

может быть ктото придумал что нить дельное с подключением таких дисплеев ? чтобы и не паяться и контакт был надежный?

плохо себе эту процедуру представляю.. расстояние между выводами маленькое..- капли клея обязательно где нить расползутся и замкнут 🙁

никто никаких колодок не делал (или может покупал где нить) для подобных дисплеев?

а какая разница сколько бит в строке ?
сами процедуры не сильно отличаются..
Code:
void LCD_pixel (unsigned char x, unsigned char y, unsigned char mode) < // вывод пиксела

if ((x >3;
unsigned char bt=1
точки я думаю понятно как рисовать..
это для экрана 128 на 64 точки, поставьте свои размеры и вперед..
правда конечно буфер экрана нужен ! без него никак при графике
а для линий смотрите в интернете алгоритм Брезенхейма — он есть для линий и для дуг..
в принципе для линий я и на СИ и на Асме писал — действительно не сложный и быстрый
вот на си
Code:
void LCD_line(unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2, char mode) < // процедура рисования линии
signed char dx, dy, sx, sy;
unsigned char x, y, mdx, mdy, l;

if (mdx>=mdy) <
l=mdx;
while (l>0) <
if (dy>0) < y=y1+mdy*(x-x1)/mdx; >
else < y=y1-mdy*(x-x1)/mdx; >
LCD_pixel(x,y,mode);
x=x+sx;
l—;
>
> else <
l=mdy;
while (l>0) <
if (dy>0) < x=x1+((mdx*(y-y1))/mdy); >
else < x=x1+((mdx*(y1-y))/mdy); >
LCD_pixel(x,y,mode);
y=y+sy;
l—;
>
>
>

текст тоже можно написать процедуру чтобы выводить с точностью до пиксела.. причем символы не рисовать по точкам, а именно выводить верхнююнижнюю часть.
К сожалению код сюда уже не уместился.

Читайте также  Интегральная микросхема inf8577cn

Ну и вот вывод текста с точностью до пиксела
Code:
void LCD_char(unsigned char ch, unsigned char mode) < // Вывод символа
const unsigned char *fontpointer;

if (ch 0) LCD_pixel(lcd_X, lcd_Y-1, 1); // если печать в режиме инверсии — сверху отчертим линию
>

lcd_buff[lcd_YC*128+lcd_X]=lcd_buff[lcd_YC*128+lcd_X] | (temp >(lcd_YP+1)); // печать нижней части символа

О! За Брезенхейма отдельный респект!
А по поводу 84 бит, это фишка этого дисплея.
Я хотел использовать без обработки формат XBM(который фактически является массивом на Си и его можно просто инклудить), еще его особенность что если длина строки не кратна 8ми то бит добивается нулями.
А тут у экрана 84 бита на строку, а в XBM 88 бит на строку и чтобы вывести все приходится при новой строке явно указывать ее номер. Еще чудес добавляет то, что вывод 1ого байта это вывод колонки из 8ми пикселей. Я с компа привык к нормальной построчной адресации. Тут такого нет. Вот и хочется написать обертку чтобы было. И сделать свою демку с графикой. А если упрусь в возможности контроллера, то возьму покруче, но это уже MSP430-ый офтоп.
Кстати вывод я только что переделал на вертикальную адресацию и там стало все хорошо ибо теперь по длине картинки 48бит.

ПС. Знаю что немного путано(

Pashgan приветствую. Решил сделать термометр с выводом комнатной и уличной температуры с использованием данного дисплея. Купил три дисплея (китайских)-зап орол два из них 😥 Кое как подключился к одному. Заметил что в последних 3-4 строках какой то мусор.
вот мой код Code: #include
#include «driver_nokia3310.h»

void main( void )
<
unsigned char* counterProg = 0;
LCDInit();
LCDClear();

while(1) <
counterProg++;
LCDStr(0, 3,counterProg);
delay_ms(100);
>
> Вот что получаю

Вопрос: откуда берется надпись «Pashgan»?
Почему вместо counterProg получаю какую то муть и как увеличить контрастность дисплея?
И можно ли убрать мусор из последних строк?

hawk то что у тебя мусор в последней строке это потому что дисплей китайский, а по поводу твоего кода объяснить не могу (потому что сам в си не силен) но подсказать как решить эту проблему могу.
Я поступил следующим образом
Функция sprintf стандартной библиотеки stdio.h
sprintf – функция для вывода форматированных данных в строку.

Code:
#include
#include
#include «driver_nokia3310.h» // использую lcd от siemens c55
unsigned char array[6];
unsigned char temp;

void main( void )
<
LCDInit();
LCDClear();
LCDContrast(75);
sprintf(array,»t %u»,temp);

Ну а по поводу мусора я решил проблему повысив разрешение с 84*48 до 101*64 так кат у меня LCD от Siemens C55. В твоем случаи попробуй поставить чуть больше разширение методом тыка.

Подключение дисплея Nokia 3310 к USB интерфейсу. Часть 2. Программное обеспечение

ATmega8

В первой части мы познакомились со схемотехническим решением на микроконтроллере ATmega8 для реализации USB интерфейса и управления дисплеем от мобильного телефона Nokia 3310. Сейчас мы рассмотрим основные моменты в программном обеспечении микроконтроллера, основные функции и их параметры, разберем протокол работы с дисплеем. Разберем основные моменты программного обеспечения Host-устройства, также познакомимся с основными функциями и их работой, рассмотрим вопрос организации пользовательских шрифтов.

Пояснение реализации USB интерфейса для микроконтроллера AVR

Если вы никогда прежде не работали с библиотекой V-USB , то, изучая исходный код, вы запутаетесь, поэтому исходный текст снабжен подробными комментариями. Пояснения требует функция usbFunctionSetup (файл AtMega8_LCD.c ) – это функция где происходит обработка всех данных посылаемых микроконтроллеру по интерфейсу USB. Если вы заметили, в функции присутствуют условные операторы IF, они проверяют наличие специфического числа в переменной rq->bRequest. Эти числа, по сути, являются командами.

В программе Host-устройства (компьютер) мы имеем функцию SendData(int request, int data), значение, которое присваивается переменной request будет передано микроконтроллеру и сохранено в переменной rq->bRequest. Это и есть команда, которая принимается микроконтроллером и соответственно которой выполняются определенные задачи в функции usbFunctionSetup.

В исходном коде имеется 6 параметров (6 кодов запроса или 6 команд), но пользователь может добавить седьмой код запроса (команду), включив следующий текст в функцию usbFunctionSetup:

Теперь, если пользователь вызовет функцию SendData с параметрами:

пользовательский код после выполнения сравнения будет выполнен.

Второй параметр функции SendData – это фактические данные, передаваемые микроконтроллеру. Это число будет сохранено в структуре rq->wValue, имеющей тип Word (2 байта).

Примечание. Пользовательские функции, занимающие много времени, необходимо помещать за пределами функции usbFunctionSetup, т.е. необходимо чтобы они выполнялись в основном цикле программы. Если их оставить в функции usbFunctionSetup и они заберут много времени для выполнения (50 мс), то USB соединение с компьютером будет потеряно.

Пояснение работы дисплея Nokia 3310

Дисплей на базе контроллера PCD8544 работает довольно странным образом, поэтому мы остановимся на этом моменте.

Разрешение дисплея 84×48 точки и адресация по оси Х осуществляется от 0 до 83, по оси Y – от 0 до 5, однако по оси Y это 6 банков точек. Каждый банк пикселей имеет 8 точек в высоту и 84 точки в ширину. Таким образом, мы можем представить восемь точек по оси Y как 1 байт. Как вы знаете 1 байт состоит 8 бит, и если бит равен 1, это соответствует включенной точке на дисплее, например, если все восемь бит равны 1, вы получите 8 черных точек по оси Y. Иллюстрация ниже поясняет этот процесс.

Каждый раз после отображения пикселев на дисплее по оси Y, адрес (позиция) по оси X автоматически инкрементируется, что очень удобно. Если вы находитесь на последнем байте банка пикселей, то позиция смещается на первый байт следующего банка, и если вы находитесь внизу дисплея, то отображение следующих пикселей начнется с верхней позиции дисплея.

Помните, что первый бит соответствует верхнему пикселю, а восьмой бит – нижнему пикселю в банке пикселей по оси Y.

Для записи пикселей в дисплей используется функция LCD_writeData(data) в программном обеспечении микроконтроллера. Функция отображает 8 пикселей в текущей позиции XY, перезаписывая существующие данные в этой позиции.

Также пользователь может посылать команды управления дисплеем при помощи функции LCD_writeCommand(data). Есть не много команд, которые могут быть переданы дисплею и которые представляют интерес после его инициализации. Вот некоторые из них, которые будут использоваться Вами чаще всего:

  • 0b00001000 – отображение пустого экрана (команда не очищает экран)
  • 0b00001100 – нормальный режим (отключение режима инверсии, режима пустого экрана, режима включенния всех пикселей)
  • 0b00001001 – все пиксели дисплея включены (команда не очищает экран)
  • 0b00001101 – инверсный режим

Для перемещения в позицию XY используется функция LCD_gotoXY(X, Y), где координаты указываются в формате:

  • 0b01000YYY – перемещение в позицию 0bYYY по оси Y (заменить Y нужным бинарным кодом позиции)
  • 0b1XXXXXXX – перемещение в позицию 0bXXXXXXX по оси X (заменить X нужным бинарным кодом позиции)

Настройка программного обеспечение для компьютера

Для начала вам необходимо установить библиотеку libusb (находится в архиве с исходными файлами). Это драйвер, который мы будем использовать в программе, и без него осуществить коммуникацию по USB интерфейсу не возможно.

Следующий шаг – установка драйвера нашего USB устройства. В архиве с файлами исходного кода вы найдете драйверы в директории «Drivers», и для установки его в систему необходимо правой кнопкой мыши кликнуть на файле LCD_Display.ini и выбрать пункт меню «Установить». Таким образов вы установите драйвер для устройства с именем «LCD_Display».

Для дальнейшей работы Вам потребуется среда разработки Visual Studio.

Подключите Ваше правильно собранное устройство к USB интерфейсу. Откройте проект LCD_Screen в среде разработки, скомпилируйте его и запустите скомпилированную программу. Если все сделано правильно, то после запуска программы на дисплее будет отображаться текущее время. Если программа закрывается сразу после запуска, то это означает, что не найдено USB устройство. Ппопробуйте повторить подключение устройства к USB или перезагрузить компьютер.

Если все удачно работает, то теперь мы можем вводить коррективы в программе. Во-первых, пользователь может изменить параметры инициализации USB интерфейса. Для этого необходимо открыть файл проекта LCD_Screen и в функции main найти строку usb_init(). Теперь можете установить свои параметры инициализации USB. Исходный код программы для компьютера, как вы заметили, также имеет комментарии.

Запись данных и команд в дисплей

Весь процесс коммуникации с дисплеем реализован в функции SendData( int request, int data), данная функция определена в файле USBFunctions.cpp . Эта функция есть укороченный вариант функции известной под именем usb_control_msg, т.к. последняя является слишком сложной и длинной.

Итак, для записи пикселей нам необходимо послать 1 байт с использованием функции SendData( SEND_DATA, data), где «data» и есть значение этого байта. В данном случае 8 пикселей будут прорисованы на дисплее в текущей позиции XY.

Для передачи команды используется функция SendData( SEND_COMMAND, data ), в данном случае «data» замещается командой дисплея (см. техническое описание контроллера PCD8544, стр. 14).

Для очистки дисплея используется функция SendData( SEND_CLEAR, 0). В этом случае микроконтроллер AVR производит запись байта со значением 0 во все пиксели. Эту операцию производит полностью микроконтроллер, т.к. он это сделает намного быстрее, нежели программа Host-устройства.

Для установки позиции XY используется функция SendData( SEND_XY, ( y Atmega8_LCD.h .

Самый простой путь подготовить свои символы – это переписать уже существующие данные в массиве font. Необходимо удалить все, что находится между фигурными скобками в этом массиве:

Далее подготавливаете свой массив данных для символов, но помните что для каждого символа необходимо 5 байт. Например, для символ «пробел», вы наверное уже представляете, какие данные будут в массиве:

Если по каким-либо причинам не хотите использовать все пять байтов, можно использовать специальный код 0b10000000 (вместо пятого байта). Таким образом можно получить расстояние в 1 пиксель между символами автоматически (см. иллюстрацию ниже).

Пример описания в массиве данных заглавного символа «А»:

Исходный код программы для компьютера, библиотека libusb , драйвер для дисплея — скачать

Перевод: Vadim по заказу РадиоЛоцман