Реклама ⓘ
Главная » Микроконтроллеры
Призовой фонд
на апрель 2024 г.
1. 100 руб.
От пользователей

Реклама ⓘ

Игровая консоль на STM32 и LCD Nokia 5110

Введение

Наверняка у многих из нас в детстве были карманные игровые консоли. У тех, кто застал советское время, была игровая консоль "Электроника". Я не застал то время, поэтому у меня был "Тетрис" с черно-белым дисплеем, содержавший в себе несколько игр, такие как "танчики", "змейка", "тетрис" и т.д. Позднее стали появляться кнопочные мобильные телефоны Nokia с играми "Змейка", "Судоку" и т.п. Дисплеи от Nokia 5110 пользуются большой популярностью среди радиолюбителей, они более компактные и функциональные, нежели символьные на контроллере HD44780. Как только у меня оказался в руках LCD Nokia 5110, было решено создать на его основе игровую консоль. В качестве примера послужила игра "Пинг-понг".

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

Дисплей построен на контроллере PCD8544 и имеет разрешение 84 х 48 пикселей. Команды и данные передаются в память дисплея с помощью интерфейса SPI. В зависимости от того, какой будет выставлен сигнал на входе D/C, приходящие байты по SPI будут восприниматься либо как данные, либо как команды. Так если будет логический 0, то все байты будут читаться как команды, в ином случае как данные. Сначала в режиме команд происходит инициализация дисплея, настраиваются температурный коэффициент, режим работы, контрастность, начальный адрес памяти дисплея. Все эти команды отлично описаны в даташите на контроллер PCD8544. После этого происходит переключение в режим данных, и память дисплея заполняется данными. О том, как заполняется дисплей приходящими данными, рассмотрим подробнее.

Вся рабочая область дисплея разделена на шесть строк. Каждая строка состоит из 84 столбцов размером 8х1 пикселей. 

Командой отправляется начальный адрес памяти, затем по адресу записывается наш байт данных. Например, выставлен адрес х=0, у=0. Тогда первый пришедший байт данных запишется в нулевой столбец нулевой строки, то есть в самую верхнюю левую ячейку. С каждым новым байтом данных адрес памяти дисплея увеличивается на единицу, и байты записываются в следующие столбцы. Например, если пришел байт 11111111, то весь столбец 8х1 будет закрашен, а если 00000000, то ни один пиксель не будет закрашен. Сверху столбца идут младшие разряды байта, а снизу - старшие. Итак, первые пришедшие 84 байта заполнят всю нулевую строку, следующие 84 байта - первую строку, и так до заполнения всех строк. Описанная выше адресация называется вертикальной. 

Выбор микроконтроллера и схема устройства

"Сердцем" игровой консоли стала отладочная плата на микроконтроллере STM32F103C8T6. У микроконтроллера имеется 64 Кб программной памяти, что может спокойно хватить на 3-4 игры в одном устройстве. Питание устройства происходит от "Кроны" через стабилизатор напряжения на 5 В. Пять вольт подается на отладочную плату, а на самой плате имеется еще стабилизатор на 3.3 вольта, от которого и питается микроконтроллер. Напряжение 3.3 вольта с отладочной платы подается для питания на сам дисплей, что позволяет не беспокоиться о согласовании логических уровней МК и дисплея. Для озвучки консоли к пину А7 подключен пьезоэлектрический динамик.

Для разработки ПО использовалась среда "CooCox CoIDE". Весь проект состоит из следующих библиотек и заголовочных файлов:

- f10x-pcd8544.c и f10x-pcd8544.h - библиотека для работы с дисплеем;

- font6x8.h - здесь хранятся английские, русские символы и графические объекты для игры;

- Game_board.c и Game_board.h - здесь у нас код игры "Пинг-Понг" на одного и двух игроков;

- Sound.h - тут хранятся массивы с мелодиями для игры. 

Сейчас мы рассмотрим работу с этими библиотеками поподробнее.

Библиотека для работы с графикой

