HRP-N3 - серия источников питания с максимальной пиковой мощностью в 350% от MEAN WELL

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

ATmega8

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

Выбираем схему BMS для заряда литий-железофосфатных (LiFePO4) аккумуляторов

Пояснение реализации 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:

// если код запроса равен 7 
if(rq->bRequest == 7){ // Комманда 7 - SEND_MYCOMMAND
// пользовательский код
}

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

SendData(7,0),

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

Второй параметр функции 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. Иллюстрация ниже поясняет этот процесс.

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

Каждый раз после отображения пикселев на дисплее по оси 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 << 8 ) + x ). Здесь необходимо заменить «y» на значение от 0 до 5, «x» – на значение от 0 до 83. Функция посылает 2 байта микроконтроллеру, в этом причина сдвига значения «y» на 8 (значение «y» является вторым байтом).

Для передачи ASCII символа в дисплей используется функция SendData( SEND_CHAR, data). Помните, что значение должно быть заключено в одинарные кавычки, например SendData( SEND_CHAR, 'A' ).

Подготовка собственных шрифтов

Создать свои символы для отображения на дисплее очень просто. Каждый символ займет до 5 байт, т.е. для отображения многих символов достаточно 8×5 пикселей. Для ускорения доступа к символам их коды расположены в памяти микроконтроллера AVR, массив с данными имеет имя "font" и находится в файле Atmega8_LCD.h.

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

static const unsigned char font[] = {
//удалить все что находится здесь
}

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

0b00000000, // *пробел*
0b00000000,
0b00000000,
0b00000000,
0b00000000,

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

дисплей Nokia 3310

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

static const unsigned char font[] = {
....
0b01111000, // Символ «A»
0b00100100,
0b00100100,
0b01111000,
0b10000000, // Пропустить последний пиксель
....
}

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

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

На английском языке: Connecting Nokia 3310 LCD to USB using AVR. Part 2. Software

69 предложений от 35 поставщиков
Переходник для Atmega 8, 48, 168 в корпусе QFN на DIP28. Соединения сделаны так, что микросхема на переходнике аналогична по выводам...
AliExpress
Весь мир
AT24C02BN 93C46 24C16A AT49LV040-12TC ATMEGA8L-8PU AT24C02 24C02
15 ₽
ЗУМ-СМД
Россия
ATmega8A-AU
Atmel
29 ₽
СЭлКом
Россия и страны СНГ
ATmega8A-AU
Microchip
от 326 ₽
ATMEGA8A-MN
Atmel
по запросу
Электронные компоненты. Бесплатная доставка по России
Для комментирования материалов с сайта и получения полного доступа к нашему форуму Вам необходимо зарегистрироваться.
Имя