Материал: ИДЗ_1 (Глеб М)

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

МИНОБРНАУКИ РОССИИ

Санкт-Петербургский государственный

электротехнический университет

«ЛЭТИ» им. В.И. Ульянова (Ленина)

Кафедра БТС

Отчет

по Лабораторной работе №1

Тема: Программирование МК для мигания светодиодом

Студент гр. 7503 _____________________ Марсаль Г. О.

Студент гр. 7503 _____________________ Роганов А. А.

Студентка гр. 7503 _____________________ Соболева Б. Д.

Преподаватель _____________________ Анисимов А. А.

Санкт-Петербург

2020

Цель работы: Исследование принципов работы микроконтроллера ATtiny104 на базе отладочной платы “ATtiny104 - Xplained Nano”. Получение начальных навыков программирования МК на языке Assembler и C, пользования средой разработки AVR Atmel Studio 7.

Используемые инструменты: Отладочная плата ATtiny104 - Xplained Nano; интегрированная среда разработки AVR Atmel Studio 7; методические указания к выполнению работы.

Теоретическое обоснование темы работы

Мигание светодиодом при помощи микроконтроллера подразумевает собой попеременную подачу на один из выходов МК сигналов разных логических уровней.

Логические элементы оперируют сигналами двух типов: "высокий логический уровень" (1) и "низкий логический уровень" (0), которые характеризуются различным уровнем напряжения: полное напряжение питания принимается в качестве уровня "логической единицы", а нулевое напряжение - в качестве уровня "логического нуля".

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

Элементы ТТЛ работают при номинальном напряжении питания 5 вольт, +/- 0,25 вольт. В идеале, сигнал высокого логического уровня должен быть равен ровно 5,00 В, а сигнал низкого уровня - ровно 0,00 вольт. Однако в реальных элементах ТТЛ не могут быть обеспечены подобные точные уровни напряжения, поэтому они могут принимать сигналы высокого и низкого уровней даже при значительном отклонении напряжения от идеальных величин. "Приемлемые" напряжения входного сигнала лежат в диапазоне от 0 до 0,8 вольт для низкого логического уровня, и от 2 до 5 вольт для высокого логического уровня. "Приемлемые" напряжения выходного сигнала (уровни напряжения, гарантируемые производителем элемента в указанных вариантах нагрузки) лежат в диапазоне от 0 до 0,5 вольт для низкого логического уровня, и от 2,7 до 5 вольт для высокого логического уровня.

Временные задержки в МК, программно, могут быть реализованы по-разному (например, с помощью счетчика, пропуском команды, библиотек задежрки, либо циклов вычисления). В данной работе был выбран наиболее простой тип задержки – при помощи цикла декрементирования переменных для Assembler и библиотека «delay» для языка С.

Вид используемой платы приведен на рисунке 1.

Рисунок 1 – Схема отладочной платы ATtiny104 Xplained Nano

Обработка результатов

  1. Программа мигания светодиодом на языке Assembler

Код программы:

LDI r16, 0b00100000 ; запись 1 в 5 разр. в РОН r16

OUT DDRA, r16 ; перенос из РОН в DDRA

Main: ; начало главного цикла

LDI r16, 0b00100000 ; запись 1 в 5 разр. в РОН r16

OUT PORTA, r16 ; перенос из РОН в PORTA

RCALL Delay ; вызов метки задержки

LDI r16, 0b00000000 ; запись 0 в 5 разр. в РОН r16

OUT PORTA, r16 ; перенос из РОН в PORTA

RCALL Delay ; вызов метки задержки

RJMP Main ; возврат в начало главного цикла

.equ LowByte = 255 ; задаем переменные

.equ MedByte = 255

.equ HighByte = 4

Delay: ; начало метки задержки

LDI r16, LowByte ; записываем переменные в регистры ОН

LDI r17, MedByte

LDI r18, HighByte

loop: ; вызываем цикл

DEC r16 ; отнимаем единицу в r16

BRNE loop ; если не 0, возвращаемся к началу loop

DEC r17

BRNE loop

DEC r18

BRNE loop

RET ; возврат в место вызова метки Delay

Как можно понять из кода, задержка при мигании светодиодом в данном случае происходит из-за «подвисания» МК во время выполнения операций декрементирования DEC. Количество арифметических операций, для получения различимой глазом задержки должно быть велико, так как тактовая частота равна 1МГц. В данном случае это число равно 255 * 255 * 4 = 260100.

Вывод А5 был выбран потому, что именно к нему, как видно на рис. 1, подключен встроенный в плату светодиод.

  1. Программа мигания светодиодом на языке с

Код программы:

#include <avr/io.h>

#include <util/delay.h> // подключили библиотеку задержки

int main(void)

{

DDRA |= (1<<DDRA5); // задали А5 на выход

while (1) // вечный цикл

{

PORTA |= (1<<PORTA5); // высокий логический уровень на А5

_delay_ms(500); // задержка 500 мс

PORTA &=~(1<<PORTA5); // низкий логический уровень на А5

_delay_ms(500); // задержка 500 мс

}

}

