Логотип

Если Вы хотите обучаться программированию микроконтроллеров, но попали, сюда не прочитав предыдущих уроков, то советую начать изучение материала с самого начала.

Программирование микроконтроллеров. Урок 8
Системы счисления

Урок 8 (Системы счисления)

На прошлом занятии мы с вами повторили пройденный материал и сделали уже вполне рабочее устройство, которое может понадобиться в домашнем хозяйстве. Сегодня же мы практическое занятие посвятим наглядному отображению чисел в двоичной системе счисления.

Но до того, как вы разберете схему, сделанную на прошлом занятии, мне бы хотелось поговорить о домашнем задании. В котором надо было доработать программу задержки реле таким образом, чтобы оно не только включалось, но и выключалось по заданному времени. Здесь я только покажу блок схему работы, а программа будет в приложении к уроку. Итак, чтобы наша реле выключалась через установленное время после включения, нам необходимо добавить флаг работы реле и немного доработать ветвь его управления.

Блок-схема 1

А самое приятное то, что это устройство можно запускать с кнопки RESETа. Нажимаешь на RESET и программа снова проходит свой цикл. Ничего больше и не надо. Ознакомится с рабочей версией программы можно в приложении к уроку. Если у кого-то получился другой алгоритм работы. Не беда. Если работа прибора отвечает техническому заданию, то вы все сделали правильно.

Было еще одно домашнее задание – подпрограмма обработчик нажатия кнопки. Но об этом позже.


А теперь, после того как вы проверили работу реле на выключение нам необходимо разобрать все то, что было собрано на прошлых уроках. После этого необходимо будет произвести подключение светодиодов вот по этой схеме.

Схема подключения светодиодов

Схема подключения светодиодов

Собираем схему на макетной плате и вот, что у вас должно получается.

Вид макетной платы 1 Вид макетной платы 2 Вид макетной платы 3

Вид макетной платы 1

Вид макетной платы 2

Вид макетной платы 3

Перед тем как мы насладимся бегущими огнями, надо вкурить немного теории и кратко познакомится с системами счисления . Уверен, что, прочитав статью вы заново открыли для себя символические методы записи чисел. О таком разнообразии в школе не учат. Но для общего развития знать полезно.

Сегодня нас будут интересовать только «Позиционные системы счисления» это там, где позиция знака в записи числа имеет значение. И только те, у которых основанием является: двойка, десятка и шестнадцать. Больше скажу, наша десятеричная система в программировании нужна только для того, чтобы обеспечивать на должном уровне не вербальное общение с двуногими существами, лишенными перьев и восприимчивыми к знаниям. Во как, почти по Платону. А шестнадцатеричная система нужна для более удобной записи двоичных чисел, организованных в байты по восемь бит. Но обо всем по порядку.

Про десятичную, шестнадцатеричную и двоичную системы счисления обязательно читаем в Википедии. А также находим самостоятельно еще парочку источников и «выкуриваем их до фильтра». Если вы что-то не поняли, не беда. Главное уяснить пять моментов.
Первый - младший разряд чисел всегда находится справа.
Второй - четыре бита одного байта называются «Ниббл» т.е. полубайт. У байта есть старший и младший нибблы. Младший находится справа.
Третий – ниббл удобно записывать шестнадцатеричным числом. Это видно из таблицы ниже.
Четвертый – чтобы программа могла правильно интерпретировать написанное вами число перед ним ставится префикс. Для чисел в двоичной системе «0b» от слова «binary - двоичный», например, (0b00101100), а для шестнадцатеричных «0x», например, (0x2С). Для десятичной системы префикс не ставят.
Пятый – желательно выучить, именно выучить на зубок, числа от 0 до 15 в двоичной/шестнадцатеричной системе счисления.


№ п/пДесятичнаяДвоичнаяШестнадцатеричная
1000000
2100011
3200102
4300113
5401004
6501015
7601106
8701117
9810008
10910019
11101010A
12111011B
13121100C
14131101D
15141110E
16151111F

Т.к. компилятор хорошо понимает цифры, записанные в десятеричной системе, то на первых порах не стоит заморачиваться пересчетами чисел из одной системы в другую (для этого есть калькулятор). Но как это делается, надо знать обязательно! Двоичное же представление, полезно тем, что наглядно отображает состояние бит в байте, но использовать двоичное представление чисел приходится не так часто. В основном для настройки регистров управления. Тоже можно сказать и о шестнадцатеричном представлении.

Теперь мы сделаем небольшую программу, которая продемонстрирует нам отображение чисел в двоичной системе от нуля до 255. А за одно и познакомимся с новым оператором цикла - «for».

Если вы прочитали всё, что я просил на прошлом занятии, то о цикле «for» уже знаете все. Но к прочитанному я добавлю свои «пять копеек». Дело в том, что циклы очень коварны. В Си их всего три «for» - цикл с заявленными параметрами, «while» - цикл с предусловием и «do-while» - цикл с постусловием. Если условия цикла прописано не верно, то это может привести к зависанию программы т.е. программа не сможет корректно выйти из цикла и будет «вращаться» по кольцу внутри него. Давайте рассмотрим, как организован цикл изнутри. Вот блок-схема цикла с проверкой до выполнения полезного кода (предусловием). Это как раз общий пример цикла «for» и «while».

Блок-схема 2

