Если Вы хотите обучаться программированию микроконтроллеров, но попали, сюда не прочитав предыдущих уроков, то советую начать изучение материала с самого начала.
На прошлом занятии мы с вами ознакомились с поразрядными операциями, а в качестве домашнего задания я предложил вам самостоятельно изучить ШИМ и попробовать, применяя знания, полученные на предыдущих уроках, запрограммировать контроллер, чтобы он выполнял функцию ШИМ регулятора. |
---|
Те, кто смог сделать домашку безусловно молодцы, но для остальных я бы хотел разобрать совою версию программы и рассказать о том, как она работает.
Я надеюсь, что про ШИМ вы уже всё знаете. Или как минимум посмотрели лекцию по ссылке прошлого урока. А значит я только напомню о том, что в нашем случае ШИМ Регулятор - это программа которая будет управлять временем, подачи напряжения на светодиоды (t1) при условии, что период (t) будет константа.
Из рисунка видно, что наша задача сводится к организации счетчика, который отсчитывает периоды (t) и счетчика, который отсчитывает время заполнения (t1). А так как нам необходимо регулировать этот процесс, то мы дополнительно должны включить в программу возможность осуществлять корректировку значения рабочего счетчика. Ну и конечно, чтобы добиться переменного свечения придется автоматически изменять значение величины заполнения (t1).
Разберем блок-схему моей программы.
В начале мы как обычно объявлениям необходимые переменные, инициализируем порт и уходим в основной цикл. Где в первую очередь проверяем счетчик периода (c_period). Если он не равен нулю, а это значит, что идет процесс индикации, то мы проверяем счетчик заполнения (c_work) и если он не равен нулю, то включаем светодиоды (PORT = ON) после чего декрементируем счетчик заполнения, а также счетчик периода. Как только счетчик заполнения (c_work) становится равным нулю, то мы гасим светодиоды (PORT = OFF) и дорабатываем до конца периода. Надо отметить, что когда счетчик заполнения (c_work) равен нулю, то светодиод не зажигается и напротив, когда он равен счетчику периода (c_period), то светодиоды горят постоянно. Как только счетчик периода (c_period) становится равен нулю, программа переходит к исполнению ветки регулирования где в первую очередь проверяется флаг работы. Ели он включен (f_work == ON), то светодиоды загораются и регулятор (d_light++) увеличивается, в противном же случае происходит затухание и регулятор уменьшается (d_light--). После чего, в зависимости от исполнения ветки, происходит сравнения значения регулятора с максимальным или минимальным значением. А в случае если значения регулятора выходит за рамки лимитов, то происходит переключение флага работы (f_work). В конце блока регулирования происходит установка счетчика работы (c_work = d_light) и обновление счетчика периода (c_period = PERIOD). После чего повторяется цикл индикации с новыми значениями счетчика работы.
Очередной зануда скажет, что данная программа не является полноценным ШИМ регулятором т.к. во время исполнения ветки регулирования между периодами работы ШИМ получается небольшой лаг. Ну да… Потому-то для реализации полноценной ШИМ на МК и используют внутренние таймеры со встроенной функцией широтно-импульсной модуляции. Но об этом позже. С другой стороны, такая реализация очень даже применима при разного рода индикациях, подсветках, управление двигателем, да Бог знает где еще. Более того, если вместо банальных (d_light++, d_light--) применить более продвинутый математический аппарат, то изменения свечения можно сделать более плавным или мерцающим. Но с этим надо быть по осторожнее т.к. обсчет разного рода формул занимает немало машинного времени.
Программа будет выглядеть таким образом.
while (1){ //Тело программы if (!(c_period)){ //Режим регулирования c_period == 0 if(f_work == ON){ //Проверка флага переключения работы если флаг ON d_light ++; //Прирощение времени свечения if (d_light >= MAXIMUM)f_work = OFF; //переключение работы по максимальному свечению } else { //если флаг OFF d_light --; //Уменьшение времени свечения if (d_light <= MINIMUM)f_work = ON; //переключение работы по минимому свечения }; c_work = d_light; //Передача данных времени свечения счетчику c_period = PERIOD; //Восстанавливаем знаение периода } else { //Режим индикации if(c_work) { //Счетчик свечения PORTD = LIGHT; //Зажигаем светодиоды c_work --; //Декремент счетчика свечения } else PORTD = DARK; //Тушим светодиоды c_period--; }; } //END while
Всю программу можно посмотреть в прилагаемых файлах. Ну вот. С ШИМ мы закончили.
Сегодня мы начнем изучать последнюю тему «Основ языка Си».
Их проще всего представить в виде книги. Тогда одномерный массив — это строка, двумерный это страница, трехмерный это уже сама книга, а четырехмерный это полка с книгами ну и так далее. В программировании массивы встречаются очень часто. Ни одна мало-мальски приличная программа не обходится без них. Но когда ты пишешь программу для МК, то с массивами надо быть очень аккуратным. Само слово «массив» говори т чем-то большом и громоздком. И действительно массивы занимают очень много памяти. А так как в МК её очень нехватает, то при инициализации массива необходимо четко представлять сколько байт он будет занимать. Например, двумерный массив данных типа (int) 32 х 8 займет в памяти прямехонько пол килобайта. А это как раз половина от всей оперативной памяти нашего МК. У массива также есть еще одно свойство. Он может в себя вмещать только одинаковые по типу данные. Для объединения данных разного типа используются «структуры». Но т.к. применение структур в МК на мой взгляд редкость, то мы этот раздел Си затрагивать не будем. На данном этапе о структурах просто надо знать. И вы, в свое время, изучите их самостоятельно.
Перед тем как мы углубимся в изучение массивов, нам, для разного рода экспериментов, необходимо будет сделать светодиодную матрицу в виде куба 3 х 3 х 3. Этот куб будет представлять классический двумерный массив 3 на 9 с которым в дальнейшем мы и будем работать.
Если мои объяснения о том, как делать куб непонятны, то можно погуглить и посмотреть, как их делают другие. Например, здесь.
Итак, приступим. Для начала наберем 27 светодиодов. Я взял светодиоды диаметром 3 мм, но это не принципиально. Главное, чтобы у них все ножки были целыми, а то придется напаивать, что в общем сильно усложнит сборку.
Для начала согнем все аноды (+) светодиодов так как показано на рисунке (шаг 1).
Затем согнем все катоды в одну сторону под 90 градусов (см. рис. Шаг 2). Потом возьмем небольшую досточку и вырвем из тетради листок в клетку. Т.к. у ваших светодиодов длинна ножек может быть не такой как у моих, поэтому исходя из длинны ножек выбираем расстояние между светодиодами. Оно будет либо 1 см. как у меня, либо 1.5 см. Расстояние больше чем 1.5 см делать не стоит потому как будет не очень удобно спаивать светодиоды в матрицу.
Размечаем нашу досточку путем прокалывания шилом приложенной к ней клетчатой бумаги и просверливаем сверлом, диаметр которого равен диаметру светодиодов, девять отверстий. Паяем свотодиоды в матрицы. Вот так.
После того как у нас получилось три матрицы. Припаиваем их друг на друга, а также припаиваем к трем общим катодам и к девяти анодам проводки со штырьками от нашего набора, предварительно откусив от них один штырек. У вас должно получиться что-то подобное.
Теперь нашу матрицу необходимо протестировать. Собираем схему тестирования. И если вы все правильно сделали, то подключая общие катоды по порядку к общей шине (-), у вас должны по слоям загораться светодиоды. Вот так.
Ну вот. Теперь можно отдохнуть от трудов праведных и перейти к теоретической части изучения массивов.
На ночь читаем все о массивах, структурах и перечислениях: Майк МакГрат «Программирование на С для начинающих» 2016. Страницы 36…39, страницы 64…65, страницы 100…108. Ю.А. Шпак «Программирование на языке С для AVR и PIC микроконтроллеров» 2006. Страницы 120…125. М.Б. Лебедев «CodeVisionAVR пособие для начинающих» 2008г. Страницы 183…198.
На следующим уроке соберем схему нашего устройства и напишем простенькую программу для нашего кубика с использованием массивов. По мимо того что мы использовали сегодня нам понадобится: три транзистора кт 815, три резистора на 1 кОм и три резистора на 10 кОм о которых я говорил на прошлом уроке.
А на сегодня всё. Удачи.
11.09.18
Уточнение по поводу следующего урока.
Когда я начал писать программу для нашего кубика, то понял, что погорячился сразу, без подготовки, давать такой материал. Для понимания массивов думаю сначала надо потренироваться на «кошках». Поэтому на следующем занятии мы подключим 7-ми сегментный индикатор (CPD-05212SR1/A) и разберем его работу. Там как раз и познакомимся со статическим массивом. Через занятие мы подключим матрицу из тех индикаторов, а вот только после этого нам понадобится наш кубик.
Если вдруг найдете в статье неточности или заблуждения. Напишите мне об этом. Я подправлю.
Приложение: проект CV_AVR.