Преимущество данного кода заключается в его компактности, простоте написания и легкой читаемости, по сравнению с кодом на Assembler. С другой стороны, данный код не полностью описывает происходящие внутри МК процессы и, в некотором смысле, является менее информативным.

  1. Программа управления состоянием светодиода по нажатию кнопки на языке Assembler

Код программы:

LDI r16, 0b00000000 ; устанавливаем все нули в РОН r16

OUT DDRB, r16 ; присваем регистру DDRB значение r16

LDI r16, 0b00000010 ; устанавливаем 1 во 1 разр. в РОН r16

OUT PUEB, r16 ; присваем регистру PUEB значение r16 (вкл. подтяжку)

LDI r16, 0b00100000 ; устанавливаем 1 во 5 разр. в РОН r16

OUT DDRA, r16 ; присваем регистру DDRA значение r16

Main: ; начало главного цикла

IN r16, PINB ; считываем значения с PINB в r16

SBRC r16, 1 ; если в 1 разр. в r16 единица

LDI r17, 0b00100000 ; присваеваем r17 единицу в 5 разр.

SBRC r16, 1 ; если в 1 разр. в r16 единица

OUT PORTA, r17 ; присваем регистру PORTA значение r17

SBRS r16, 1 ; если в 1 разр. в r16 ноль

LDI r17, 0b00000000 ; присваеваем r17 нули во всех разр.

SBRS r16, 1 ; сли в 1 разр. в r16 ноль

OUT PORTA, r17 ; присваем регистру PORTA значение r17

RJMP Main

Стоит отметить, что очень важной частью программы является включение подтяжки (Pull Up – PUE) для используемой кнопки. В противном случае данный вывод будет находиться в режиме Hi-Z.

Hi-Z - режим высокоимпендансного входа. Этот режим включен по умолчанию. Все вентили разомкнуты, а сопротивление порта очень велико. В принципе, по сравнению с другими режимами, можно его считать бесконечностью. То есть электрически вывод как бы вообще никуда не подключен и ни на что не влияет («висит в воздухе»). В этом случае напряжение будет на нем «скакать» в зависимости от внешних наводок и электромагнитных помех. Очень часто на порту в этом случае нестабильный синус 50Гц — наводка от сети 220В, а в регистре PIN будет меняться 0 и 1 с частотой около 50Гц

  1. Программа управления состоянием светодиода по нажатию кнопки на языке с

Код программы:

#include <avr/io.h>

int main(void)

{

DDRA |= (1<<DDRA5); // установили 1 в 5 разр. DDRA (на вых.)

DDRB &=~ (1<<DDRB1); // установили 0 в 1 разр. DDRB (на вх.)

PUEB |= (1<<PORTB1); // включили подтяжку на 1 кнопке (B1)

PORTB |= (1<<PORTB1);

while (1)

{

if (!(PINB & (1<<PINB1))) { // если кнопка не нажата

PORTA &=~ (1<<PORTA5); // на светодиоде низкий уровень

} else {

PORTA |= (1<<PORTA5); // на светодиоде высокий уровень

}

}

}

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

Результат работы программ представлен на рис. 2 и рис. 3.

Рисунок 2 – Вид платы (кнопка не нажата)

Рисунок 3 - Вид платы (кнопка нажата)

  1. Программа управления состоянием светодиода по нажатию кнопки на языке Assembler (усложненная)

Код программы:

LDI r16, 0b00000000

OUT DDRB, r16

LDI r16, 0b00000010

OUT PUEB, r16

LDI r16, 0b00100000

OUT DDRA, r16

LDI r16, 0b00000000

OUT PORTA, r16

Main:

IN r16, PINB

SBRS r16, 1

RCALL Blink

SBRC r16, 1

LDI r17, 0b00100000

SBRC r16, 1

OUT PORTA, r17

RJMP Main

.equ LowByte = 255

.equ MedByte = 255

.equ HighByte = 4

Blink:

LDI r18, 0b00000000

OUT PORTA, r18

RCALL Delay

LDI r18, 0b00100000

OUT PORTA, r18

RCALL Delay

RET

Delay:

LDI r19, LowByte

LDI r20, MedByte

LDI r21, HighByte

loop:

DEC r19

BRNE loop

DEC r20

BRNE loop

DEC r21

BRNE loop

RET

По сути, данная программа является комбинацией программ из п. 1 и п. 3, и результат её выполнения заключается в мигании светодиода при нажатой кнопке на плате, и отключение светодиода при её отпускании.

Выводы: Микроконтроллер является сложным, по своей структуре, устройством. Написание даже простых программ для такого устройства требует знания и понимания происходящих внутри процессов. Полезным, в процессе написания алгоритмов, является умение использовать разные подходы к реализации поставленных задач, в частности, выбор языка программирования.

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

Источник: https://studfile.net/preview/16557547/