Простой счётчик на STM32
Теперь когда мы более-менее разобрались как рулить портами микроконтроллера можно попробовать сделать что-то практическое и даже немного полезное, дабы закрепить знания. Делать мы сегодня будем простейший счётчик, а считать он будет количество нажатий кнопки. Ну а кнопку в свою очередь можно прицепить куда угодно, например к двери, чтоб считать количество открываний :) Это первое что пришло мне в голову, вероятно что вы придумаете ему куда более лучшее применение. В качестве устройства индикации мы будем использовать 4-х разрядный семисегментный индикатор. Он представляет собой вот такую железяку:
Может показаться немного странно, что выводов меньше чем должно быть. Сегментов у нас семь + точка итого 8 на разряд, а разрядов 4. Итого получаем 8 * 4 = 32 + как минимум один общий провод итого 33! Но на деле всего лишь 12 выводов. Такое уменьшение количества выводов достигается за счёт соединения вместе всех одинаковых сегментов. Таким образом наружу индикатора выходят 8 выводов (для сегментов) и 4 общих вывода (по одному на разряд). Возникает вопрос: А как вообще вывести какое-либо число на индикатор ? Ведь все сегменты соединены воедино и вывести две разные цифры в разные разряды в один момент времени не получится. Для решения этой проблемы придумали динамическую индикацию. Принцип её работы очень хорошо отражает следующая картинка:
Из неё видно, что в любой момент времени на индикаторе загорается только один разряд. Разряды загораются по очереди, и очень быстро. Из-за инерционности человеческого зрения, нам кажется что все разряды горят одновременно. Прежде чем писать код, сначала разберёмся какие индикаторы бывают и как их подключить к контроллеру. Индикаторы бывают с общим катодом и общим анодом. Какие покупать это совершенно не принципиально, юзать можно любой, но придётся изменять код программы и немного подправить схему. Для того чтобы зажечь цифру на индикаторе с общим катодом нужно подать плюс питания на нужные сегменты, а общий вывод нужного разряда посадить на землю. Для индикатора с общим анодом всё наоборот: Сегменты соединяем с землёй, а на общий вывод разряда подаём напряжение питания. Теперь о подключении всего этого дела к контроллеру. Кроме самого индикатора нам еще потребуются 8 резисторов, или 7 если точка нам не нужна. Поскольку мы ваяем счётчик нажатий кнопки, то считать он будет целые числа, а следовательно точка нам ни к чему. Каждый сегмент индикатора это один обычный светодиод. А значит для того чтоб он не сгорел, нужно ограничить ток который через него проходит. Для этого мы будем использовать семь резисторов на на 220 ом каждый. Таким образом ток через каждую ножку подключенную к сегментам не превысит 15 мА что вполне допустимо. Но есть одна проблема с выводами контроллера которые подключаются к общим выводам индикатора: Если одновременно загорятся все 7 сегментов, то ток который протекает через общий вывод составит примерно 15*7=105 мА! От такой нагрузки контроллер может вспотеть и испустить волшебный дымок на котором работает вся электроника. Когда дымок покидает устройство - оно ломается :) Для того чтоб уменьшить нагрузку на общие выводы, в схеме применяются ключевые транзисторы. Когда на базу транзистора поступает лог 1 с контроллера, он открывается и соединяет общий вывод индикатора с землёй, тем самым принимая всю нагрузку на себя. Схема всего этого выглядит так:
Транзисторы можно применить вообще любые n-p-n типа. У меня нашлись BC547 вот их то я и использовал. Четыре резистора по 1К обязательны, они ограничивают ток базы. Если таких нет, то можно заюзать другие (не слишком большого сопротивления) лишь бы транзистор полностью открывался. Теперь о кнопке. у нас она будет подключена к ноге PA0, это удобно так как эта кнопка уже есть на STM32vl Discovery и припаивать её мне не придётся. На этом описание аппаратной части можно считать законченным. Прежде чем писать софт еще пара слов об алгоритме работы:
1) Настроить порты ввода/вывода:
1.1) Включить тактирование портов
1.2) Настроить 11 пинов порта ХХ на выход
1.3) Настроить пин PA0 на вход
2) Проверить состояние кнопки.
2.1) Если нажата то увеличить счётчик на 1.
2.2) Если счётчик досчитал до 10000 то обнулить его
3) Разложить число в переменной счётчике на отдельные цифры
4) Поочередно вывести каждую цифру на соответствующий разряд индикатора
5) Перейти к шагу 2
Теперь, когда у нас есть хотябы примерный алгоритм можно приступать к написанию кода.
В этом коде я работаю с портами не напрямую через регистры, как в предыдущем примере, а использую специалзированную библиотеку, а это значит что при создании новго проекта в CooCox'e нужно не забыть поставить галку GPIO. С использованием этой библиотеки код становится более читаемым, не нужно помнить о том для чего нужен каждый бит. Многое в этом коде откомментировано, думаю что особых проблем с пониманием написанного не возникнет. Ну а если вопросы появятся то можно задать их чуть ниже. Компилируем, прошиваем, запускаем и получаем в результате что-то типа такого:
Работает! Жмем кнопку - значение счётчика увеличивается. Теперь можно сделать для всего этого отдельный корпус и найти счётчику достойное применение :-)