Счетчику цикла (I) в начале присваивается некое значение, в нашем случае это (0). После чего происходит проверка условия работы цикла. Т.е. сравнения счетчика с неким числом или переменной, зафиксированной в начале цикла. Если условие верно, то выполняется полезный код и происходит изменение счетчика по установленной программистом формуле (в нашем случае это приращение на единицу «инкремент»). Как только условие цикла становится не верно, программа выходит из цикла. Хочу отдельно отметить, тот факт, что в циклах с предусловием если при первой проверке условие цикла не выполняется, то программа не разу не выполнит внутренний код цикла. А вот в цикле с постусловием даже если условие цикла не выполняется, то внутренний код цикла будет выполнен один раз перед тем как произойдет выход из цикла. А теперь немного о заявленном коварстве. Если вдруг вы неправильно прописали условие изменения счетчика (например, написали i = i) или тип переменной счетчика не соответствует типу числа, указанного в условии (например, переменная i у нас имеет тип char, а число в условии больше чем 255) и, что еще хуже, когда в теле цикла вы изменяете переменную счетчика присвоив ей другое значение (например, значение (i = 5)). То при таких ошибках ваша программа намертво зависнет т.к. условие всегда будет выполняться и выхода из цикла не последует. Напугал… Вот и хорошо. Об этих свойствах циклов надо помнить всегда. Кстати говоря у циклов есть еще несколько заморочек связанных с компиляторами, но об этом пока говорить рано. Лучше вернемся к нашим баранам. Блок-схема программы будет следующей.

Блок-схема 3

После инициализации переменных мы конфигурируем весь порт как выходной. И инициализируем его единицами. Для того чтобы потушить светодиоды.

Затем мы, войдя о основной цикл программы (W), организуем цикл от 255 до 0 и передаем значения каждого шага в порт для отображения на нашем импровизированном индикаторе.

Для того, чтобы можно было понять и увидеть, как происходит счет в двоичной системе необходимо сделать небольшую задержку. Она будет забирать на себя работу МК и переключение индикации будет замедленно, что позволит увидеть приращение счетчика шаг за шагом.

После того как счетчик достигнет максимума, цикл счета повториться снова.

/*
Уроки по изучению основ программирования микроконтроллеров
Тестовая программа к уроку 8
Системы счисления
Сайт: red-resisror.ru
*/
    #include <mega8.h>		//апноты
    #define CLEAN 0		//Очистка
    #define PAUSEA 10000	//пауза
    #define SCHET     255	//Начало отсчета

//Объявляем подпрограммы
void pausa (unsigned long int c_pausa); //подпрограмма паузы


//----------------------------------------------------------------------------------
    void main(void){
//Рабочие переменные и настройки
    unsigned char c_binary = CLEAN;	//счетчик

    PORTD = 0x00;			//Проверка работоспособности всех диодов
    DDRD = 0xff;			//Инициализация вывода порта как выход
    pausa (PAUSEA);			//Задержка отображения всей линейки
    PORTD = 0xff;			//гасим все светодиоды

while (1){				//Тело программы

    for (c_binary = SCHET;c_binary!=0;c_binary--){
        PORTD = c_binary;
        pausa (PAUSEA);
    };

    } //END while
} //END main
//----------------------------------------------------------------------------------
//подпограмма паузы
void pausa (unsigned long int c_pausa) {
    for (c_pausa;c_pausa!=0;c_pausa--){};
}

Вот, что у вас должно получится после того как вы, прошьёте программу в МК.

Некоторые зададутся вопросом почему мы видим на светодиодной дорожке счет от нуля до 255, а счетчик у нас считает в обратную сторону? Все очень просто и связано с питанием светодиодов. Т.к. светодиоды у нас подколочены к общей шине питания и для их активации нужно иметь на выходе МК (0), то нам приходится прибегать к инвертированию данных. То есть считая от 255 к нулю мы увеличиваем количество нулей в порте, что дает нам возможность наблюдать правильный счет на индикаторе.

Домашнее задание. Подумайте над тем как доработать программу таким образом, чтобы по нашей светодиодной полосе бегал один светодиод. Хотя бы вот так.

Поэкспериментируйте с алгоритмами вывода на светодиодную линейку разных узоров.

На следующим занятии мы будем подключать кнопку, потому как есть у меня предчувствие того, что вы забили на домашнее задание седьмого урока. Т.к. кнопка у нас уже есть, то никаких дополнительных радиодеталей не понадобится. Да… Не разбирайте пока светодиодную полоску она пригодится на ближайших двух занятиях.


К следующему уроку необходимо почитать:


Немного о микропроцессорах их организации и работе.
   С.А. Никулин, А.В. Повный «Энциклопедия начинающего радиолюбителя» 2011 год. Страницы 156…187.


Все обооператорах «while» и «do-while»:
   М.Б. Лебедев «CodeVisionAVR пособие для начинающих» 2008г. Страницы 220...221.
   Ю.А. Шпак «Программирование на языке С для AVR и PIC микроконтроллеров» 2006. Страница 127...129.
   Майк МакГрат «Программирование на С для начинающих» 2016. Страницы 80…81.
   К. Поляков «Программирование на языке Си» 1995-2012. Страницы 20…22.


Также необходимо ознакомится с операторами переходов «break, continue и goto», а также другими малоиспользуемыми операторами:
   М.Б. Лебедев «CodeVisionAVR пособие для начинающих» 2008г. Страницы 222…229.
   Ю.А. Шпак «Программирование на языке С для AVR и PIC микроконтроллеров» 2006. Страница 127.
   Майк МакГрат «Программирование на С для начинающих» 2016. Страницы 82…85.
   К. Поляков «Программирование на языке Си» 1995-2012. Страницы 23…24.


А на сегодня всё. Удачи.


28.06.18


Если вдруг найдете в статье неточности или заблуждения. Напишите мне об этом. Я подправлю.




Приложение:
Блок-схемы, проект CV_AVR.