AVR на C — просто? Часть 2

2. Первая программа или порты ввода-вывода.

2.1. Порты и выводы.

Чтобы общаться с внешним миром у микроконтроллера есть порты ввода-вывода, в каждом из которых есть несколько отдельных битов (считай выводов), на которых можно установить ноль (0) или единицу (1).

У ATmega328 таких портов 3 это порты B,C и D. На каждом порту по 8 битов(за исключением порта C он 7 — разрядный) которыми можно (нужно) управлять. Но управлять с некоторыми ограничениями.

Ограничения:

  • D0 и D1 используются для прошивки микроконтроллерах на плате Arduino через USB;

  • C6 – используется для перезагрузки (reset);

  • B6 и B7 — на этих выводах микроконтроллера подключается внешний кварцевый резонатор.

Остальные биты можно использовать если они не задействованы. Для наших изысканий будем использовать:

  • порт B – B0, B1, B2, B3, B4, B5 (соответственно выводы микроконтроллера с 14 по 19);

  • порт C – С0, С1, С2, С3, С4, С5 (выводы — с 23 по 28);

  • порт D – D2, D3, D4, D5, D6, D7 (выводы — 4, 5, 6, 11, 12, 13).

Необходимо учитывать что ATmega328 производится в разных корпусах и нумерация выводов может отличатся

2.2. Регистры управления портами.

Управление портами достаточно простое. Используется три восьми битных регистра —

DDRx, PORTx и PINx, где x имя порта (в нашем случае B,C и D).

  • DDRx – Настройка разрядов порта x на вход или выход.

  • PORTx – Управление состоянием выходов порта x (если соответствующий разряд настроен как выход), или подключением внутреннего подтягивающего резистора (резистор подтягивает разряд к 1 если соответствующий разряд настроен как вход).

  • PINx –Чтение логических уровней разрядов порта x.

Настройка и работа портов сводится к трем операциям в зависимости от настройки входа или выхода.

Ввод:

  • В регистре DDRx на нужный разряд устанавливаем 0 обозначая его как ввод;

  • При необходимости на указанном разряде устанавливаем 1 для подключения подтягивающего резистора (резистор подтягивает указанный вывод к 1), подтягивающий резистор включают для уменьшения внешних помех и его можно не подключать;

  • Считываем из регистра PINx с того-же разряда состояние 0 или 1.

  • Вывод:

  • В регистре DDRx на нужный разряд устанавливаем 1 обозначая его как вывод;

  • В регистр PORTx на этот разряд устанавливаем его состояние 0 или 1;

  • В регистре PINx можно считать текущее состояние каждого разряда порта.

  • Пример: На выводе 5 порта B установить 1 (вывод 17 микроконтроллера переключить на логическую 1)

    регистр DDRB

    DDRB7

    DDRB6

    DDRB5

    DDRB4

    DDRB3

    DDRB2

    DDRB1

    DDRB0

    0

    0

    1

    0

    0

    0

    0

    0

    Установили разряд DDRB5 в 1 настроив вывод как вывод

    регистр PORTB

    PORTB7

    PORTB6

    PORTB5

    PORTB4

    PORTB3

    PORTB2

    PORTB1

    PORTB0

    0

    0

    1

    0

    0

    0

    0

    0

    Установили разряд PORTB5 переключив вывод микроконтроллера в 1. Дальнейшее переключение этого вывода производится без изменения регистра DDRx если не понадобится переключить разряд порта на ввод.

    Регистр PINB можно не использовать, если лишь для проверки состояния выводов порта.

    Рекомендация: биты регистров желательно переключать по отдельности, чтобы не вносить путаницу в программу микроконтроллера, если нет необходимости использовать все выводы порта как ввод или вывод.

    2.3. Программа

    Разберем программу на C по строкам.

    #include <avr/io.h> // Подключение библиотеки
    // ввода/вывода AVR

    #include <util/delay.h> // Подключение библиотеки создания задержек

    #define V_V 5 // Указываем макроопределение регистра 5 порта B

    int main() {
    DDRB |= 1 << V_V; // Устанавливаем 5 бит регистра DDRB в
    // (назначаем как вывод)

    while(1) { // Безконечный цикл основной программы
    PORTB |= 1 << V_V; // Устанавливаем вывод микроконтроллера в 1
    _delay_ms(100); // Ждем 100 мс
    PORTB &= ~(1 << V_V); // Устанавливаем вывод микроконтроллера в 0
    _delay_ms(100); // Ждем 100 мс
    }
    return 0;
    }

    В программе вставлен бесконечный цикл while(1), чтобы микроконтроллер не выполнил ничего лишнего. Все действия с портами в программе выполнены с использованием поразрядных операций в языке C. Что дало возможность управлять лишь одним разрядом (одним выводом микроконтроллера) порта B.

    На использованном нами выводе микроконтроллера ATmega328 в Arduino UNO и Arduino Nano v3 подключен светодиод, поэтому в первой программе не придется даже собирать схему, достаточно подключить Arduino к компьютеру.

    2.4. Проект на C и компиляция

    Программное обеспечение готово, программа написана, микроконтроллер тоже есть в виде Arduino. Начнем.

    Запускаем CodeBlocks, в меню File >> New >> Project начинаем создавать проект.

    Выбираем AVR Project и Go.

    Next

    В поле Project title указываем название проекта, ниже в Folder to create project in указываем путь к папке куда создаем проект и жмем Next.

    В следующем окне оставляем галку лишь Create “Release” configuration и опять Next.

    Выбираем наш микроконтроллер (у меня atmega328p) устанавливаем частоту (для Arduino Nano v3 — 16МГц) и оставляем создание лишь hex файла и Finish.

    И наконец в созданном проекте находим файл main.c и открываем его. Внутри видим:

    /*
    */

    #include <avr/io.h>

    int main(void)
    {

    // Insert code

    while(1);

    return 0;
    }

    Заменяем эту заготовку нашей программой и жмем 

    Происходит компиляция проекта и внизу видим

    2.5. Прошиваем микроконтроллер

    Все прошивка готова, она находится в папке проекта (выбранной при создании проекта). У меня C:avrProgram1binReleaseProgram1.hex этот файл и является нашей прошивкой.

    Начнем прошивать. Запустим программу ArduinoBuilder

    В окне выбираем файл hex (находится в папке проекта CodeBlocks >> bin/Release/project1.hex) нашего проекта, выбираем Arduino и частоту микроконтроллера и жмем кнопку чем программировать (у меня COM9) обычно это com порт отличный от 1. После сего проделанного смотрим мигающий диод.

    На этом задача минимум выполнена. Рассмотрен подборка программного обеспечения, изучены порты ввода/вывода и регистры их управления, написана программа на C скомпилирована и прошита в микроконтроллер. И все это можно применить для микроконтроллеров AVR за исключением программы ArduinoBuilder которая в основном создана под Arduino, но и ее можно заменить при использовании например программатора USBASP и программы AVRDUDE_PROG, основная часть материала полностью применима.

    Часть 3

    Список радиоэлементовОбозначение
    Тип
    Номинал
    Количество
    ПримечаниеМагазинМой блокнот

    Плата ArduinoArduino Nano 3.01

    Плата ArduinoArduino Uno1
    Добавить все

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

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

    Добавить комментарий

    Ваш адрес email не будет опубликован.