Управление MAX7219 при помощи STM32. Часть вторая - практическое применение
Добрый день.
Совсем недавно мы разобрали какие именно данные, и как необходимо отправлять в MAX7219 для управления подключенными к ней восемью семисегментными индикаторами.
Но теория без практики - бессмысленна.
Да и задание, которое мы планировали на предыдущее занятие не выполнено.
По этому запасаемся чаем, печеньками, и возвращаемся к незаконченному проекту.
На всякий случай сделаем коммит, пока имеем рабочий код.
Теперь давайте собирать наши наброски во что нибудь, что можно будет использовать удобно.
Создадим файлы DS_MAX7219.h и DS_MAX7219.c.
Си файл, пропишем сразу в список файлов для сборки при помощи Cmake.
Как обычно - в заголовочный файл - пишем стандартную обёртку, и добавляем header для работы с HAL.
Ранее мы использовали структуры - не будем себе изменять. Создаём структуру.
Далее - определяемся что мы хотим там хранить. Очевидно, в первую очередь что там нам надо сохранить указатель на экземпляр SPI. Так же создадим массив, для хранения того, что именно должно быть выведено на дисплей. Ещё хотелось бы управлять всеми точками, что нам доступны. Сделаем и для этого переменную. Для 8 точек хватит и 8 бит, значит восьмибитной переменной более чем достаточно.
На первый взгляд - этого достаточно.
Прописываем прототипы функций.
Инициализация.
Управление точками.
Обновление всего дисплея.
Пока хватит. Если будет чего то нехватать - добавим позднее.
Приступаем к реализации. Инициализация.
В конце предыдущего занятия, я говорил о том, что из-за того, что дисплей рассчитан на пятивольтовую логику, перед первой отправкой данных необходимо сделать задержку.
 
Режим декодирования будем хранить в структуре. Интенсивность - тоже сохраним. ScanLimit - туда же.
Инициализируем новые переменные.
Надо как то дать из вне доступ к этим переменным. Значит нужна пользовательская функция их задающая. Делаем ещё один прототип.
Сразу напишем её реализацию.
После установки значения переменным - надо это как то отправить в микросхему. Ещё один прототип, и сразу идём реализовывать.
Так, проблема, мы совсем забыли про пин ChipSelect. Добавляем его в структуру, и в функцию инициализации.
Возвращаемся к нашей функции отправки.
Создадим временный массив, в который сложим все необходимые данные для отправки.
И в цикле отправим данные через SPI.
Получившуюся функцию можно добавить в процедуру инициализации.
 
Далее - функция вывода на дисплей всех символов из массива. Так как у нас массив char-ов, то необходимо сделать преобразование из char в int.
воспользуемся swich - case, и вынесем это в отдельную функцию.
 
Так же нам понадобится функция, которая будет на вход получать число, которое необходимо отобразить на дисплее, и переводить его в массив символов, который уже непосредственно выводится на дисплей.
Создаём прототип, и сразу реализуем её.
 
Алгоритм довольно простой, основанный на целочисленном делении, но как его описать - я не придумал. По этому если кому то интересно - смотрите итоговый код. Его можно оптимизировать, при чем сильно, но сейчас важна простата понимания.
 
Ну и наконец то непосредственно сама функция обновления дисплея.
 
И последний шаг - в main.c осталось описать алгоритм взаимодействия с нашим дисплеем.
Инициализация дисплея, и для теста в цикле будем выводить счетчик этого цикла.
Для этого используем функции принт и update.
Наконец индикатор ожил, но показывает что то бессмысленое. Идём искать ошибки.
 
Самое важное исправление - отказ от функции конвертации. у нас же и так массив, содержащий цифры. их не надо в цифры конвертировать.
 
Отлично, дисплей начал показывать что-то осмысленное, значит мы на верном пути, продолжаем.
 
Убираем всё лишнее, и создаём новую переменную, которая будет хранить число для отображения на индикаторе.
 
Далее - осталось описать работу с кнопками.
 
Функции работы с ними - возьмем из предыдущего нашего проекта.
Подключим заголовочный файл, создадим 2 экземпляра кнопок, и инициализируем их. В бесконечном цикле - сделаем циклический опрос кнопок.
 
Если какая либо из кнопок нажата - меняем значение нашей переменой, и выводим его на дисплей.
Делаем то же самое для длительного нажатия.
Но для определения очень длинного нажатия у нас нет подходящей функции, по этому идём дописывать функционал работы с кнопками.
 
Так же поправим, что бы у нас длительные нажатия срабатывали раз в пол секунды.
 
Проверяем что получилось.
Красивая билибирда... нельзя забывать инициализировать переменные.
Отлично, работает почти как и было поставлено в задаче. проблема только с отрицательными числами - вместо знака минус получается буква Л.
Всё таки конвертацию нужно частично вернуть.
На этом с этим заданием покончено, спасибо за внимание.