Библиотека была взята отсюда - http://vg.ucoz.ru/forum/9-100-1 . Данная библиотека позволяет выводить текст на латинице и кириллице, строить прямые, прямоугольники, выводить строки и целочисленные переменные типа int. В файле f10x-pcd8555.h в директивах #define можно настроить порт и пины микроконтроллера, к которым подключается дисплей. Как пользоваться функциями, довольно понятно, достаточно посмотреть на прототипы функций в f10x-pcd8544.h.  Единственное, что может быть непонятным сразу, это аргумент mode во многих функциях, если мы задаем 0, то выводится черный текст на белом фоне, если 1 задать, то соответственно наоборот. Приведу небольшой пример работы с функциями:
int main(void)
 {
  lcd8544_init(); // инициализация дисплея
  lcd8544_putstr(0,0,"ПРИВЕТ",0);
  lcd8544_putstr(0,10,"КАК ДЕЛА?",0);
  lcd8544_refresh(); // вывод массива на дисплей
 while(1)
 {
 }
 }

К данной библиотеке была добавлена одна очень необходимая для созданий игр функция void lcd8544_putobject(unsigned char px,unsigned char py,unsigned char width,unsigned char height,unsigned char object[]). Функция позволяет выводить на дисплей изображения любых размеров (естественно не больше 84х48) по заданным координатам. Таким образом в файле font6x8.h мы можем создать массив изображения любого графического объекта и выводить его уже на дисплей. Например, можно нарисовать танк, человечка, всё что угодно. Аргумент px - координата по х, py - по y, следующие два аргумента это ширина и высота изображения, последний аргумент функции - строка с названием массива изображения. Создав такой графический объект, мы можем манипулировать с его координатами, как нам необходимо: заставлять двигаться по экрану, взаимодействовать с другими графическими объектами.

Создать графический объект в font6x8.h можно вручную, например, такой:

const unsigned char NashMassiv[]= { // 8x8
  0xFF, 0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF,
};

Так мы создали квадрат 8х8. У нас в массиве 8 элементов, каждый элемент представляет из себя байт 11111111. Как мы помним, в дисплее у нас происходит вертикальная адресация, значит эти восемь байт из массива и создадут изображения квадрата.

Для создания массивов удобно пользоваться программой "LCD Vision". Запускаем программу, выбираем File - New Font, задаем, например, размер 8х8.

Это режим создания символов любых размеров, этим режимом удобно пользоваться, когда рисуем по пикселям. Нарисуем что-либо в символе "пробел", код этого символа 0х20.

Выбираем File - Export, а после File - Save Export. Файл сохраняем в формате .с . Открываем созданный файл с помощью блокнота, в нем содержатся массивы на все нарисованные символы. Поскольку нарисован только символ "пробел", то и будет массив только с этим символом, а в остальных массивах одни нули.

Массивы для вертикальной адресации находятся в середине файла. Копируем полученный массив в font6x8.h , и дело почти готово. Осталось только зайти в f10x-pcd8844.c и в теле функции lcd8544_putobject дописать строку рядом с подобными строчками:

	if((strcmp(object,"NashMassiv"))==0) fontpointer=NashMassiv;

После этого уже будет возможно использовать наш новый графический объект. Пример использования нового массива:

int main (void)
{
 lcd8544_init();
 lcd8544_putobject(10,10,8,8,"NashMassiv");
 lcd8544_refresh();
 while(1)
 {
 }
}

Создание игры "Пинг-Понг"

Используя функцию lcd8544_putobject можно создавать уже любые игры, остается только создать необходимые графические объекты и задать им перемещение по определенному алгоритму. Так была создана игра "Пинг-Понг". Сейчас подробнее о функционале игры.

