Машинка на ДУ управлении своими руками — МК это просто (Atmel AVR)!

На этом уроке мы начнём осваивать работу с микроконтроллером ATmega8.

Первым делом подадим питание на МК, подключим его к программатору, Добьемся, чтобы программатор «увидел» МК. Разберёмся с фьюзами. Установим среду программирования. Напишем первую программу, скомпилируем и прошьём МК. В окончании убедимся в работоспособности МК.

Заглянем в даташит, раздел 25.8 Serial Downloading. Будем подключать МК к программатору согласно этому рисунку…

Назначения выводов Вашего программатора вы можете узнать из документации к нему. В моём случае распиновка USBASP следующая:

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

Теперь необходимо установить драйвера к программатору USBasp Driver 0.1.12.1.

Программа SinaProg 2.1 установки не требует.

Ну а теперь эти страшные фьюзы… устанавливаем как на screenshoot-ах…

Программирование битов защиты: нам нечего скрывать, всё разблокировано – No lock…

  • BOOTSZ0..1 – задает размер сектора загрузчика
  • RSTDISBL – отключает вывод reset, делая его обычной ножкой ввода-вывода
  • WDTON – включает Watch Dog Timer
  • SPIEN – разрешает последовательное програм- мирование
  • EESAVE – защита EEPROM от стирания 
  • BOOTRST – заставляет микроконтроллер запускаться с области бутлоадера
  • CKOPT –  задает размах тактового сигнала,  т.е. амплитуду колебаний на выходе с кварца. Когда CKOPT = 1 то размах минимальный, за счет этого достигается пониженное  энергопотребление, но снижается устойчивость к помехам. Если CKOPT = 0, то размах сигнала увеличится. Это повышает энергопотребление и помехоустойчивость.

ВНИМАНИЕ! Не вЫключайте бит SPIEN. Выключение этого бита, запретит последовательный режим программирования, и микроконтроллер не будет отвечать.

ВНИМАНИЕ! Не вКлючайте бит RSTDISBL. В последовательном режиме программирования необходим вывод RESET. Включение этого бита, выключит вывод RESET, и микроконтроллер не будет отвечать.

  • BODLEVEL и BODEN – определяет момент срабатывания детектора уровня питающего напряжения, при снижении напряжения питания ниже установленного уровня, произойдет «перезагрузка» контроллера
  • CKSEL – выбор источника тактового сигнала для микроконтроллера

Программу для нашего МК мы будем писать в Atmel Studio 6.2.

Какая среда лучше? CodeVisionAVR, WinAVR, Bascom-AVR? В какой писать удобнее, а в какой понятнее вопрос субъективный.

Я решил для себя, что писать лучше в среде разработки предоставленной ATMEL. На том и порешили…

Первая программа. Что ж, запускаем Atmel Studio. Создаём новый проект File->New->Project…

Выбираем тип процессора, жмём далее. В результате мастер создания проектов, выдаёт шаблон кода, который мы приведем к благообразному виду…

/*
* test.c
*
* Created: 16.02.2015 0:41:52
* Author: Сергей Владимирович
*/
#include < avr/io.h > //Файл определения имён регистров, портов, констант…

Int main(void) //Основной цикл

{
while(1) //Бесконечный цикл
{
//TODO:: Please write your application code
}
}

Для обмена данными с внешним миром в МК предусмотрены порты ввода-вывода. Именуются они PORTA, PORTB, PORTC… и так далее. У каждого порта может быть несколько линий, выводов, обычно их 8-мь. В нашем случае, из раздела Pin Configurations, мы узнаём, что наш МК имеет три порта:

  • PORTB имеет 8-ь выводов с названиями PB0 — PB7;
  • PORTC имеет 7-ь выводов с названиями PC0- PC6;
  • PORTD имеет 8-ь выводов с названиями PD0 — PD7.

   Каждому порту можно задать направление передачи данных:

  • порт настроен на ввод, МК получает данные из вне;
  • порт настроен на вывод, МК выводит обработанные данные во внешнюю среду, включает, управляет и т.п.

