Blog the XELFAER

Заметки *NIX

Первый проект на микроконтроллере —

Первый создаваемый проект очень важен, от него зависит захочет ли человек в случае неудачи разобраться с проблемой или бросит это занятие. Обычно для начала выбирают схему попроще: например мигание светодиодом или группой светодиодов. Свой путь я начал со схемы USB термометра, но собрав схему, прошив МК она работать отказалась. Были тщетные попытки схему заставить работать, но как выяснилось позже с ней были проблемы не только у меня. Поэтому я также решил начать с самого простого — мигание группой светодиодов.

В предыдущей статье было рассмотрено, что необходимо для начала работы, поэтому повторятся не будем.

Для начала соберем схему для будущего устройства. Я собирал на макетной плате спаивая проводами. Для большего интереса решено было использовать не один светодиод, а сразу 5 штук — это позволит более наглядно посмотреть на работу устройства.
Для всей схемы потребуются:
1. Микроконтроллер Atmega8 — 1 шт.
2. Светодиоды — 5 шт.
3. Резисторы 300 Ом — 5 шт.
4. Конденсатор электролитический 100 мкф — 1 шт.
5. Разъем ISP для подключения шлейфа программатора — 1шт.
и помимо этого необходим также программатор для прошивки МК и источник питания с выходным напряжением 5V для запуска устройства.

Ниже приведена принципиальная схема устройства:

Схема устройства

Внимательно глянув на схему можно заметить что на ней отсутствует конденсатор, хотя в перечне деталей он присутствует. Его можно ставить, можно не ставить — зависит от какого источника питания вы будете питать устройство. Если все таки решите поставить, то его нужно подключить между выводами VCC и GND. Я его поставил у себя так как хуже не будет, поэтому пусть будет.
Спаять на макетной плате устройство это еще только пол дела. По сути наше устройство груда железа. Что бы его оживить необходимо написать прошивку, чем сейчас и займемся.

Для создания прошивки используем любой текстовый редактор. Прошивку будем писать на C.
Создаем файл main.c в каталоге проекта и с приступаем к написанию кода.

#define F_CPU 1000000UL //устанавливаем частоту МК 1 MHz
#include <avr /io.h>        //подключаем header библиотеки ввода/вывода
#include <util /delay.h>    //подключаем header библиотеки задержки

int main(void)
{
    DDRD = 0xff;    //устанавливаем все порты D как выходы
        while (1)   //запуск бесконечного цикла
        {
            //**прямой порядок**//
            PORTD |= _BV(PD0);  //устанавливаем логическую 1 на порт D линии 0
            _delay_ms(150);     //устанавливаем задержку
            PORTD &= ~_BV(PD0); //устанавливаем логический 0 на порт D линии 0
            _delay_ms(150);     //устанавливаем задержку
       
            PORTD |= _BV(PD1);
            _delay_ms(150);
            PORTD &= ~_BV(PD1);
            _delay_ms(150);
           
            PORTD |= _BV(PD2);
            _delay_ms(150);
            PORTD &= ~_BV(PD2);
            _delay_ms(150);
           
            PORTD |= _BV(PD3);
            _delay_ms(150);
            PORTD &= ~_BV(PD3);
            _delay_ms(150);
           
            PORTD |= _BV(PD4);
            _delay_ms(150);
            PORTD &= ~_BV(PD4);
            _delay_ms(150);
           
            //**обратный порядок**//
            PORTD |= _BV(PD3);
            _delay_ms(150);
            PORTD &= ~_BV(PD3);
            _delay_ms(150);
   
            PORTD |= _BV(PD2);
            _delay_ms(150);
            PORTD &= ~_BV(PD2);
            _delay_ms(150);
           
            PORTD |= _BV(PD1);
            _delay_ms(150);
            PORTD &= ~_BV(PD1);
            _delay_ms(150);
           
            //**от краев**//
            PORTD |= _BV(PD0);
            PORTD |= _BV(PD4);
            _delay_ms(150);
            PORTD &= ~_BV(PD0);
            PORTD &= ~_BV(PD4);
            _delay_ms(150);
           
            PORTD |= _BV(PD1);
            PORTD |= _BV(PD3);
            _delay_ms(150);
            PORTD &= ~_BV(PD1);
            PORTD &= ~_BV(PD3);
            _delay_ms(150);
           
            PORTD |= _BV(PD2);
            _delay_ms(150);
            PORTD &= ~_BV(PD2);
            _delay_ms(150);
           
            //**от центра**//
            PORTD |= _BV(PD2);
            _delay_ms(150);
            PORTD &= ~_BV(PD2);
            _delay_ms(150);
           
            PORTD |= _BV(PD1);
            PORTD |= _BV(PD3);
            _delay_ms(150);
            PORTD &= ~_BV(PD1);
            PORTD &= ~_BV(PD3);
            _delay_ms(150);
           
            PORTD |= _BV(PD0);
            PORTD |= _BV(PD4);
            _delay_ms(150);
            PORTD &= ~_BV(PD0);
            PORTD &= ~_BV(PD4);
            _delay_ms(150);
            }
        _delay_ms(1000);
}