При запуске игры появляется главное меню с выбором режимов на одного и двух игроков, при этом играет фоновая мелодия. Выбор пунктов меню осуществляется кнопками Right Platform1, Left Platform1, Button Select. Также находясь в главном меню, мы можем отключить или выключить музыку и звуки в игре, нажав Button_Cancel. Выбрав пункт "1 ИГРОК" , мы окажемся в меню выбора сложности. В зависимости от уровня сложности, будет различной начальная скорость мяча. После выбора уровня сложности начинается игра против бота, до семи забитых голов. После гола нажмите Button Select, игра продолжится дальше. Игру можно ставить на паузу, нажимая Button Select, а также нажатием Button Cancel выходить из нее. При выборе пункта "2 ИГРОКА" возможно играть уже с другом, вторая платформа уже управляется кнопками Right Platform2 и Left Platform2. 

Код игры обоих режимов игры написан в Game_board.c в функциях Single_Player() и Two_Player(). Функция Game_Init() выводит на дисплей счет и разметочную линию. Подробнее об алгоритме игры можете почитать в комментариях в исходном коде. В файле main.с реализовано двухуровневое меню, а также функции воспроизведения мелодии и звука. Сама мелодия хранится в виде массива в Sound.h.

Устройство собрано в распределительной коробке для электромонтажа, форма коробки круглая и довольно удобная.

 

Прошивка загружается в микроконтроллер с помощью программатора ST-Link V2. Для прошивки можно использовать саму среду разработки "CooCox" либо отдельную небольшую утилиту "STM32 ST-LINK Utility".  Файл прошивки имеет формат .bin.

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

Список радиоэлементов

Обозначение Тип Номинал Количество ПримечаниеМагазинМой блокнот
МК STM32
STM32F103C8
1 Поиск в магазине ОтронВ блокнот
LCD-дисплейNokia 51101 Поиск в магазине ОтронВ блокнот
VR Линейный регулятор
L78L05
1 Поиск в магазине ОтронВ блокнот
EP1 Пьезоэлектрический динамик1 Поиск в магазине ОтронВ блокнот
Кнопка без фиксации6 Поиск в магазине ОтронВ блокнот
C1,2 Конденсатор0,1 мкФ2 Поиск в магазине ОтронВ блокнот
R1 Резистор
300 Ом
1 Поиск в магазине ОтронВ блокнот
Добавить все

Скачать список элементов (PDF)

Прикрепленные файлы:

Теги:

Опубликована: 0 0
Я собрал 1 2
x

Оценить статью

  • Техническая грамотность
  • Актуальность материала
  • Изложение материала
  • Полезность устройства
  • Повторяемость устройства
  • Орфография
0

Средний балл статьи: 5 Проголосовало: 2 чел.

Комментарии (9) | Я собрал (0) | Подписаться

0
Публикатор #
На форуме автоматически создана тема для обсуждения статьи.
Ответить
0
andro #
А в среде Arduino IDE нельзя скомпилировать эту программу?
Ответить
0

[Автор]
RioDeJaneiro #
Да, замечал мельком статьи по работе в Arduino IDE с STM32, но сам не проверял. Возможно выдаст ошибки в инициализации портов ввода/вывода, главное правильно инициализировать порты.
Отредактирован 19.09.2018 15:34
Ответить
0

[Автор]
RioDeJaneiro #
Забыл ещё про инициализацию таймера сказать.
Ответить
0
Pauk #
Как на счёт другого экрана, возможна замена чем нибудь?
Ответить
+1
sser #
Вроде работает .
Только нужно R1 на 5 Вольт ,а не на корпус.
Отредактирован 09.10.2021 22:16
Прикрепленный файл: IMG_20211009_220402.jpg
Ответить
0
Reedqi #
У тебя экран другого формата просто.
Ответить
0
wertanes #
Подскажите пожалуйста, как загрузить прошивку?
Ответить
0
sser #
"STM32 ST-LINK Utility". Файл прошивки имеет формат .bin.
Ответить
Добавить комментарий
Имя:
E-mail:
не публикуется
Текст:
Защита от спама:
В чем измеряется электрическая мощность?
Файлы:
 
Для выбора нескольких файлов использйте CTRL

AVR-программатор USB ASP
AVR-программатор USB ASP
Радиореле 220В Discovery V8
вверх