В процессе работы вывод порта может принимать два состояния:

  • «высокое» — логическая единица – напряжение +5В;
  • «низкое» — логический ноль, напряжение 0В.   

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

Во первых подключаем внешнюю библиотеку для работы с функциями задержки…

#include < util/delay.h >  //Функции ожидания

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

#define F_CPU 8000000UL  //Указываем тактовую частоту процессора

Выбираем порт, например PORTC. Порт содержит семь линий, используем линию PC5 которая соединена с 28-ым выводом микросхемы.

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

Каждой линии порта PORTC соответствует бит регистра DDRC. Этот бит определяет направление линии ввода-вывода. Если бит регистра DDRC равен 1, то линия PC5 настроена на выход, если равен 0, то на вход.

DDRC |= (1<<5);  //Настраиваем линию PC5 на выход

Как же понять эту строчку??

Выражение 1<<5 осуществляет сдвиг единички влево на 5 бит, то есть справа добавляются четыре нулевых бита и получается 10000, а знак «|», стоящий перед знаком присваивания «=», осуществляет операцию побитного логического сложения.

При логическом сложении  0+0=0, 0+1=1, 1+1=1. Операцию логического сложения по-другому называют операцией ИЛИ (английское название OR).

Таким образом, к битам, хранящимся в регистре DDRС = 0b00000000, прибавляется двоичное 10000, представленное как 0b00010000, и результат сложения 0b00010000 записывается в регистр DDRС.

Собираем всё вместе…

#define F_CPU 8000000UL

#include < avr/io.h > //Файл определения имён регистров, портов, констант…
#include < util/delay.h > //Функции ожидания

int main(void) //Основной цикл
{
DDRC |= (1 << 5); //Настраиваем линию порта PC5 на вывод!

while(1) //Бесконечный цикл
{
PORTC |= (1 << PC5); //Устанавливаем линию порта в высокое состояние
_delay_ms(2000); //Ждём 2-е секунды

PORTC &= ~(1 << PC5); //Устанавливаем линию порта в низкое состояние
_delay_ms(2000); //Ждём 2-е секунды
}
}

Как записать единицу в регистр Вы уже знаете, а как быть с нулем?

Чтобы установить вывод порта PС5 в низкое состояние, нам необходимо в бит PC5 порта PORTC записать ноль. Для этого применяют следующую конструкцию:

PORTC &= ~(1<< PC5);  // Устанавливаем линию порта в низкое состояние

Выражение 1<< PC5 осуществляет сдвиг единички влево на 5 бит, то есть справа добавляются четыре нулевых бита и получается 10000, далее инвертируется с помощью операции побитного инвертирования, обозначаемой значком «~». После инверсии мы получаем вместо нулей единички, а вместо единичек – нули. Эта логическая операция иначе называется операцией НЕ (английское название NOT).

Таким образом, при побитном инвертировании 0b00010000 мы получаем 0b11101111.

Получившееся число с помощью операции побитного логического умножения & умножается на число, хранящееся в регистре порта PORTC, и результат записывается в регистр порта PORTC.

При логическом умножении 0*0=0, 0*1=0, 1*1=1. Операцию логического умножения иначе называют операцией И (английское название AND).

То есть сдвинутая нами влево на пять позиций единичка превращается при инвертировании в ноль и умножается на соответствующий бит, хранящийся в регистре порта PORTC. При умножении на ноль мы получаем ноль. Таким образом, бит PC5 становится равным нулю.

Остаётся скомпилировать проект Build->Build Solution (F7) и прошить контроллер файлом с расширением .hex, который лежит по адресу диск:<имя проекта>Debug.

Работоспособность программы проверяется вольтметром, подключённым к линии PC5 порта PORTC. Наблюдают изменение потенциала линии PC5 раз в две секунды.

Ну, вот и всё! Поздравляю Вас с написанием первой программы!!!

PS: Для лучшего усвоения материала советую Вам выбрать порт и его линию самостоятельно!

См. также видеокурс по AVR-микроконтроллерам для начинающих

Тема поддержки на форуме

Кто хочет идти «в ногу» с автором курса — создавайте свои дневники на форуме и выкладывайте что у вас получается и какие вопросы возникают при этом. 

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

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