Внимательно смотрим код прошивки и читаем комментарий к коду.
Так как использовано в проекте 5 светодиодов, то было решено в прошивке реализовать разные эффекты, а то монотонное мигание выглядит немного удручающе.
Сохраняем файл прошивки и приступаем к компиляции:

avr-gcc -mmcu=atmega8 -I. -gdwarf-2 -DF_CPU=1000000UL -Os -o main.o main.c

где: main.c — файл с кодом прошивки
main.o — объектный файл, который будет создан в случае успешно выполненной команды

далее мы должны получить долгожданный файл прошивки в формате hex:

avr-objcopy -O ihex main.o main.hex

где: main.o — объектный файл
main.hex — файл прошивки, который будет создан в случае успешно выполненной команды

Прошивка готова. Теперь осталось дело за малым — залить ее в микроконтроллер. Подключаем программатор к устройству, подключаем к устройству внешнее питание (подключать внешнее питание следует только в том случае если в программаторе нет функции подачи питания на программируемое устройство).
У меня программатор AVR910 с USB интерфейсом. Для прошивки необходимо узнать на каком порту он висит. После подключения программатор к ПК вводим команду dmesg которая покажет нам наш программатор:

dmesg

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

Когда все подключено можно опросить программатор:

# avrdude -c avr910 -pm8 -P /dev/ttyACM0

на что он выдаст что то похожее на:
test_avr910
и приступить уже к заливке прошивки:

# avrdude -c avr910 -pm8 -P /dev/ttyACM0 -U flash:w:main.hex

на что он выдаст что то похожее на:
write_firmware
Прошивка залита. Фъюзы микроконтроллера менять не нужно они остаются по умолчанию.
Теперь можно отключить программатор и включить устройство. Светодиоды должны начать мигать в той последовательности которая заложена в прошивке.


Скачать архив прошивки: led_string

© 2013 — 2015, XELFAER. Все права защищены. Использование материалов блога разрешается только при указании активной ссылки на статью.

Print Friendly, PDF & Email

Рубрики: Linux | Microcontrollers | Radioelectronica


комментариев 12

  1. atsybulin:

    Установил avrdude, прошивку скомпилил. Теперь столкнулся с такой проблемой, подключаю программатор к Raspberry Pi (только на нем у меня Linux), не пойму как его опросить. Вывод dmesg и фотку как это все подключено по прилагаемой ссылке. Программатор у меня USBASP v2.0. Как мне запустить эту конструкцию?

    P.S. Можно ли без программатора залить прошивку? На RPi есть GPIO, распиновку прилагаю.

    http://tinyurl.com/qxt5chd

    • Для начала необходимо проверить подключение программатора к МК. Для указанного программатора распиновка разъема вот:
      USBasp v2.0 pinout
      Для МК Atmega8 — выводы:
      17(PB3) — MOSI
      18(PB4) — MISO
      19(PB5) — SCK
      1(PC6) — RESET
      7(VCC) и 20(AVCC) — +5V
      8(GND) и 22(GND) — земля(общий)

      Если подается напряжение от отдельного источника питания — необходимо соединять общий провод(GND) программатора с общим проводом источника питания.
      Для прошивки через avrdude:
      avrdude -c usbasp -p m8 -U flash:w:main.hex
      где: main.hex — прошивка.

      • atsybulin:

        вроде все подключил как на схеме, после этой команды выдает такие сообщения:
        avrdude: warning: cannot set sck period. please check for usbasp firmware update.
        avrdude: error: programm enable: target doesn’t answer. 1
        avrdude: initialization failed, rc=-1
        Double check connections and try again, or use -F to override
        this check.

        • Вроде — это не корректный ответ. Необходимо точно проверять.
          Приложите нормальные фото/видео соединения программатора с отлаживаемой схемой: что от чего питается, что куда подключается.

          • atsybulin:

            По той же ссылке добавил два фото, питание пробовал переключать перемычку на 5В на программаторе, или с USB порта. При втором варианте 5В из программатора убирал. Чяднт?

          • Если бы сделали фото крупнее с подключение проводов к разъемам, что бы было видно куда какой провод подключается — было бы удобней, а так разглядеть достаточно проблематично. И еще: я заметил что стоит USB hub, он питается от отдельного источника питания или от USB порта Raspberry PI? Отключите все от малины из USB портов, и оставьте только клавиатуру и программатор и тогда пробуйте прошивать МК.

  2. atsybulin:

    Добавил еще несколько фото. USB hub питается от сети (отдельного источника).

  3. atsybulin:

    Если будет время, напишите статейку, как соединить ATmega и nRF24L01+. Заранее благодарен.

    • Самому хотелось с данным модулем разобраться, но увы за не имением данного модуля и финансов на его покупку — это является на текущий момент не возможным.

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